Data Structures | Files | Defines | Typedefs | Functions

EGmemSlab

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

Detailed Description

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:

Version:
0.9.0
History:
  • 2011-03-01
    • Make EGms_t thread-safe, i.e. a single memory pool can serve several threads. This makes the default memory manager for GMP thread safe as well
  • 2010-12-27
    • Add short-hand names for functions
  • 2008-10-06
    • Second implementation
  • 2005-07-30
    • First Implpementation.

Define Documentation

#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  ) 
Value:
({\
  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.

Parameters:
__Pool slab pool from where we will get the memory.
Returns:
pointer to an initialize element.
Examples:
eg_memslab.ex.c.

Definition at line 347 of file eg_memslab.h.

Referenced by EGsimNewEvent(), and main().

#define EGmemSlabPoolFree (   __ptr  ) 
Value:
({\
  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.

Parameters:
__ptr pointer to be returned to the pool.
Examples:
eg_memslab.ex.c.

Definition at line 383 of file eg_memslab.h.

Referenced by main().

#define EGmemSlabPoolInit (   pool,
  sz,
  constr_fn,
  dest_fn 
)
Value:
__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.

Parameters:
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.
Examples:
eg_memslab.ex.c.

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  ) 
Value:
({\
  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.

Parameters:
slab pointer within a slab memory.
Returns:
pointer to a void* of initialized memory by the given contructor in the slab pool.

Definition at line 248 of file eg_memslab.h.

#define EGmemSlabPushElement (   __ptr  ) 
Value:
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.

Parameters:
__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

short names for common functions

Definition at line 405 of file eg_memslab.h.

Referenced by work().

#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 Documentation

structure used to store a slab memory pool


Function Documentation

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.

Parameters:
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.

Parameters:
slab pointer to an area of the slab memory to be clear.
Note:
If debugging is enabled, then all fields will be poisoned so that subsequent use of this structure will fail (but for the free call). Also, if debugging is enabled, we will check that the slab has no element in use.
void EGmemSlabDisplay ( const EGmemSlab_t *const   slab,
FILE *  stream 
)

display given slab structure

Parameters:
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).

Parameters:
__Pool slab pool to be cleared.
Examples:
eg_memslab.ex.c.

Referenced by main().

void EGmemSlabPoolDisplay ( const EGmemSlabPool_t *const   pool,
FILE *  stream 
)

display given pool structure

Parameters:
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.

Parameters:
pool slab pool to be shrinked.
Examples:
eg_memslab.ex.c.

Referenced by main().

int main ( int  argc,
char **  argv 
)
static void my_constr ( void *  ptr  )  [static]

brief simple destructor for heap connectors

Examples:
eg_memslab.ex.c.

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

Examples:
eg_memslab.ex.c.

Definition at line 35 of file eg_memslab.ex.c.

References EGeHeapCnClear.

Referenced by main().