libk  Diff

Differences From Artifact [e0850f6b30]:

To Artifact [9a7772ee1a]:


     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] )`