Commit | Line | Data |
---|---|---|
63abb1e7 FF |
1 | The GNU mmalloc (mapped-malloc) package. fnf@cygnus.com |
2 | ||
3 | ||
4 | Description | |
5 | ----------- | |
6 | ||
7 | This is a heavily modified version of GNU malloc which has been extended to | |
8 | use mmap() as the basic mechanism for for obtaining memory from the system, | |
9 | rather than sbrk(). This gives it several advantages over the | |
10 | more traditional malloc: | |
11 | ||
12 | * Providing suitable precautions are taken to avoid memory region | |
13 | collisions, sbrk() is now available for use by applications that | |
14 | use this package and still need to use some memory management | |
15 | package that includes functions like malloc/realloc/free. | |
16 | ||
17 | * Several different memory pools can be used, each of them growing | |
18 | or shinking under control of mmap(), with the mmalloc functions | |
19 | using a specific pool on a call by call basis. | |
20 | ||
21 | * By using mmap, it is easy to create data pools which are intended to | |
22 | be persistent and exist as a filesystem object after the creating | |
23 | process has gone away. | |
24 | ||
25 | * Because multiple memory pools can be managed, data used for a | |
26 | specific purpose can be allocated into it's own memory pool, making | |
27 | it easier to allow applications to "dump" and "restore" initialized | |
28 | malloc-managed memory regions. I.E., the "unexec" hack popularized | |
29 | by GNU emacs could potentially go away. | |
30 | ||
31 | ||
32 | Implementation | |
33 | -------------- | |
34 | ||
35 | The mmalloc functions contain no internal static state. All of mmalloc | |
36 | internal data is allocated in the mapped in region, along with the user | |
37 | data that it manages. This allows it to manage multiple such regions | |
38 | and to "pick up where it left off" when such regions are later dynamically | |
39 | mapped back in. | |
40 | ||
41 | In some sense, malloc has been "purified" to contain no internal state | |
42 | information and generalized to use multiple memory regions rather than a | |
43 | single region managed by sbrk(). However the new routines now need an | |
44 | extra parameter which informs malloc which memory region it is dealing | |
45 | with (along with other information). | |
46 | ||
47 | For ease of initial implementation, and to avoid exporting or importing | |
48 | any more global variables or routines than necessary, this package is | |
49 | implemented with all functions contained within a single source file. | |
50 | At some future point, once everything has stabilized, it may be desirable | |
51 | split it up into separate files. | |
52 | ||
53 | The functions initially provided by mmalloc are: | |
54 | ||
55 | void *mmalloc_attach (int fd, void *baseaddr); | |
56 | void *mmalloc_detach (void *md); | |
57 | int mmalloc_errno (void *md); | |
58 | int mmalloc_setkey (void *md, int keynum, void *key); | |
59 | void *mmalloc_getkey (void *md, int keynum); | |
60 | ||
61 | void *mmalloc (void *md, size_t size); | |
62 | void *mrealloc (void *md, void *ptr, size_t size); | |
63 | void *mvalloc (void *md, size_t size); | |
64 | void mfree (void *md, void *ptr); | |
65 | ||
66 | Backwards Compatibility | |
67 | ----------------------- | |
68 | ||
69 | To allow a single malloc package to be used in a given application, provision | |
70 | is made for the traditional malloc/realloc/free functions to be implemented | |
71 | as special cases of the mmalloc functions. In particular, if any of the | |
72 | functions that expect malloc descriptors are called with a NULL pointer rather | |
73 | than a valid malloc descriptor, then they default to using an mmap'd region | |
74 | starting at the current sbrk() value and mapped to /dev/zero. Applications | |
75 | can simply include the following defines to use the mmalloc versions: | |
76 | ||
77 | #define malloc(size) mmalloc ((void *)0, (size)) | |
78 | #define realloc(ptr,size) mrealloc ((void *)0, (ptr), (size)); | |
79 | #define free(ptr) mfree ((void *)0, (ptr)) | |
80 | ||
81 | or replace the existing malloc/realloc/free calls with the above patterns | |
82 | if the #define's cause problems. | |
83 | ||
84 | Note that this does not prevent calls to malloc/realloc/free within | |
85 | libraries from continuing to use the library version of malloc, so if this | |
86 | is a problem, the compatibility issue needs to be dealt with in another way. | |
87 | ||
88 | ||
89 | Function Descriptions | |
90 | --------------------- | |
91 | ||
92 | void *mmalloc_attach (int fd, void *baseaddr); | |
93 | ||
94 | Initialize access to a mmalloc managed region. | |
95 | ||
96 | If FD is a valid file descriptor for an open file then data for the | |
97 | mmalloc managed region is mapped to that file, otherwise "/dev/zero" | |
98 | is used and the data will not exist in any filesystem object. | |
99 | ||
100 | If the open file corresponding to FD is from a previous use of | |
101 | mmalloc and passes some basic sanity checks to ensure that it is | |
102 | compatible with the current mmalloc package, then it's data is | |
103 | mapped in and is immediately accessible at the same addresses in | |
104 | the current process as the process that created the file. | |
105 | ||
106 | If BASEADDR is not NULL, the mapping is established starting at the | |
107 | specified address in the process address space. If BASEADDR is NULL, | |
108 | the mmalloc package chooses a suitable address at which to start the | |
109 | mapped region, which will be the value of the previous mapping if | |
110 | opening an existing file which was previously built by mmalloc, or | |
111 | for new files will be a value chosen by mmap. | |
112 | ||
113 | Specifying BASEADDR provides more control over where the regions | |
114 | start and how big they can be before bumping into existing mapped | |
115 | regions or future mapped regions. | |
116 | ||
117 | On success, returns a "malloc descriptor" which is used in subsequent | |
118 | calls to other mmalloc package functions. It is explicitly "void *" | |
119 | ("char *" for systems that don't fully support void) so that users | |
120 | of the package don't have to worry about the actual implementation | |
121 | details. | |
122 | ||
123 | On failure returns NULL. | |
124 | ||
125 | void *mmalloc_detach (void *md); | |
126 | ||
127 | Terminate access to a mmalloc managed region by closing the base | |
128 | file and unmapping all memory pages associated with the region. | |
129 | ||
130 | Returns NULL on success. | |
131 | ||
132 | Returns the malloc descriptor on failure, which can subsequently | |
133 | be used for further action (such as obtaining more information about | |
134 | the nature of the failure). | |
135 | ||
136 | void *mmalloc (void *md, size_t size); | |
137 | ||
138 | Given an mmalloc descriptor MD, allocate additional memory of | |
139 | SIZE bytes in the associated mapped region. | |
140 | ||
141 | void *mrealloc (void *md, void *ptr, size_t size); | |
142 | ||
143 | Given an mmalloc descriptor MD and a pointer to memory previously | |
144 | allocated by mmalloc in PTR, reallocate the memory to be SIZE bytes | |
145 | long, possibly moving the existing contents of memory if necessary. | |
146 | ||
147 | void *mvalloc (void *md, size_t size); | |
148 | ||
149 | Like mmalloc but the resulting memory is aligned on a page boundary. | |
150 | ||
151 | void mfree (void *md, void *ptr); | |
152 | ||
153 | Given an mmalloc descriptor MD and a pointer to memory previously | |
154 | allocated by mmalloc in PTR, free the previously allocated memory. | |
155 | ||
156 | int mmalloc_errno (void *md); | |
157 | ||
158 | Given a mmalloc descriptor, if the last mmalloc operation | |
159 | failed for some reason due to a system call failure, then | |
160 | returns the associated errno. Returns 0 otherwise. |