typedef struct { link_t link; count_t busy; /**< Count of full slots in magazine */ count_t size; /**< Number of slots in magazine */ void *objs[]; /**< Slots in magazine */ } slab_magazine_t; typedef struct { slab_magazine_t *current; slab_magazine_t *last; SPINLOCK_DECLARE(lock); } slab_mag_cache_t; typedef struct { link_t link; /* Configuration */ /** Size of slab position - align_up(sizeof(obj)) */ size_t size; // int (*constructor)(void *obj, int kmflag); // int (*destructor)(void *obj); /** Flags changing behaviour of cache */ int flags; /* Computed values */ u32_t order; /**< Order of frames to be allocated */ unsigned int objects; /**< Number of objects that fit in */ /* Statistics */ atomic_t allocated_slabs; atomic_t allocated_objs; atomic_t cached_objs; /** How many magazines in magazines list */ atomic_t magazine_counter; /* Slabs */ link_t full_slabs; /**< List of full slabs */ link_t partial_slabs; /**< List of partial slabs */ SPINLOCK_DECLARE(slablock); /* Magazines */ link_t magazines; /**< List o full magazines */ SPINLOCK_DECLARE(maglock); /** CPU cache */ slab_mag_cache_t *mag_cache; } slab_cache_t; typedef struct { link_t link; /**< List of full/partial slabs. */ slab_cache_t *cache; /**< Pointer to parent cache. */ count_t available; /**< Count of available items in this slab. */ void *start; /**< Start address of first item. */ void *nextavail; /**< The index of next available item. */ } slab_t; #define SLAB_INSIDE_SIZE (4096 >> 3) /** Maximum wasted space we allow for cache */ #define SLAB_MAX_BADNESS(cache) (((size_t) PAGE_SIZE << (cache)->order) >> 2) /** Do not use per-cpu cache */ #define SLAB_CACHE_NOMAGAZINE 0x1 /** Have control structure inside SLAB */ #define SLAB_CACHE_SLINSIDE 0x2 /** We add magazine cache later, if we have this flag */ #define SLAB_CACHE_MAGDEFERRED (0x4 | SLAB_CACHE_NOMAGAZINE) slab_cache_t * slab_cache_create( size_t size, size_t align, int (*constructor)(void *obj, int kmflag), int (*destructor)(void *obj), int flags); void* __fastcall slab_alloc(slab_cache_t *cache, int flags); void __fastcall slab_free(slab_cache_t *cache, void *obj);