Differences From
Artifact [e0850f6b30]:
4 4
5 5 ## module functions
6 6
7 7 **kmem** supplies two module-level functions, used to interact with the `kmptr` container type.
8 8
9 9 * `kmfree(kmptr) → void` - free, downref, or ignore the pasted object as appropriate
10 10 * `kmshred(kmptr) → void` - free, downref, or ignore the pasted object as appropriate. if deallocating, zero its contents
11 - * `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 }`.
11 + * `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 }`.
12 12 * `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.
13 13
14 14 ## types
15 15
16 16 kmem defines the following types:
17 17
18 + * `enum kmkind` - enumerates allocation strategies
18 19 * `struct kmptr` - abstract pointer object
19 - * `enum kmptr_kind`
20 20 * `struct kmcell` - abstract memory cell
21 - * `enum kmcell_kind`
22 21 * `struct kmref` - a reference-counted cell
23 22 * `struct kmnode` - a node in an allocation tree
24 23 * `struct kmpool` - a memory pool
25 24
26 25 `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)`)
27 26
27 +
28 +### kmkind
29 +
30 +`kmkind` is an enum that specifies an allocation function.
31 +
32 + * `kmkind_none` - no allocation
33 + * `kmkind_heap` - heap allocation
34 + * `kmkind_pool` - pool allocation
35 + * `kmkind_ref` - reference-counting allocation
36 + * `kmkind_tree` - tree allocation
37 +
28 38 ### kmptr
29 39
30 40 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.
31 41
32 42 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.
33 43
34 44 a `kmptr` has the following layout:
35 45
36 - * `kmptr_kind kind` - codes the type of pointer
46 + * `kmkind kind` - codes the type of pointer; `kmkind_none` indicates a non-allocated pointer to a static (global or on-stack) object.
37 47 * `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.
38 48 * `void* ref` - the raw pointer enclosed by `cell`
39 49 * `kmcell* cell` - a pointer to an object enclosure, typically either a memory pool or a referencing-counting object. NULL if not needed.
40 50
41 51 the convenience function `kmstat(void*) → kmptr` wraps a pointer to a static object in a `kmptr` struct.
42 52
43 -#### kmptr_kind
44 -
45 -`kmptr_kind` is an enum with one of the following values.
46 -
47 - * `kmptr_kind_none` - not a valid pointer
48 - * `kmptr_kind_static` - points to a static region of space. `kmptr` instances with this kind will be ignored by `kmfree`.
49 - * `kmptr_kind_heap` - a traditional heap pointer.
50 - * `kmptr_kind_pool` - points to a region stored in a memory pool.
51 - * `kmptr_kind_ref` - points to a reference-counted object.
52 - * `kmptr_kind_node` - points to a reference-counted object.
53 -
54 53 ### kmcell
55 54
56 55 `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`.
57 56
58 57 * `kmptr_kind kind` - kind of cell
59 58 * `size_t sz` - kind of cell (data plus all fields)
60 59 * `kmshred shred` - shredding flag
61 60
62 61 ### kmref
63 62
64 63 `kmref` is a struct that constitutes the in-memory representation of a reference-counted cell.
65 64
66 - * `kmcell_kind kind = ref` - kind of cell
65 + * `kmkind kind = kmkind_ref` - kind of cell
67 66 * `size_t sz` - size of cell (data plus all fields)
68 67 * `kmshred shred` - shredding flag
69 68 * `size_t refs` - number of active references
70 69 * `kmcell* src` - source, if any
71 70 * `char data[]` - content of cell
72 71
73 72 ### kmnode
74 73
75 74 `kmnode` is a struct that constitutes the in-memory representation of a tree node.
76 75
77 - * `kmcell_kind kind = node` - kind of cell
76 + * `kmkind kind = kmkind_tree` - kind of cell
78 77 * `size_t sz` - size of cell (data plus all fields)
79 78 * `kmshred shred` - shredding flag
80 79 * `kmnode* parent` - parent node
81 80 * `kmnode* child` - first child node
82 81 * `kmnode* lastchild` - last child node
83 82 * `kmnode* prev` - previous sibling, NULL if first
84 83 * `kmnode* next` - next sibling, NULL if last
85 84 * `char data[]` - content of cell
86 85
87 86 ### kmpool
88 87
89 - * `kmcell_kind kind = pool` - indicates the kind of source
88 + * `kmkind kind = kmkind_pool` - indicates the kind of source
90 89 * `size_t sz` - size of cell (data plus all fields)
91 90 * `kmshred shred` - shredding flag
92 91 * `size_t cellsz` - size of individual pool cells
93 92 * `kmpoolcell* top` - pointer to most recently allocated pool cell
94 93 * `kmpoolcell* bottom` - pointer to most recently freed pool cell
95 94 * `kmpoolcell data[]` - content of cell
96 95
97 -### kmpoolcell
96 +#### kmpoolcell
98 97
99 98 * `kmpoolcell* last` - pointer to last element allocated before this one
100 99 * `char data[]` - pool data
101 100
102 101 ### kmshred
103 102
104 103 `kmshred` is an enum used to indicate whether an object should be "shredded" (written over) in memory when it's deleted. this is a useful means to ensure that privileged information is not accidentally left in memory after use. if the shredding mechanism is not useful, compile libk with the flag `KFmem_noshred` to exclude its functions and fields.
................................................................................
151 150 * `tree` [af] - uses a node-child strategy. when a node is freed, all of its children are automatically freed as well.
152 151 * `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.
153 152 * `kmtreez(kmcell* src, void* parent, size_t) → void*` - like `kmtreea` but zeroed
154 153 * `kmtreeao(kmcell* src, void* parent, size_t) → kmptr` - like `kmtreea` but returns a `kmptr`
155 154 * `kmtreezo(kmcell* src, void* parent, size_t) → kmptr` - like `kmtreez` but returns a `kmptr`
156 155 * `kmtreef(void*) → kmptr` - frees a node and all its children
157 156
157 +## macros
158 +
159 +kmem defines the following macros.
160 +
161 + * `Kmsz(array)` - a convenience macro to return the number of elements in a static array. inserts the text `( sizeof (array) / sizeof (array) [0] )`