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