Added:
[ocaml-ancient.git] / ancient.mli
index 50d6c8a..f77a4b4 100644 (file)
@@ -1,5 +1,5 @@
 (** Mark objects as 'ancient' so they are taken out of the OCaml heap.
 (** Mark objects as 'ancient' so they are taken out of the OCaml heap.
-  * $Id: ancient.mli,v 1.3 2006-09-27 18:39:44 rich Exp $
+  * $Id: ancient.mli,v 1.6 2006-10-09 12:18:05 rich Exp $
   *)
 
 type 'a ancient
   *)
 
 type 'a ancient
@@ -30,18 +30,38 @@ val delete : 'a ancient -> unit
     * Forgetting to delete an ancient object results in a memory leak.
     *)
 
     * Forgetting to delete an ancient object results in a memory leak.
     *)
 
+val is_ancient : 'a -> bool
+  (** [is_ancient ptr] returns true if [ptr] is an object on the ancient
+    * heap.
+    *)
+
 (** {6 Shared memory mappings} *)
 
 type md
   (** Memory descriptor handle. *)
 
 (** {6 Shared memory mappings} *)
 
 type md
   (** Memory descriptor handle. *)
 
-val attach : Unix.file_descr -> md
-  (** [attach fd] attaches to a new or existing file which may contain
-    * shared objects.
+val attach : Unix.file_descr -> nativeint -> md
+  (** [attach fd baseaddr] attaches to a new or existing file
+    * which may contain shared objects.
     *
     * Initially [fd] should be a read/writable, zero-length file
     *
     * Initially [fd] should be a read/writable, zero-length file
-    * (see {!Unix.openfile}).  One or more objects can then be
-    * shared in this file using {!Unix.share}.
+    * (for example you could create this using {!Unix.openfile} and
+    * passing the flags [O_RDWR], [O_TRUNC], [O_CREAT]).
+    * One or more objects can then be shared in this file
+    * using {!Unix.share}.
+    *
+    * For new files, [baseaddr] specifies the virtual address to
+    * map the file.  Specifying [Nativeint.zero] ([0n]) here lets [mmap(2)]
+    * choose this, but on some platforms (notably Linux/AMD64)
+    * [mmap] chooses very unwisely, tending to map the memory
+    * just before [libc] with hardly any headroom to grow.  If
+    * you encounter this sort of problem (usually a segfault or
+    * illegal instruction inside libc), then look at [/proc/PID/maps]
+    * and choose a more suitable address.
+    *
+    * If the file was created previously, then the [baseaddr] is
+    * ignored.  The underlying [mmalloc] library will map the
+    * file in at the same place as before.
     *)
 
 val detach : md -> unit
     *)
 
 val detach : md -> unit
@@ -58,7 +78,7 @@ val share : md -> int -> 'a -> 'a ancient
     * file.  See {!Ancient.attach}, {!Ancient.detach}.
     *
     * More than one object can be stored in a file.  They are
     * file.  See {!Ancient.attach}, {!Ancient.detach}.
     *
     * More than one object can be stored in a file.  They are
-    * indexed using integers in the range [0..1023] (the limit
+    * indexed using integers in the range [0..max_key] (the limit
     * is hard-coded in [mmalloc/mmprivate.h]).  The [key] parameter
     * controls which object is written/overwritten by [share].
     * If you do not wish to use this feature, just pass [0]
     * is hard-coded in [mmalloc/mmprivate.h]).  The [key] parameter
     * controls which object is written/overwritten by [share].
     * If you do not wish to use this feature, just pass [0]
@@ -72,19 +92,26 @@ val share : md -> int -> 'a -> 'a ancient
     * The underlying [mmalloc] library does not do any sort of
     * locking, so all calls to [share] must ensure that they have
     * exclusive access to the underlying file while in progress.
     * The underlying [mmalloc] library does not do any sort of
     * locking, so all calls to [share] must ensure that they have
     * exclusive access to the underlying file while in progress.
+    * (Other processes should not even call {!Ancient.get} while
+    * this is happening, but it seems safe to be just reading an
+    * ancient object from the file).
     *)
 
 val get : md -> int -> 'a ancient
   (** [get md key] returns the object indexed by [key] in the
     * attached file.
     *
     *)
 
 val get : md -> int -> 'a ancient
   (** [get md key] returns the object indexed by [key] in the
     * attached file.
     *
-    * The key is in the range [0..1023] (the limit is hard-coded in
-    * [mmalloc/mmprivate.h]).
+    * The key is in the range [0..max_key] (the limit is hard-coded in
+    * [mmalloc/mmprivate.h]).  If you do not wish to use this feature,
+    * just pass [0] as the key when sharing / getting.
     *
     * You need to annotate the returned object with the correct
     * type.  As with the Marshal module, there is no type checking,
     * and setting the wrong type will likely cause a segfault
     *
     * You need to annotate the returned object with the correct
     * type.  As with the Marshal module, there is no type checking,
     * and setting the wrong type will likely cause a segfault
-    * or undefined behaviour.
+    * or undefined behaviour.  Note that the returned object has
+    * type [sometype ancient], not just [sometype].
     *
     * @raises [Not_found] if no object is associated with the key.
     *)
     *
     * @raises [Not_found] if no object is associated with the key.
     *)
+
+val max_key : int