Added:
[ocaml-ancient.git] / ancient.mli
1 (** Mark objects as 'ancient' so they are taken out of the OCaml heap.
2   * $Id: ancient.mli,v 1.6 2006-10-09 12:18:05 rich Exp $
3   *)
4
5 type 'a ancient
6
7 val mark : 'a -> 'a ancient
8   (** [mark obj] copies [obj] and all objects referenced
9     * by [obj] out of the OCaml heap.  It returns the proxy
10     * for [obj].
11     *
12     * The copy of [obj] accessed through the proxy MUST NOT be mutated.
13     *
14     * If [obj] represents a large object, then it is a good
15     * idea to call {!Gc.compact} after marking to recover the
16     * OCaml heap memory.
17     *)
18
19 val follow : 'a ancient -> 'a
20   (** Follow proxy link to out of heap object.
21     *
22     * @raise [Invalid_argument "deleted"] if the object has been deleted.
23     *)
24
25 val delete : 'a ancient -> unit
26   (** [delete obj] deletes ancient object [obj].
27     *
28     * @raise [Invalid_argument "deleted"] if the object has been deleted.
29     *
30     * Forgetting to delete an ancient object results in a memory leak.
31     *)
32
33 val is_ancient : 'a -> bool
34   (** [is_ancient ptr] returns true if [ptr] is an object on the ancient
35     * heap.
36     *)
37
38 (** {6 Shared memory mappings} *)
39
40 type md
41   (** Memory descriptor handle. *)
42
43 val attach : Unix.file_descr -> nativeint -> md
44   (** [attach fd baseaddr] attaches to a new or existing file
45     * which may contain shared objects.
46     *
47     * Initially [fd] should be a read/writable, zero-length file
48     * (for example you could create this using {!Unix.openfile} and
49     * passing the flags [O_RDWR], [O_TRUNC], [O_CREAT]).
50     * One or more objects can then be shared in this file
51     * using {!Unix.share}.
52     *
53     * For new files, [baseaddr] specifies the virtual address to
54     * map the file.  Specifying [Nativeint.zero] ([0n]) here lets [mmap(2)]
55     * choose this, but on some platforms (notably Linux/AMD64)
56     * [mmap] chooses very unwisely, tending to map the memory
57     * just before [libc] with hardly any headroom to grow.  If
58     * you encounter this sort of problem (usually a segfault or
59     * illegal instruction inside libc), then look at [/proc/PID/maps]
60     * and choose a more suitable address.
61     *
62     * If the file was created previously, then the [baseaddr] is
63     * ignored.  The underlying [mmalloc] library will map the
64     * file in at the same place as before.
65     *)
66
67 val detach : md -> unit
68   (** [detach md] detaches from an existing file, and closes it.
69     *)
70
71 val share : md -> int -> 'a -> 'a ancient
72   (** [share md key obj] does the same as {!Ancient.mark} except
73     * that instead of copying the object into local memory, it
74     * writes it into memory which is backed by the attached file.
75     *
76     * Shared mappings created this way may be shared between
77     * other OCaml processes which can access the underlying
78     * file.  See {!Ancient.attach}, {!Ancient.detach}.
79     *
80     * More than one object can be stored in a file.  They are
81     * indexed using integers in the range [0..max_key] (the limit
82     * is hard-coded in [mmalloc/mmprivate.h]).  The [key] parameter
83     * controls which object is written/overwritten by [share].
84     * If you do not wish to use this feature, just pass [0]
85     * as the key.
86     *
87     * Do not call {!Ancient.delete} on a mapping created like this.
88     * Instead, call {!Ancient.detach} and, if necessary, delete the
89     * underlying file.
90     *
91     * Caution when sharing files/objects between processes:
92     * The underlying [mmalloc] library does not do any sort of
93     * locking, so all calls to [share] must ensure that they have
94     * exclusive access to the underlying file while in progress.
95     * (Other processes should not even call {!Ancient.get} while
96     * this is happening, but it seems safe to be just reading an
97     * ancient object from the file).
98     *)
99
100 val get : md -> int -> 'a ancient
101   (** [get md key] returns the object indexed by [key] in the
102     * attached file.
103     *
104     * The key is in the range [0..max_key] (the limit is hard-coded in
105     * [mmalloc/mmprivate.h]).  If you do not wish to use this feature,
106     * just pass [0] as the key when sharing / getting.
107     *
108     * You need to annotate the returned object with the correct
109     * type.  As with the Marshal module, there is no type checking,
110     * and setting the wrong type will likely cause a segfault
111     * or undefined behaviour.  Note that the returned object has
112     * type [sometype ancient], not just [sometype].
113     *
114     * @raises [Not_found] if no object is associated with the key.
115     *)
116
117 val max_key : int