feat: extend slab with KmemCache and SpinLock
This commit is contained in:
1 parent
8d2b1df100
commit
98e09f13f8
4 files changed
+199
No files matched your search
@@ -0,0 +1,55 @@
|
||||
#ifndef FROSTBYTE_SLAB_H
|
||||
#define FROSTBYTE_SLAB_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*
|
||||
* Slab: a fixed-size object cache backed directly by physical frames from
|
||||
* pmm, bypassing the general-purpose heap. Each slab is exactly one frame;
|
||||
* the Slab descriptor lives at the start of that same frame (so freeing a
|
||||
* pointer is O(1): mask it down to the enclosing frame to recover the
|
||||
* descriptor, no list walk needed), and the rest of the frame is carved
|
||||
* into objSize-aligned objects threaded onto a singly-linked free list
|
||||
* through their own (currently-unused) storage.
|
||||
*
|
||||
* Intended for kernel-internal fixed-size allocations (list/tree nodes,
|
||||
* PCB-sized structs, ...) where slab's O(1) alloc/free and per-slab
|
||||
* locality beat the heap's general-purpose free-list search.
|
||||
*/
|
||||
|
||||
typedef struct KmemCache {
|
||||
const char* name;
|
||||
usize objSize; /* rounded up to at least sizeof(void*), 8-aligned */
|
||||
usize objsPerSlab;
|
||||
struct Slab* slabs; /* every slab owned by this cache, newest first */
|
||||
usize slabCount;
|
||||
usize usedObjs;
|
||||
} KmemCache;
|
||||
|
||||
/* Returns false if objSize (after rounding) cannot fit at least one object
|
||||
per frame alongside the slab header -- the cache is left zeroed either
|
||||
way, so kmemCacheDestroy is always safe to call. */
|
||||
bool kmemCacheInit(KmemCache* cache, const char* name, usize objSize);
|
||||
|
||||
/* Releases every frame the cache ever grew into back to pmm. The cache is
|
||||
left in a freshly-initialized (empty, growable-again) state. */
|
||||
void kmemCacheDestroy(KmemCache* cache);
|
||||
|
||||
/* Grows the cache (allocates a new frame from pmm) on demand. nullptr only
|
||||
if pmm is out of frames. */
|
||||
void* kmemCacheAlloc(KmemCache* cache);
|
||||
|
||||
/* obj must have come from kmemCacheAlloc on this exact cache and not
|
||||
already be free. */
|
||||
void kmemCacheFree(KmemCache* cache, void* obj);
|
||||
|
||||
usize kmemCacheUsed(const KmemCache* cache);
|
||||
/* Objects across every slab the cache has grown into so far -- 0 until the
|
||||
first kmemCacheAlloc, since slabs are only ever grown lazily on demand. */
|
||||
usize kmemCacheCapacity(const KmemCache* cache);
|
||||
usize kmemCacheSlabCount(const KmemCache* cache);
|
||||
/* How many objects a single slab (frame) holds for this cache -- fixed at
|
||||
kmemCacheInit time, independent of how many slabs have been grown. */
|
||||
usize kmemCacheObjsPerSlab(const KmemCache* cache);
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user