Data Structures | |
| struct | EGmemSlab_t |
| struct | EGmemSlabPool_t |
| structure used to store a slab memory pool More... | |
| struct | EGmsbControl_t |
| structure that holds the information relevant to each slab More... | |
Files | |
| file | eg_memslab.c |
| file | eg_memslab.ex.c |
| file | eg_memslab.h |
Defines | |
| #define | __EGmsbUPD1(__pool) |
| add one to the given pointer, if profiling is enabled, otherwise, do nothing | |
| #define | __EGmsbUPD2(__pool) |
| #define | __EGmspLock(__slab) |
| slab lock/unlock macros | |
| #define | __EGmspUnlock(__slab) |
| #define | EG_SLAB_DEBUG 1000 |
| local debug level for the slab allocator, the lower the level, the more testing will be done. | |
| #define | EG_SLAB_ENDMARK ((uint8_t)255U) |
| end of list marker, note that this can not be more than 255 | |
| #define | EG_SLAB_LLIMIT ((size_t)16) |
| #define | EG_SLAB_MASK (~(EG_SLAB_SIZE-1)) |
| mask to detect the position of a piece of memory within a slab | |
| #define | EG_SLAB_PAGE(__ptr) (((size_t)__ptr)&EG_SLAB_MASK) |
| Given a pointer, return a pointer to the beginning of the containing page. | |
| #define | EG_SLAB_POISON ((size_t)0xdeadbeef) |
| address used to check consistency if enabled | |
| #define | EG_SLAB_PROFILE 1000 |
| if set to one, enable profiling for the slab allocator | |
| #define | EG_SLAB_SIZE ((size_t)0x1000) |
| size of the memory slabs (in bytes ) | |
| #define | EG_SLAB_ULIMIT ((size_t)1023) |
| maximum size of the objects that can be allocated via slab. | |
| #define | EG_SLAB_VERBOSE 1000 |
| local verbose level for the slab allocator, the lower the level, the more information will be printed on screen. | |
| #define | EGmemSlabGetSlab(__ptr) ((EGmemSlab_t*)(EG_SLAB_PAGE(__ptr))) |
| given a piece of memory that should be within a slab, return the pointer to the related slab structure, remember that the slab structure is at the beggining of the page. | |
| #define | EGmemSlabPoolAlloc(__Pool) |
| Given a slab pool, return an element from the pool. | |
| #define | EGmemSlabPoolFree(__ptr) |
| Given a pointer to an element allocated through a slab pool, give it back to the pool. | |
| #define | EGmemSlabPoolInit(pool, sz, constr_fn, dest_fn) |
| initialize a slab pool as an empty pool for elements of the given size, and with te given constructor and destructors. | |
| #define | EGmemSlabPoolInitProfile(_EGmPl, __sz, __file, __func, __line) |
| Initialize the profiling data of a slab pool. | |
| #define | EGmemSlabPopElement(slab) |
| Given a non-full slab, extract a pointer to the next unused element in the slab, and update all internal data. and if it becomes full, then move it to the full list within the pool. Also, if debugging, poison the pointer to the enext element in the returned element. If the slab is not full, and the number of active elements is one, then move the slab to the half-full slab list in the pool. | |
| #define | EGmemSlabPushElement(__ptr) |
| Given an used object within a slab, give it back to the slab for future use. | |
| #define | EGms_t EGmemSlabPool_t |
| #define | EGmsAlloc EGmemSlabPoolAlloc |
| short names for common functions | |
| #define | EGmsClear EGmemSlabPoolClear |
| #define | EGmsFree EGmemSlabPoolFree |
| #define | EGmsInit EGmemSlabPoolInit |
| #define | EGmsShrink EGmemSlabPoolShrink |
Typedefs | |
| typedef struct EGmemSlabPool_t | EGmemSlabPool_t |
| structure used to store a slab memory pool | |
Functions | |
| void | __EGmemSlabInit (EGmemSlab_t *const slab, EGmemSlabPool_t *const __Pool) |
| initialize a slab structure. This include calling the constructor for all elements in the slab. Note that this function asumes that all memory has been previously set to NULL. It will also place this slab in the list of empty slabs in the given pool. | |
| void | __EGmemSlabPoolInit (EGmemSlabPool_t *const pool, const size_t sz, EGconstructor_f constr_fn, EGdestructor_f dest_fn, const char *const file, const char *const func, const int line) |
| void | EGmemSlabClear (EGmemSlab_t *const slab) |
| given an initialized slab, clear all internally allocated memory, and leave the slab ready to be freed by 'free', this include calling the destructor for all elements in the slab. | |
| void | EGmemSlabDisplay (const EGmemSlab_t *const slab, FILE *stream) |
| display given slab structure | |
| void | EGmemSlabPoolClear (EGmemSlabPool_t *const __Pool) |
| clear a slab pool and all internal sub-structures and data, no further calls to this structure are posible after this (but for freeing the memory containing this data, or to re-initialize it). | |
| void | EGmemSlabPoolDisplay (const EGmemSlabPool_t *const pool, FILE *stream) |
| display given pool structure | |
| int | EGmemSlabPoolSetParam (EGmemSlabPool_t *const pool, const int param, const int val) |
| set parameters for a slab pool | |
| void | EGmemSlabPoolShrink (EGmemSlabPool_t *const pool) |
| Given a slab pool, free all unused slabs. | |
| int | main (int argc, char **argv) |
| this program expect only one parameter, the number of elements to be created. | |
| static void | my_constr (void *ptr) |
| static void | my_dest (void *ptr) |
| simple destructor for heap connectors | |
EGmemSlab Parameters | |
parameters for controling slab pool allocation | |
| #define | EG_MSLBP_FREEFREE 1 |
| control the handle of empty slabs, if set to non-zero, free unused slabs as they become unused, if set to zero, keep all unused slabs until EGmemSlabPoolShrink is called | |
This is a basic interface for slab pool managment. The idea comes from Slabs as defined in both Linux and Solaris (see "The Slab Allocator: An Object-Caching Kernel Memory Allocator", by Jeff Bonwick, Sun Microsystems), the basic idea is to provide pool for a specific type of object, and to store them in an initialized state, so that initialization and destruction only is done while growing/freeing the memory slabs, thus this approach should provide greater advantages for complitated to initialize structures. and in theory (althought not yet implemented) this structure can be managed so as to provide a shrinkable memory managment on the fly.
In this implementation we only allow small caches (i.e. objects must be smaller than EG_SLAB_ULIMIT and internally we don't allocate objects smaller than EG_SLAB_LLIMIT), within a unique memory page. We could allow in the future for more flexible slabs. This implementation also uses colored slabs (see the paper for further details).
Here we can see a schematic drawing of the slab allocator structure and functions:
| #define __EGmsbUPD1 | ( | __pool | ) |
add one to the given pointer, if profiling is enabled, otherwise, do nothing
Definition at line 338 of file eg_memslab.h.
| #define __EGmsbUPD2 | ( | __pool | ) |
Definition at line 339 of file eg_memslab.h.
| #define __EGmspLock | ( | __slab | ) |
slab lock/unlock macros
Definition at line 190 of file eg_memslab.h.
| #define __EGmspUnlock | ( | __slab | ) |
Definition at line 191 of file eg_memslab.h.
| #define EG_MSLBP_FREEFREE 1 |
control the handle of empty slabs, if set to non-zero, free unused slabs as they become unused, if set to zero, keep all unused slabs until EGmemSlabPoolShrink is called
Definition at line 76 of file eg_memslab.h.
| #define EG_SLAB_DEBUG 1000 |
local debug level for the slab allocator, the lower the level, the more testing will be done.
Definition at line 111 of file eg_memslab.h.
| #define EG_SLAB_ENDMARK ((uint8_t)255U) |
end of list marker, note that this can not be more than 255
Definition at line 115 of file eg_memslab.h.
| #define EG_SLAB_LLIMIT ((size_t)16) |
Definition at line 85 of file eg_memslab.h.
| #define EG_SLAB_MASK (~(EG_SLAB_SIZE-1)) |
mask to detect the position of a piece of memory within a slab
Definition at line 93 of file eg_memslab.h.
| #define EG_SLAB_PAGE | ( | __ptr | ) | (((size_t)__ptr)&EG_SLAB_MASK) |
Given a pointer, return a pointer to the beginning of the containing page.
Definition at line 128 of file eg_memslab.h.
| #define EG_SLAB_POISON ((size_t)0xdeadbeef) |
address used to check consistency if enabled
Definition at line 97 of file eg_memslab.h.
| #define EG_SLAB_PROFILE 1000 |
if set to one, enable profiling for the slab allocator
Definition at line 101 of file eg_memslab.h.
| #define EG_SLAB_SIZE ((size_t)0x1000) |
size of the memory slabs (in bytes )
Definition at line 89 of file eg_memslab.h.
| #define EG_SLAB_ULIMIT ((size_t)1023) |
maximum size of the objects that can be allocated via slab.
Definition at line 84 of file eg_memslab.h.
| #define EG_SLAB_VERBOSE 1000 |
local verbose level for the slab allocator, the lower the level, the more information will be printed on screen.
Definition at line 106 of file eg_memslab.h.
| #define EGmemSlabGetSlab | ( | __ptr | ) | ((EGmemSlab_t*)(EG_SLAB_PAGE(__ptr))) |
given a piece of memory that should be within a slab, return the pointer to the related slab structure, remember that the slab structure is at the beggining of the page.
Definition at line 211 of file eg_memslab.h.
| #define EGmemSlabPoolAlloc | ( | __Pool | ) |
({\
EGmemSlabPool_t*const _EGmPl = (__Pool);\
void*_EGmb = EGmalloc(_EGmPl->elem_sz+sizeof(void*));\
void**_EGpt = (void**)_EGmb;\
__EGmsbUPD1(_EGmPl);\
(*_EGpt) = _EGmPl;\
_EGmb=((void*)(_EGpt+1));\
if(_EGmPl->constr) _EGmPl->constr(_EGmb);\
_EGmb;})
Given a slab pool, return an element from the pool.
| __Pool | slab pool from where we will get the memory. |
Definition at line 347 of file eg_memslab.h.
Referenced by EGsimNewEvent(), and main().
| #define EGmemSlabPoolFree | ( | __ptr | ) |
({\
void**_EGptr = ((void**)(__ptr))-1;\
EGmemSlabPool_t*const _EGmPl = (EGmemSlabPool_t*)(*_EGptr);\
__EGmsbUPD2(_EGmPl);\
if(_EGmPl->dest) _EGmPl->dest(((void*)(_EGptr+1)));\
EGfree(_EGptr);})
Given a pointer to an element allocated through a slab pool, give it back to the pool.
| __ptr | pointer to be returned to the pool. |
Definition at line 383 of file eg_memslab.h.
Referenced by main().
| #define EGmemSlabPoolInit | ( | pool, | ||
| sz, | ||||
| constr_fn, | ||||
| dest_fn | ||||
| ) |
__EGmemSlabPoolInit(pool, sz, constr_fn, dest_fn, \ __FILE__, __func__, __LINE__)
initialize a slab pool as an empty pool for elements of the given size, and with te given constructor and destructors.
| constr_fn | constructor fnctioin for the elements to be stored in the pool. | |
| dest_fn | destructor function for the elements to be stored in the pool. | |
| pool | pointer to the slab pool to initialize. | |
| sz | (real) size (in bytes) of the elements to be hold. in the pool. This means that sz is the result of sizeof(TYPE), where TYPE is the structure to be pooled. |
Definition at line 311 of file eg_memslab.h.
Referenced by main().
| #define EGmemSlabPoolInitProfile | ( | _EGmPl, | ||
| __sz, | ||||
| __file, | ||||
| __func, | ||||
| __line | ||||
| ) |
Initialize the profiling data of a slab pool.
Definition at line 187 of file eg_memslab.c.
| #define EGmemSlabPopElement | ( | slab | ) |
({\
EGmemSlab_t*const _EGmSlb = EGmemSlabGetSlab(slab);\
EGmemSlabPool_t*const _EGPlRf = _EGmSlb->control.pool;\
const size_t _EGmSlb_esz = _EGmSlb->control.elem_sz;\
const size_t _EGmSlb_ne = _EGmSlb->control.next;\
const size_t _EGmSlb_nn = _EGmSlb->next_list[_EGmSlb_ne];\
void*const _EGelem = (void*)(_EGmSlb_ne*_EGmSlb_esz + _EGmSlb->control.base);\
/* now update the slab */\
_EGmSlb->control.n_elem++;\
_EGmSlb->control.next = _EGmSlb_nn;\
EXITL(EG_SLAB_DEBUG,_EGmSlb_ne == EG_SLAB_ENDMARK, "Allocating from full slab");\
/* if the slab is full, move it to full list */\
if(_EGmSlb_nn == EG_SLAB_ENDMARK){\
EGeListMoveAfter(&(_EGmSlb->control.slab_cn),&(_EGPlRf->full));}\
/* if the slab is first-time used, move to half list */\
else if(_EGmSlb->control.n_elem == 1U){\
EGeListMoveAfter(&(_EGmSlb->control.slab_cn),&(_EGPlRf->half));}\
/* return the element */\
_EGelem;})
Given a non-full slab, extract a pointer to the next unused element in the slab, and update all internal data. and if it becomes full, then move it to the full list within the pool. Also, if debugging, poison the pointer to the enext element in the returned element. If the slab is not full, and the number of active elements is one, then move the slab to the half-full slab list in the pool.
| slab | pointer within a slab memory. |
Definition at line 248 of file eg_memslab.h.
| #define EGmemSlabPushElement | ( | __ptr | ) |
do{\ char*const _EGmsbPtr = (char*)(__ptr);\ EGmemSlab_t*const _EGmSlb = EGmemSlabGetSlab(_EGmsbPtr);\ EGmemSlabPool_t*const _EGPlRf = _EGmSlb->control.pool;\ __EGmspLock(_EGPlRf);{\ const size_t _EGmSlb_esz = _EGmSlb->control.elem_sz;\ const size_t _EGmSlb_ne = _EGmSlb->control.next;\ const size_t _EGmSlb_nn = ((_EGmsbPtr) - _EGmSlb->control.base)/_EGmSlb_esz;\ /* if debugging, check for poison in the pointer to the next element in the \ * given element */\ EXITL(EG_SLAB_DEBUG, !_EGmSlb->control.n_elem, "freeing from an empty slab");\ /* now actually put the element into the slab */\ _EGmSlb->control.n_elem--;\ _EGmSlb->control.next = _EGmSlb_nn;\ _EGmSlb->next_list[_EGmSlb_nn] = _EGmSlb_ne;\ __EGmsbUPD2(_EGPlRf);\ /* if the slab is now not being used, update accordingly */\ if(_EGmSlb_ne == EG_SLAB_ENDMARK){\ EGeListMoveAfter(&(_EGmSlb->control.slab_cn),&(_EGPlRf->half));}\ else if(!_EGmSlb->control.n_elem){\ if(_EGPlRf->freefree){\ EGmemSlabClear(_EGmSlb);\ free((void*)_EGmSlb);}\ else{\ EGeListMoveAfter(&(_EGmSlb->control.slab_cn),&(_EGPlRf->empty));}}}\ __EGmspUnlock(_EGPlRf);\ }while(0)
Given an used object within a slab, give it back to the slab for future use.
| __ptr | pointer to the element to be given back to its containing slab. |
Definition at line 273 of file eg_memslab.h.
| #define EGms_t EGmemSlabPool_t |
Definition at line 409 of file eg_memslab.h.
| #define EGmsAlloc EGmemSlabPoolAlloc |
| #define EGmsClear EGmemSlabPoolClear |
Definition at line 408 of file eg_memslab.h.
Referenced by main().
| #define EGmsFree EGmemSlabPoolFree |
Definition at line 406 of file eg_memslab.h.
Referenced by work().
| #define EGmsInit EGmemSlabPoolInit |
Definition at line 407 of file eg_memslab.h.
Referenced by main().
| #define EGmsShrink EGmemSlabPoolShrink |
Definition at line 410 of file eg_memslab.h.
| typedef struct EGmemSlabPool_t EGmemSlabPool_t |
structure used to store a slab memory pool
| void __EGmemSlabInit | ( | EGmemSlab_t *const | slab, | |
| EGmemSlabPool_t *const | __Pool | |||
| ) |
initialize a slab structure. This include calling the constructor for all elements in the slab. Note that this function asumes that all memory has been previously set to NULL. It will also place this slab in the list of empty slabs in the given pool.
| slab | pointer within the memory range of the slab to be initialized. | |
| __Pool | Slab __Pool where this slab will bellong from. The slab pool should be initialized (i.e. should have a constructor and destructor, and an element size set. |
| void __EGmemSlabPoolInit | ( | EGmemSlabPool_t *const | pool, | |
| const size_t | sz, | |||
| EGconstructor_f | constr_fn, | |||
| EGdestructor_f | dest_fn, | |||
| const char *const | file, | |||
| const char *const | func, | |||
| const int | line | |||
| ) |
| void EGmemSlabClear | ( | EGmemSlab_t *const | slab | ) |
given an initialized slab, clear all internally allocated memory, and leave the slab ready to be freed by 'free', this include calling the destructor for all elements in the slab.
| slab | pointer to an area of the slab memory to be clear. |
| void EGmemSlabDisplay | ( | const EGmemSlab_t *const | slab, | |
| FILE * | stream | |||
| ) |
display given slab structure
| slab | what to display | |
| stream | where to print it |
| void EGmemSlabPoolClear | ( | EGmemSlabPool_t *const | __Pool | ) |
clear a slab pool and all internal sub-structures and data, no further calls to this structure are posible after this (but for freeing the memory containing this data, or to re-initialize it).
| __Pool | slab pool to be cleared. |
Referenced by main().
| void EGmemSlabPoolDisplay | ( | const EGmemSlabPool_t *const | pool, | |
| FILE * | stream | |||
| ) |
display given pool structure
| pool | what to display | |
| stream | where to print it |
| int EGmemSlabPoolSetParam | ( | EGmemSlabPool_t *const | pool, | |
| const int | param, | |||
| const int | val | |||
| ) |
set parameters for a slab pool
| void EGmemSlabPoolShrink | ( | EGmemSlabPool_t *const | pool | ) |
Given a slab pool, free all unused slabs.
| pool | slab pool to be shrinked. |
Referenced by main().
| int main | ( | int | argc, | |
| char ** | argv | |||
| ) |
this program expect only one parameter, the number of elements to be created.
Definition at line 44 of file eg_memslab.ex.c.
References EGeHeapAdd, EGeHeapChangeD, EGeHeapClear, EGeHeapDel, EGeHeapGetMin, EGeHeapInit, EGeHeapIsFull, EGeHeapResize, EGlib_info(), EGlib_version(), EGlpNumClear(), EGlpNumStart(), EGmemSlabPoolAlloc, EGmemSlabPoolClear(), EGmemSlabPoolFree, EGmemSlabPoolInit, EGmemSlabPoolShrink(), EGrandInit(), EGrandU01(), EGsetLimits(), EGsigSet, my_constr(), my_dest(), pool, seed, EGeHeap_t::sz, and EGeHeapCn_t::val.

| static void my_constr | ( | void * | ptr | ) | [static] |
brief simple destructor for heap connectors
Definition at line 28 of file eg_memslab.ex.c.
References EGeHeapCnInit.
Referenced by main().
| static void my_dest | ( | void * | ptr | ) | [static] |
simple destructor for heap connectors
Definition at line 35 of file eg_memslab.ex.c.
References EGeHeapCnClear.
Referenced by main().
1.7.1