Go to the source code of this file.
Data Structures | |
struct | ctl_pool_base |
This is a dynamically grown memory pool class it provides a 'bottomless' expandable pool of like-sized things, typically of the same class, to allocate. More... | |
Defines | |
#define | ctl_malloc(ptr, size) _ctlmalloc( ppCastPtr(void**)&(ptr),(size) ppDebugParam( ppFileLine("ctl_malloc") ) ) |
Allocate some uninitialized memory. | |
#define | ctl_calloc(ptr, nelem, size) _ctlcalloc( ppCastPtr(void**)&(ptr),(nelem),(size) ppDebugParam( ppFileLine("ctl_calloc") ) ) |
Allocate some zero-filled memory. | |
#define | ctl_realloc(ptr, size) _ctlrealloc( ppCastPtr(void**)&(ptr),(size) ppDebugParam( ppFileLine("ctl_realloc") ) ) |
Reallocate some memory. | |
#define | ctl_free(ptr) _ctlfree( ppCastPtr(void**)&(ptr) ppDebugParam( ppFileLine("ctl_free") ) ) |
Release memory previously allocated. | |
#define | ctl_size(ptr) _ctlsize( (ptr) ppDebugParam( ppFileLine("ctl_size") ) ) |
Find out how big a particular allocation was; handy for all kinds of things... especially for keeping track of allocation sizes. TODO: Certain platforms may already have this in the runtims data.... | |
#define | ctl_strdup(ptr, sz) _ctlstrdup( (char**)&(ptr), (sz) ppDebugParam( ppFileLine("ctl_strdup") ) ) |
Copy an 8-bit ASCII string. | |
#define | ctl_wcsdup(ptr, sz) _ctlwcsdup( (wchar_t**)&(ptr), (sz) ppDebugParam( ppFileLine("ctl_wcsdup") ) ) |
Copy a wide-character string. | |
#define | ctl_assertmem(ptr) assert( _ctlvalidate( (ptr), ppFileLine("ctl_assertmem") ) ) |
Assert an allocated pointer was allocated with a ctl allocation function. | |
#define | ctl_alloctype(ptr, type) ctl_malloc((ptr),sizeof(type)) |
Allocate something (usually a structure) by its type, and presets it to all-zero. | |
#define | ctl_alloc_array(ptr, type, count) ctl_malloc((ptr),sizeof(type)*(count)) |
Allocate an array of something(s) (usually a structure) by its type AND PERFORMS NO INITIALIZATION. | |
#define | ctl_calloctype(ptr, type) ctl_calloc((ptr),sizeof(type)) |
Allocate something (usually a structure) by its type, and presets it to all-zero. | |
#define | ctl_calloc_array(ptr, type, count) ctl_calloc((ptr),sizeof(type)*(count)) |
Allocate an array of something(s) (usually a structure) by its type AND PERFORMS NO INITIALIZATION. | |
#define | ctl_new(ptr, type) |
Allocate something (usually a structure) by its type. | |
#define | ctl_new_array(type, ptr, count) |
Allocate an array of something(s) (usually a structure) by its type, and performs INIT on each and every one. | |
#define | ctl_delete(ptr) _ctldelete( ppCastPtr(void**)&(ptr) ppDebugParam( ppFileLine("ctl_delete") ) ) |
Allocate something (usually a structure) by its type. | |
#define | ctl_ref(ptr, fromptr) _ctlref( ((ptr)=(fromptr)) ppDebugParam( ppFileLine("ctl_ref") ) ) |
Add a reference to an object allocated with ctl_new. | |
#define | ctl_deref(ptr) _ctldelete( ppCastPtr(void**)&(ptr) ppDebugParam( ppFileLine("ctl_deref") ) ) |
Remove a reference to an object allocated with ctl_new. | |
#define | ctl_refcount(ptr) _ctlrefcount( (ptr) ppDebugParam( ppFileLine("ctl_refcount") ) ) |
Get reference count of pointer, 0 if ptr is NULL. | |
#define | ctl_delete_array(type, ptr, count) |
Perform a destroy on each member of array, then free the array. | |
#define | ctl_pool(type) ctl_pool_base |
Get the ctl_pool class type. | |
#define | ctl_pool_auto(type, pool, delta) ctl_pool_base_auto(sizeof(type),delta,pool) |
Declare a ctl_pool object as an auto, or global variable Uses non-standard ANSI extension: non-const initializers. | |
#define | ctl_pool_init(type, pool, delta) ctl_pool_base_init(pool,sizeof(type),delta,#pool) |
Initialize a typed ctl_pool. | |
#define | ctl_pool_grow(type, pool, size) ctl_pool_base_grow(pool,size) |
Force a pool to grow to an expected size. | |
#define | ctl_pool_destroy(type, pool) ctl_pool_base_destroy(pool) |
Free a pool - mainly used for onexit destruction. | |
#define | ctl_pool_alloc(type, pool, ptr) { (ptr) = (type*)ctl_pool_base_alloc(pool); } |
Allocate from a pool. | |
#define | ctl_pool_free(type, pool, ptr) { ctl_pool_base_free(pool, (ptr) ); (ptr) = NULL; } |
Allocate from a pool. | |
#define | ctl_pool_free_count(pool) ((pool)->cFree) |
Determine how many pre-allocated free pool allocations there are. | |
#define | ctl_pool_alloc_count(pool) ((pool)->cAlloc) |
Determine how many pool allocations there are. | |
#define | ctl_pool_count(pool) ((pool)->cAlloc+(pool)->cFree) |
Determine how many free+allocated,total allocations there are. | |
#define | ctl_pool_base_entry(unitSize, delta, label) { NULL, NULL, NULL, #label, (unitSize), (delta), 0,0 } |
Declare a ctl_pool_base object as a member of a table. | |
#define | ctl_pool_base_auto(unitSize, delta, label) ctl_pool_base label = ctl_pool_base_entry( unitSize, delta, label ) |
Declare a ctl_pool_base object as an auto, or global variable Uses non-standard ANSI extension: non-const initializers. | |
Typedefs | |
typedef void(* | ctl_newhandler )(const char *sz, size_t needed) |
Callback for allocation failures If this returns, retry allocation; else it most likely aborted. | |
Functions | |
ctl_newhandler | ctl_set_new_handler (ctl_newhandler handler) |
Set a handler for allocation failures. | |
size_t | ctl_memory_dump (uint32 logmask) |
If we have memory tracking, we can dump a list of what's allocated. | |
void | ctl_pool_base_init (ctl_pool_base *pool, size_t unitSize, size_t delta, const char *name) |
Initialize a ctl_pool_base. | |
void | ctl_pool_base_grow (ctl_pool_base *pool, size_t size) |
Force a pool to grow to an expected size. | |
void | ctl_pool_base_destroy (ctl_pool_base *pool) |
Free a pool - mainly used for onexit destruction. | |
void * | ctl_pool_base_alloc (ctl_pool_base *pool) |
Allocate a block of memory from this pool. | |
void | ctl_pool_base_free (ctl_pool_base *pool, void *ptr) |
Return a pointer back to memory pool. | |
size_t | ctl_pool_dump (uint32 logmask) |
Dump a list of active memory pools. | |
void | ctl_destroy_all_pools (void) |
Dump a list of active memory pools. |
Definition in file ctlnew.h.
#define ctl_alloc_array | ( | ptr, | |||
type, | |||||
count | ) | ctl_malloc((ptr),sizeof(type)*(count)) |
Allocate an array of something(s) (usually a structure) by its type AND PERFORMS NO INITIALIZATION.
ptr | An lvalue type variable to receive the pointer; must be pre-initialized to NULL, or previously allocated data | |
type | Type of data (i.e. 'struct Thing') to allocate one of | |
count | Count of these things we want |
#define ctl_alloctype | ( | ptr, | |||
type | ) | ctl_malloc((ptr),sizeof(type)) |
Allocate something (usually a structure) by its type, and presets it to all-zero.
ptr | An lvalue type variable to receive the pointer; must be pre-initialized to NULL, or previously allocated data | |
type | Type of data (i.e. 'struct Thing') to allocate one of |
Definition at line 82 of file ctlnew.h.
Referenced by SocketsInit().
#define ctl_assertmem | ( | ptr | ) | assert( _ctlvalidate( (ptr), ppFileLine("ctl_assertmem") ) ) |
#define ctl_calloc | ( | ptr, | |||
nelem, | |||||
size | ) | _ctlcalloc( ppCastPtr(void**)&(ptr),(nelem),(size) ppDebugParam( ppFileLine("ctl_calloc") ) ) |
#define ctl_calloc_array | ( | ptr, | |||
type, | |||||
count | ) | ctl_calloc((ptr),sizeof(type)*(count)) |
Allocate an array of something(s) (usually a structure) by its type AND PERFORMS NO INITIALIZATION.
ptr | An lvalue type variable to receive the pointer; must be pre-initialized to NULL, or previously allocated data | |
type | Type of data (i.e. 'struct Thing') to allocate one of | |
count | Count of these things we want |
#define ctl_calloctype | ( | ptr, | |||
type | ) | ctl_calloc((ptr),sizeof(type)) |
Allocate something (usually a structure) by its type, and presets it to all-zero.
ptr | An lvalue type variable to receive the pointer; must be pre-initialized to NULL, or previously allocated data | |
type | Type of data (i.e. 'struct Thing') to allocate one of |
#define ctl_delete | ( | ptr | ) | _ctldelete( ppCastPtr(void**)&(ptr) ppDebugParam( ppFileLine("ctl_delete") ) ) |
#define ctl_delete_array | ( | type, | |||
ptr, | |||||
count | ) |
Value:
{\ type* ppScr2(dela,pcurr) = (ptr) + (count);\ const type* ppScr2(dela,end) = ppScr2(dela,pcurr);\ while( ppScr2(dela,pcurr)-- > ppScr2(dela,end) )\ ppConcat(type,_destroy)(ppScr2(dela,pcurr));\ ctl_free(ptr);\ }
type | Type of data (i.e. 'struct Thing') to allocate one of | |
ptr | A pointer that came from ctl_alloc_array or ctl_new_array | |
count | Count of these things we want Assumes 'type_destroy(type)' exists in some form |
#define ctl_deref | ( | ptr | ) | _ctldelete( ppCastPtr(void**)&(ptr) ppDebugParam( ppFileLine("ctl_deref") ) ) |
#define ctl_free | ( | ptr | ) | _ctlfree( ppCastPtr(void**)&(ptr) ppDebugParam( ppFileLine("ctl_free") ) ) |
Release memory previously allocated.
ptr | An lvalue type variable that's either NULL, or contains an allocated pointer |
Definition at line 40 of file ctlnew.h.
Referenced by ctl_pool_base_destroy(), Socket_Customize(), and SocketsShutdown().
#define ctl_malloc | ( | ptr, | |||
size | ) | _ctlmalloc( ppCastPtr(void**)&(ptr),(size) ppDebugParam( ppFileLine("ctl_malloc") ) ) |
Allocate some uninitialized memory.
ptr | An lvalue type variable to receive the pointer | |
size | Amount to allocate |
Definition at line 18 of file ctlnew.h.
Referenced by ctl_pool_base_grow(), Socket_Customize(), and SocketsInit().
#define ctl_new | ( | ptr, | |||
type | ) |
Value:
{\ void** ppScr(pptr) = ppCastPtr(void**)&(ptr);\ _ctlnew( (void**)ppScr(pptr), sizeof(type), ppCastPtr(void(*)(void*))ppConcat(type,_destroy) ppDebugParam( ppFileLine("ctl_new") ) );\ ppConcat(type,_init)((type*)*ppScr(pptr));\ }
ptr | An lvalue type variable to receive the pointer; must be pre-initialized to NULL, or previously allocated data | |
type | Type of data (i.e. 'struct Thing') to allocate one of Assumes 'type_init(type)' exists in some form |
#define ctl_new_array | ( | type, | |||
ptr, | |||||
count | ) |
Value:
{\ if( ctl_malloc((ptr),sizeof(type)*(count)) );\ {\ type* ppScr2(newa,pcurr) = (ptr);\ const type* ppScr2(newa,end) = ppScr2(newa,pcurr) + (count);\ while( ppScr2(newa,pcurr)++ < ppScr2(newa,end) )\ ppConcat(type,_init)(ppScr2(newa,pcurr));\ }\ }
ptr | An lvalue type variable to receive the pointer; must be pre-initialized to NULL, or previously allocated data | |
type | Type of data (i.e. 'struct Thing') to allocate one of | |
count | Count of these things we want Assumes 'type_init(type)' exists in some form |
#define ctl_pool | ( | type | ) | ctl_pool_base |
#define ctl_pool_alloc | ( | type, | |||
pool, | |||||
ptr | ) | { (ptr) = (type*)ctl_pool_base_alloc(pool); } |
#define ctl_pool_alloc_count | ( | pool | ) | ((pool)->cAlloc) |
#define ctl_pool_auto | ( | type, | |||
pool, | |||||
delta | ) | ctl_pool_base_auto(sizeof(type),delta,pool) |
#define ctl_pool_base_auto | ( | unitSize, | |||
delta, | |||||
label | ) | ctl_pool_base label = ctl_pool_base_entry( unitSize, delta, label ) |
Declare a ctl_pool_base object as an auto, or global variable Uses non-standard ANSI extension: non-const initializers.
unitSize | Size of an allocation from this pool | |
delta | Number of such units to grow by | |
label | A string to represent this with to debug / configure code |
#define ctl_pool_base_entry | ( | unitSize, | |||
delta, | |||||
label | ) | { NULL, NULL, NULL, #label, (unitSize), (delta), 0,0 } |
Declare a ctl_pool_base object as a member of a table.
unitSize | Size of an allocation from this pool | |
delta | Number of such units to grow by | |
label | A string to represent this with to debug / configure code |
#define ctl_pool_count | ( | pool | ) | ((pool)->cAlloc+(pool)->cFree) |
#define ctl_pool_destroy | ( | type, | |||
pool | ) | ctl_pool_base_destroy(pool) |
#define ctl_pool_free | ( | type, | |||
pool, | |||||
ptr | ) | { ctl_pool_base_free(pool, (ptr) ); (ptr) = NULL; } |
#define ctl_pool_free_count | ( | pool | ) | ((pool)->cFree) |
#define ctl_pool_grow | ( | type, | |||
pool, | |||||
size | ) | ctl_pool_base_grow(pool,size) |
#define ctl_pool_init | ( | type, | |||
pool, | |||||
delta | ) | ctl_pool_base_init(pool,sizeof(type),delta,#pool) |
#define ctl_realloc | ( | ptr, | |||
size | ) | _ctlrealloc( ppCastPtr(void**)&(ptr),(size) ppDebugParam( ppFileLine("ctl_realloc") ) ) |
Reallocate some memory.
ptr | An lvalue type variable to receive the pointer; must be pre-initialized to NULL, or previously allocated data | |
size | Amount to allocate; BEWARE: if zero, the memory is freed and the pointer is NULL |
#define ctl_ref | ( | ptr, | |||
fromptr | ) | _ctlref( ((ptr)=(fromptr)) ppDebugParam( ppFileLine("ctl_ref") ) ) |
#define ctl_refcount | ( | ptr | ) | _ctlrefcount( (ptr) ppDebugParam( ppFileLine("ctl_refcount") ) ) |
#define ctl_size | ( | ptr | ) | _ctlsize( (ptr) ppDebugParam( ppFileLine("ctl_size") ) ) |
Find out how big a particular allocation was; handy for all kinds of things... especially for keeping track of allocation sizes. TODO: Certain platforms may already have this in the runtims data....
ptr | An lvalue type variable that's either NULL, or contains an allocated pointer |
#define ctl_strdup | ( | ptr, | |||
sz | ) | _ctlstrdup( (char**)&(ptr), (sz) ppDebugParam( ppFileLine("ctl_strdup") ) ) |
Copy an 8-bit ASCII string.
CAUTION: Invokes realloc, so make sure ptr is NULL, first!
ptr | An lvalue type variable to receive the pointer; must be pre-initialized to NULL, or previously allocated data | |
sz | String to copy |
#define ctl_wcsdup | ( | ptr, | |||
sz | ) | _ctlwcsdup( (wchar_t**)&(ptr), (sz) ppDebugParam( ppFileLine("ctl_wcsdup") ) ) |
Copy a wide-character string.
CAUTION: Invokes realloc, so make sure ptr is NULL, first!
ptr | An lvalue type variable to receive the pointer; must be pre-initialized to NULL, or previously allocated data | |
sz | String to copy |
typedef void(* ctl_newhandler)(const char *sz, size_t needed) |
size_t ctl_memory_dump | ( | uint32 | logmask | ) |
If we have memory tracking, we can dump a list of what's allocated.
Dump memory and return count of blocks allocated
handler | Your provided function gets called back to tell where and how much memory was allocated |
Definition at line 325 of file ctlnew.c.
References dll_foreach.
00326 { 00327 size_t count = 0; 00328 dll_foreach( AllocList,allocated, memoryList, curr ) 00329 { 00330 count++; 00331 if( curr->check == HEAD_CHECK && curr->check2 == HEAD_CHECK ) 00332 { 00333 LOG( logmask, "%s: %u\n", curr->szFileLine, curr->size ); 00334 _ctlvalidate( ALLOC_OFFSET(curr), "ctl_memory_dump" ); 00335 } 00336 else 00337 { 00338 /* We can't trust any pointer between bad header checks */ 00339 LOG( LOG_ERROR, "Bad memory node link\n" ); 00340 break; 00341 } 00342 } 00343 return count; 00344 }
void* ctl_pool_base_alloc | ( | ctl_pool_base * | pool | ) |
Allocate a block of memory from this pool.
pool | Instance of pool to initialize |
Definition at line 488 of file ctlnew.c.
References ctl_pool_base::cAlloc, ctl_pool_base::cFree, ctl_pool_base_grow(), ctl_pool_base::delta, ctl_pool_base::freelist, ctl_pool_base_node::pool, sll_erase, and ctl_pool_base_node::specialization.
00489 { 00490 struct ctl_pool_base_node* pfree = pool->freelist; 00491 if( NULL == pfree ) 00492 { 00493 ctl_pool_base_grow( pool, pool->delta ); 00494 pfree = pool->freelist; 00495 } 00496 pool->cFree--; 00497 pool->cAlloc++; 00498 sll_erase(struct ctl_pool_base_node,specialization.free, pool->freelist, pfree ); 00499 ppDebug(pfree->specialization.pool = pool); 00500 return pfree+1; 00501 }
void ctl_pool_base_destroy | ( | ctl_pool_base * | pool | ) |
Free a pool - mainly used for onexit destruction.
pool | Instance of pool to initialize |
Definition at line 467 of file ctlnew.c.
References ctl_pool_base::blocks, ctl_free, ctl_pool_base_block::next, and sll_erase.
Referenced by ctl_destroy_all_pools().
00468 { 00469 /* Walk through each of our pool blocks, freeing the base pointer */ 00470 struct ctl_pool_base_block* curr = pool->blocks; 00471 pool->blocks = NULL; 00472 while( curr ) 00473 { 00474 struct ctl_pool_base_block* next = curr->next; 00475 ctl_free( curr ); 00476 curr = next; 00477 } 00478 /* Remove from active pool list; this instance may be falling out of scope, or being freed */ 00479 sll_erase(ctl_pool_base,poolList, ctl_pool_base_list, pool ); 00480 memset(pool,0,sizeof(*pool)); 00481 }
void ctl_pool_base_free | ( | ctl_pool_base * | pool, | |
void * | ptr | |||
) |
Return a pointer back to memory pool.
pool | Pool pointer came from | |
ptr | Pointer to free |
Definition at line 508 of file ctlnew.c.
References assert, assertobjptr, assertptr, ctl_pool_base::cAlloc, ctl_pool_base::cFree, ctl_pool_base::freelist, ctl_pool_base_node::pool, sll_push_front, and ctl_pool_base_node::specialization.
00509 { 00510 struct ctl_pool_base_node* pfree = (struct ctl_pool_base_node*)ptr-1; 00511 assertobjptr(pool); 00512 assertptr(ptr,4); 00513 00514 /* We should not be expecting a free if nothing has been allocated from this pool */ 00515 assert( pool->cAlloc > 0 ); 00516 00517 /* We stuck those pointers into the memory link nodes for a reason. */ 00518 assert( pfree->specialization.pool == pool ); 00519 00520 /* Add it back to the free list */ 00521 pool->cFree++; 00522 pool->cAlloc--; 00523 sll_push_front(struct ctl_pool_base_node,specialization.free, pool->freelist, pfree ); 00524 }
void ctl_pool_base_grow | ( | ctl_pool_base * | pool, | |
size_t | delta | |||
) |
Force a pool to grow to an expected size.
pool | Instance of pool to initialize | |
size | How many units to grow now | |
pool | Instance of pool to initialize | |
delta | How many units to grow now |
Definition at line 438 of file ctlnew.c.
References ctl_pool_base::blocks, ctl_pool_base::cFree, ctl_malloc, ctl_pool_base::freelist, ctl_pool_base_block::next, sll_push_front, and ctl_pool_base::unit.
Referenced by ctl_pool_base_alloc().
00439 { 00440 /* Need to allocate a new block */ 00441 struct ctl_pool_base_block* block; 00442 size_t unitSize = roundup(pool->unit, sizeof( struct ctl_pool_base_node )) + sizeof( struct ctl_pool_base_node ); 00443 size_t size = sizeof(struct ctl_pool_base_block) + (unitSize * delta); 00444 ctl_malloc( block, size ); 00445 /* Add to list of active pools */ 00446 if( !pool->blocks ) 00447 sll_push_front(ctl_pool_base,poolList, ctl_pool_base_list, pool ); 00448 sll_push_front(struct ctl_pool_base_block,next, pool->blocks, block ); 00449 { 00450 uint8* pCurr = (uint8*)block+size; 00451 size_t curr = delta; 00452 while( curr-- ) 00453 { 00454 struct ctl_pool_base_node* pfree; 00455 pCurr -= unitSize; 00456 pfree = (struct ctl_pool_base_node*)pCurr; 00457 sll_push_front(struct ctl_pool_base_node,specialization.free, pool->freelist, pfree ); 00458 } 00459 pool->cFree += delta; 00460 } 00461 }
void ctl_pool_base_init | ( | ctl_pool_base * | pool, | |
size_t | unitSize, | |||
size_t | delta, | |||
const char * | name | |||
) |
Initialize a ctl_pool_base.
pool | Instance of pool to initialize | |
unitSize | Size of an allocation unit | |
delta | How many units to grow at a time | |
name | Name to stick into data for future debugging help | |
pool | Instance of pool to initialize | |
unitSize | Size of an allocation unit | |
delta | How many units to grow at a time | |
name | Name of this pool |
Definition at line 417 of file ctlnew.c.
References assertconst, assertobjptr, ctl_pool_base::blocks, ctl_pool_base::cAlloc, ctl_pool_base::cFree, ctl_pool_base::delta, ctl_pool_base::freelist, ctl_pool_base::name, ctl_pool_base::poolList, and ctl_pool_base::unit.
00418 { 00419 assertobjptr(pool); 00420 assertconst(name,1); 00421 00422 /* Initialize a pool */ 00423 pool->freelist = NULL; 00424 pool->blocks = NULL; 00425 pool->poolList = NULL; 00426 pool->name = name; 00427 /* Units we deal with are allocated in values divisible by sizeof ctl_pool_base_node; setting aside room for one ctl_pool_base_node as well */ 00428 pool->unit = unitSize; 00429 pool->delta = delta; 00430 pool->cFree = pool->cAlloc = 0; 00431 }