karlos/include/slab.h

50 lines
2 KiB
C

#ifndef KARLOS_SLAB_H
#define KARLOS_SLAB_H
#include <stdint.h>
#include <stddef.h>
#include <paging.h>
/* Forward declaration of per-page descriptor */
typedef struct slab_page slab_page_t;
/*------------------------------------------------------------------------*/
/* Per-cache descriptor: one cache per object size */
/*------------------------------------------------------------------------*/
typedef struct slab_cache {
size_t obj_size; // bytes per object
size_t slots_per_slab; // = PAGE_SIZE / obj_size
slab_page_t *empty_slabs; // slabs with all slots free
slab_page_t *partial_slabs; // slabs with some free slots
slab_page_t *full_slabs; // slabs with no free slots
void (*constructor)(void *obj, size_t size);
void (*destructor)(void *obj, size_t size);
} slab_cache_t;
/*------------------------------------------------------------------------*/
/* Per-slab descriptor: one page carved into fixed-size slots */
/*------------------------------------------------------------------------*/
typedef struct slab_page {
void **free_stack; // stack of free slots in this page
size_t free_index; // current head of stack (also free_count)
size_t free_count; // how many slots are free right now
void *page_base; // base address of the slab's page
struct slab_page *next; // link to next slab_page in cache list
} slab_page_t;
/*------------------------------------------------------------------------*/
/* API: implemented in KARLOS_SLAB.c */
/*------------------------------------------------------------------------*/
slab_cache_t *slab_cache_create(
size_t obj_size,
size_t align,
void (*constructor)(void*, size_t),
void (*destructor)(void*, size_t)
);
void *slab_alloc(slab_cache_t *cache);
void slab_free(slab_cache_t *cache, void *obj);
void slab_destroy(slab_cache_t *cache);
#endif /* KARLOS_SLAB_H */