#ifndef lib_slab_h #define lib_slab_h /* Cesar project {{{ * * Copyright (C) 2008 Spidcom * * <<>> * * }}} */ /** * \file lib/slab.h * \brief Slab allocator. * \ingroup lib * * Slab Allocator * ============== * * The slab allocator is a finer grain allocator. It allocates memory using * the block allocator and slices the allocated blocks into smaller memory * buffers, all with the same size. * * It solves two problems: * * - the need for an allocator with smaller allocation size than the block * allocator, * - reducing memory fragmentation. * * The allocation unit of this allocator is called an object. Objects are * allocated from a cache. * * A cache is a storage of objects of the same type. It allocates memory by * slabs, which corresponds here to blocks from the block allocator. Slabs * are then sliced into objects. * * Differences from other slab allocators: * * - does not try to cache constructed objects, only uses the memory * allocation part of slab allocators benefits. * - reference counting: an object can be referenced by several pointers, it * will be deallocated once every references are released. * - polymorphism: the cache structure is not needed to add or release a * reference, therefore, it can be done without knowing the underlying * type. */ #include "lib/blame.h" #include "lib/list.h" /** * Object destructor called just before the object memory is released. * \param object pointer to object data */ typedef void (*slab_object_destructor_t) (void *object); /** The slab cache structure. */ struct slab_cache_t { /** Cache name. */ const char *name; /** Size of objects in the cache. */ uint object_size; /** Number of object per slab. */ uint object_per_slab; /** Offset of the first object in a slab. */ uint object_offset_first; /** Offset of the next objects after the first. */ uint object_offset; /** Partially used slabs. */ list_t partial; /** Full slabs. */ uint full_nb; /** Destructor for objects in the cache. */ slab_object_destructor_t object_destructor; }; typedef struct slab_cache_t slab_cache_t; BEGIN_DECLS /** * Initialise the slab allocator. */ void slab_init (void); /** * Create a new slab cache. * \param cache cache structure * \param name cache name * \param object_size size of objects in the cache * \param object_destructor destructor for objects in the cache, or NULL if * none */ void slab_cache_init (slab_cache_t *cache, const char *name, uint object_size, slab_object_destructor_t object_destructor); /** * Destroy a slab cache. * \param cache cache structure * * The cache must be empty. */ void slab_cache_uninit (slab_cache_t *cache); /** * Allocate an object from the slab cache. * \param cache cache structure * \return the newly allocated object */ void * slab_alloc_ (slab_cache_t *cache __FL); #define slab_alloc(cache) slab_alloc_ ((cache) __fL) /** * Add a reference to a slab cache allocated object. * \param object referenced object */ void slab_addref_ (void *object __FL); #define slab_addref(object) slab_addref_ ((object) __fL) /** * Remove a reference to a slab cache allocated object. * \param object referenced object */ void slab_release_ (void *object __FL); #define slab_release(object) slab_release_ ((object) __fL) END_DECLS #endif /* lib_slab_h */