Differences From
Artifact [0e44a94bf4]:
1 1 # kmem
2 2
3 3 **kmem** is a libk module that contains various functions for memory allocation and deallocation. it uses the **short** naming convention with the glyph `m`.
4 4
5 5 # description
6 6
7 -kmem allocators can work in several different ways. they can allocate memory directly from the heap (like `kmheapa()` and `kmlina()`), use a header that has already been allocated by another function, or allocate memory only from a pre-allocated pool. linear allocation with pool allocation is particularly useful, as it permits the very rapid allocation and deallocation of lots of objects with only a few adjustments to the heap, and no possibility of fragmentation or need for expensive algorithms like `malloc()` or `kmheapa()`
7 +kmem allocators can work in several different ways. they can allocate memory directly from the heap (like `kmheapa()` and `kmlina()`), use a header that has already been allocated by another function, or allocate memory only from a pre-allocated pool. linear allocation with pool allocation is particularly useful, as it permits the very rapid allocation and deallocation of lots of objects with only a few adjustments to the heap, and no possibility of fragmentation or need for expensive algorithms like `malloc()` or `kmheapa()`. functions that can return a value and an error condition always return a value of type `kmres`, a struct that contains the field `kmcond` with an error code, and one of `raw` (for functions that return raw pointers) or `ptr` (for functions that return `kmptr` objects).
8 8
9 9 # module functions
10 10
11 11 kmem supplies two module-level functions, used to interact with the `kmptr` container type.
12 12
13 13 * `kmfree(kmptr) → kmcond` - free, downref, or ignore the passed object as appropriate
14 14 * `kmshred(kmptr) → void` - free, downref, or zero the passed object as appropriate. if downref'ing, mark underlying object to be shredded. otherwise, zero its contents, then deallocate if appropriate.
................................................................................
109 109
110 110 # naming convention
111 111
112 112 kmem function names are based on the **method** of allocation and the **action** being performed. methods are listed in the section below. kmem defines a number of standardized actions, though not every method uses every action. the character listed in brackets is suffixed to the name of the method to produce a function name: for instance, `kmheapa` will allocate memory on the heap, while `kmrefd` will decrement the reference count of its argument.
113 113
114 114 * initialize [i] - initializes a memory store on the heap
115 115 * initialize fixed [if] - initialize a memory store on the stack or in a fixed-size global
116 - * allocate [a] -a llocate a new region of memory of the given size, ready to write, and write a pointer to it into argument `where`. returns a value of `kmcond`; always check this to ensure allocation succeeded. contents of that region undefined. takes parameters `void** where, size_t sz`.
117 - * allocate pointer object [o] - like *allocate*, but fills in a `kmptr` instead of a raw `void*`. takes parameters `kmptr* where, size_t sz`.
116 + * allocate [a] - allocate a new region of memory of the given size, ready to write, and return a struct `kmres` containing an error code and, if the call succeeded, a pointer in the field `raw`. always check the `cond` field of its return value to ensure allocation succeeded. contents of the region specified by the `raw` field are undefined. takes parameter `size_t sz`.
117 + * allocate pointer object [o] - like *allocate*, but yields a `kmptr` in the `ptr` field of its return value instead of a raw `void*`. takes parameters `size_t sz`.
118 118 * zero [z] - allocate a new region of memory and zero it before returning it for writing.
119 119 * zero pointer object [zo] - like *zero*, but returns a `kmptr` instead of a raw `void*`.
120 120 * free [f] - free a section of memory, either decrementing a reference count or returning it to whatever pool it came from.
121 121 * shred [s] - destroy whatever was in the segment of memory, then return it to the pool it came from.
122 122 * destroy [x] - tears down a memory store
123 123 * upref [u] - increments a reference counter
124 124
125 125 ## methods
126 126
127 127 kmem currently supports the following methods of memory management, along with which methods are defined for it. (note that `a` implies `z` and `f` implies `s`). a method may be excluded from a libk binary by defining the flag `KFmem_no[name]`, e.g. `KFmem_noheap`.
128 128
129 129 the fastest allocator is the linear allocator, which should be sufficient for most simple programs. it allocates and deallocates memory simply by resizing the stack; there is no fragmentation, but objects must be freed in the order they are allocated. however, entire groups of objects can be freed at once at very little cost.
130 130
131 +**caveat scriptor:** the linear allocation method is unfortunately complicated by the fact that the methods it uses make it fundamentally incompatible with use in the program of the "malloc" allocator used by libc. this should not be a problem for programs that only link libk, but if they link in any external libraries that depend on libc and which use malloc internally, **the linear allocator cannot be used.**
132 +
131 133 * `lin` [iax] - linear heap allocator
132 - * `kmlini(void) → void*` - return a pointer to the current top of the heap
133 - * `kmlina(size_t) → void*` - allocate space on the heap and increase its size appropriately
134 - * `kmlinz(size_t) → void*` - allocate zero-filled space on the heap and increase its size appropriately
135 - * `kmlinx(void*) → void*` - returns the top of the heap to the location specified, freeing all memory allocated since the call to kmlini() or `kmlina()` that produced it
134 + * `kmlini` - return a pointer to the current top of the heap
135 + * `kmlina` - allocate space on the heap and increase its size appropriately
136 + * `kmlinz` - allocate zero-filled space on the heap and increase its size appropriately
137 + * `kmlinx` - returns the top of the heap to the location specified, freeing all memory allocated since the call to kmlini() or `kmlina()` that produced it
136 138 * `heap` [af] - random heap allocation
137 - * `kmheapa(size_t) → void*` - allocate
138 - * `kmheapz(size_t) → void*` - zero-allocate
139 - * `kmheapao(size_t) → kmptr` - allocate pointer object
140 - * `kmheapzo(size_t) → kmptr` - zero-allocate pointer object
141 - * `kmheapf(void*) → void` - free
142 - * `kmheaps(void*) → void` - shred
139 + * `kmheapa` - allocate
140 + * `kmheapz` - zero-allocate
141 + * `kmheapo` - allocate pointer object
142 + * `kmheapzo` - zero-allocate pointer object
143 + * `kmheapf` - free
144 + * `kmheaps` - shred
143 145 * `ref` [afu] - reference-counted heap object
144 - * `kmrefa(kmcell*, size_t) → void*` - allocate
145 - * `kmrefz(kmcell*, size_t) → void*` - zero-allocate
146 - * `kmrefao(kmcell*, size_t) → void*` - allocate pointer object
147 - * `kmrefzo(kmcell*, size_t) → void*` - zero-allocate pointer object
148 - * `kmreff(void*) → void` - downref; free if last ref
149 - * `kmrefs(void*) → void` - downref and mark for shred on last ref
146 + * `kmrefa` - allocate
147 + * `kmrefz` - zero-allocate
148 + * `kmrefo` - allocate pointer object
149 + * `kmrefzo` - zero-allocate pointer object
150 + * `kmreff` - downref; free if last ref
151 + * `kmrefs` - downref and mark for shred on last ref
150 152 * `pool` [ixaf] - memory pool
151 153 * `kmpooli(kmcell*, size_t sz, size_t n) → kmpool*` - initialize a fixed memory pool (a pool of `n` cells of length `sz`)
152 - * `kmpoolx(kmpool*) → void` - tear down a memory pool
153 - * `kmpoola(kmpool*) → void*` - allocate from pool
154 - * `kmpoolz(kmpool*, size_t) → void*` - zero-allocate from pool
155 - * `kmpoolao(kmpool*, size_t) → void*` - allocate pointer object
156 - * `kmpoolzo(kmpool*, size_t) → void*` - zero-allocate pointer object
157 - * `kmpoolf(void*) → void` - downref; free if last ref
158 - * `kmpools(void*) → void` - downref and mark for shred on last ref
154 + * `kmpoolx` - tear down a memory pool
155 + * `kmpoola` - allocate from pool
156 + * `kmpoolz` - zero-allocate from pool
157 + * `kmpoolo` - allocate pointer object
158 + * `kmpoolzo` - zero-allocate pointer object
159 + * `kmpoolf` - downref; free if last ref
160 + * `kmpools` - downref and mark for shred on last ref
159 161 * `tree` [af] - uses a node-child strategy. when a node is freed, all of its children are automatically freed as well.
160 - * `kmtreea(kmcell* src, void* parent, size_t) → void*` - create a tree node. if `parent` is NULL, the node will the top of a new tree. if src is null, allocate on-heap.
161 - * `kmtreez(kmcell* src, void* parent, size_t) → void*` - like `kmtreea` but zeroed
162 - * `kmtreeao(kmcell* src, void* parent, size_t) → kmptr` - like `kmtreea` but returns a `kmptr`
163 - * `kmtreezo(kmcell* src, void* parent, size_t) → kmptr` - like `kmtreez` but returns a `kmptr`
164 - * `kmtreef(void*) → kmptr` - frees a node and all its children
162 + * `kmtreea` - create a tree node. if `parent` is NULL, the node will the top of a new tree. if src is null, allocate on-heap.
163 + * `kmtreez` - like `kmtreea` but zeroed
164 + * `kmtreeao` - like `kmtreea` but returns a `kmptr`
165 + * `kmtreezo` - like `kmtreez` but returns a `kmptr`
166 + * `kmtreef` - frees a node and all its children
165 167
166 168 ## macros
167 169
168 170 kmem defines the following macros.
169 171
170 172 * `Kmsz(array)` - a convenience macro to return the number of elements in a static array. inserts the text `( sizeof (array) / sizeof (array) [0] )`
171 173 * `Kmszs(type, struct)` - a convenience macro to return the size of a struct. requires compound literals.
172 174 * `Kmszsa(type, array)` - calculates the number of elements in an array of a given struct type. inserts the text `( sizeof ( (type) array ) / sizeof (type) )`
173 175 * `Kmpsa(type, struct)` - a convenience macro to insert a "pascal struct array" - that is, a struct array prefixed with a size value. this is equivalent to `Kmszsa(type, array), array`