@@ -7,25 +7,35 @@ **kmem** supplies two module-level functions, used to interact with the `kmptr` container type. * `kmfree(kmptr) → void` - free, downref, or ignore the pasted object as appropriate * `kmshred(kmptr) → void` - free, downref, or ignore the pasted object as appropriate. if deallocating, zero its contents - * `kmstat(void*) → kmptr` - convenience function to wrap a pointer to a non-managed object in a `kmptr` struct, so it can be passed to functions that accept arbitrary objects. `kmptr p = kmstat(raw)` is equivalent to `kmptr p = { kmptr_kind_static, raw, NULL }`. + * `kmstat(void*) → kmptr` - convenience function to wrap a pointer to a non-managed object in a `kmptr` struct, so it can be passed to functions that accept arbitrary objects. `kmptr p = kmstat(raw)` is equivalent to `kmptr p = { kmkind_none, raw, NULL }`. * `kmtaint(&kmptr) → void` - "taints" a `kmptr` object by setting it to be shredded when freed. this may be desirable if the object pointed to contains privileged information. ## types kmem defines the following types: + * `enum kmkind` - enumerates allocation strategies * `struct kmptr` - abstract pointer object - * `enum kmptr_kind` * `struct kmcell` - abstract memory cell - * `enum kmcell_kind` * `struct kmref` - a reference-counted cell * `struct kmnode` - a node in an allocation tree * `struct kmpool` - a memory pool `kmptr` and `kmcell` are both very similar. the difference is that a kmptr points to a region in memory and can be passed around freely. a `kmcell` is the actual in-memory representation of an allocation cell. a `kmcell` cannot be usefully instantiated; rather, it is downcast from an actual cell type (e.g. `kmnode n; kmcell* s = (kmcell*)(&n)`) + +### kmkind + +`kmkind` is an enum that specifies an allocation function. + + * `kmkind_none` - no allocation + * `kmkind_heap` - heap allocation + * `kmkind_pool` - pool allocation + * `kmkind_ref` - reference-counting allocation + * `kmkind_tree` - tree allocation + ### kmptr kmem functions can operate on both raw pointers and the `kmptr` struct type. `kmptr` is a generic struct that can contain any kind of pointer. this is useful if you wish to allocate different objects in different manners, but pass them on into a single interface. @@ -32,26 +42,15 @@ memory pointed at by `kmptr` pointers can be freed either with the usual specialized function, or by passing the `kmptr` structure itself to the generic function `kmfree`, which will handle it appropriately, even if it's a pointer to a garbage-collected object or to a static region of memory. a `kmptr` has the following layout: - * `kmptr_kind kind` - codes the type of pointer + * `kmkind kind` - codes the type of pointer; `kmkind_none` indicates a non-allocated pointer to a static (global or on-stack) object. * `kmshred shred` - an enum. if `kmshred_yes`, the value will be zeroed or otherwise made unreadable on free. if no, `kmfree` will consult `src` for shred policy if it is not NULL. * `void* ref` - the raw pointer enclosed by `cell` * `kmcell* cell` - a pointer to an object enclosure, typically either a memory pool or a referencing-counting object. NULL if not needed. the convenience function `kmstat(void*) → kmptr` wraps a pointer to a static object in a `kmptr` struct. -#### kmptr_kind - -`kmptr_kind` is an enum with one of the following values. - - * `kmptr_kind_none` - not a valid pointer - * `kmptr_kind_static` - points to a static region of space. `kmptr` instances with this kind will be ignored by `kmfree`. - * `kmptr_kind_heap` - a traditional heap pointer. - * `kmptr_kind_pool` - points to a region stored in a memory pool. - * `kmptr_kind_ref` - points to a reference-counted object. - * `kmptr_kind_node` - points to a reference-counted object. - ### kmcell `kmcell` is a stub struct used to disambiguate between source types.a "source" is an object that can hold an allocated object, such as the heap, a memory pool, a fixed-length array on stack, or a fixed-length global array. all values produced by a kmem allocation function point to within a `kmcell`. @@ -62,9 +61,9 @@ ### kmref `kmref` is a struct that constitutes the in-memory representation of a reference-counted cell. - * `kmcell_kind kind = ref` - kind of cell + * `kmkind kind = kmkind_ref` - kind of cell * `size_t sz` - size of cell (data plus all fields) * `kmshred shred` - shredding flag * `size_t refs` - number of active references * `kmcell* src` - source, if any @@ -73,9 +72,9 @@ ### kmnode `kmnode` is a struct that constitutes the in-memory representation of a tree node. - * `kmcell_kind kind = node` - kind of cell + * `kmkind kind = kmkind_tree` - kind of cell * `size_t sz` - size of cell (data plus all fields) * `kmshred shred` - shredding flag * `kmnode* parent` - parent node * `kmnode* child` - first child node @@ -85,17 +84,17 @@ * `char data[]` - content of cell ### kmpool - * `kmcell_kind kind = pool` - indicates the kind of source + * `kmkind kind = kmkind_pool` - indicates the kind of source * `size_t sz` - size of cell (data plus all fields) * `kmshred shred` - shredding flag * `size_t cellsz` - size of individual pool cells * `kmpoolcell* top` - pointer to most recently allocated pool cell * `kmpoolcell* bottom` - pointer to most recently freed pool cell * `kmpoolcell data[]` - content of cell -### kmpoolcell +#### kmpoolcell * `kmpoolcell* last` - pointer to last element allocated before this one * `char data[]` - pool data @@ -154,4 +153,9 @@ * `kmtreeao(kmcell* src, void* parent, size_t) → kmptr` - like `kmtreea` but returns a `kmptr` * `kmtreezo(kmcell* src, void* parent, size_t) → kmptr` - like `kmtreez` but returns a `kmptr` * `kmtreef(void*) → kmptr` - frees a node and all its children +## macros + +kmem defines the following macros. + + * `Kmsz(array)` - a convenience macro to return the number of elements in a static array. inserts the text `( sizeof (array) / sizeof (array) [0] )`