#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "mem.h"
Go to the source code of this file.
Data Structures | |
struct | Mem_Fixed_t_ |
struct | Mem_Flex_t_ |
struct | Mem_Step_t_ |
Defines | |
#define | ALLOC(type, num) ((type *) malloc(sizeof(type) * (num))) |
#define | FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) |
#define | REALLOC(type, obj, num) |
Functions | |
Mem_Fixed_t * | Mem_FixedStart (int nEntrySize) |
void | Mem_FixedStop (Mem_Fixed_t *p, int fVerbose) |
char * | Mem_FixedEntryFetch (Mem_Fixed_t *p) |
void | Mem_FixedEntryRecycle (Mem_Fixed_t *p, char *pEntry) |
void | Mem_FixedRestart (Mem_Fixed_t *p) |
int | Mem_FixedReadMemUsage (Mem_Fixed_t *p) |
int | Mem_FixedReadMaxEntriesUsed (Mem_Fixed_t *p) |
Mem_Flex_t * | Mem_FlexStart () |
void | Mem_FlexStop (Mem_Flex_t *p, int fVerbose) |
char * | Mem_FlexEntryFetch (Mem_Flex_t *p, int nBytes) |
void | Mem_FlexRestart (Mem_Flex_t *p) |
int | Mem_FlexReadMemUsage (Mem_Flex_t *p) |
Mem_Step_t * | Mem_StepStart (int nSteps) |
void | Mem_StepStop (Mem_Step_t *p, int fVerbose) |
char * | Mem_StepEntryFetch (Mem_Step_t *p, int nBytes) |
void | Mem_StepEntryRecycle (Mem_Step_t *p, char *pEntry, int nBytes) |
int | Mem_StepReadMemUsage (Mem_Step_t *p) |
#define ALLOC | ( | type, | |||
num | ) | ((type *) malloc(sizeof(type) * (num))) |
#define FREE | ( | obj | ) | ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) |
#define REALLOC | ( | type, | |||
obj, | |||||
num | ) |
char* Mem_FixedEntryFetch | ( | Mem_Fixed_t * | p | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 167 of file mem.c.
00168 { 00169 char * pTemp; 00170 int i; 00171 00172 // check if there are still free entries 00173 if ( p->nEntriesUsed == p->nEntriesAlloc ) 00174 { // need to allocate more entries 00175 assert( p->pEntriesFree == NULL ); 00176 if ( p->nChunks == p->nChunksAlloc ) 00177 { 00178 p->nChunksAlloc *= 2; 00179 p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc ); 00180 } 00181 p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize ); 00182 p->nMemoryAlloc += p->nEntrySize * p->nChunkSize; 00183 // transform these entries into a linked list 00184 pTemp = p->pEntriesFree; 00185 for ( i = 1; i < p->nChunkSize; i++ ) 00186 { 00187 *((char **)pTemp) = pTemp + p->nEntrySize; 00188 pTemp += p->nEntrySize; 00189 } 00190 // set the last link 00191 *((char **)pTemp) = NULL; 00192 // add the chunk to the chunk storage 00193 p->pChunks[ p->nChunks++ ] = p->pEntriesFree; 00194 // add to the number of entries allocated 00195 p->nEntriesAlloc += p->nChunkSize; 00196 } 00197 // incrememt the counter of used entries 00198 p->nEntriesUsed++; 00199 if ( p->nEntriesMax < p->nEntriesUsed ) 00200 p->nEntriesMax = p->nEntriesUsed; 00201 // return the first entry in the free entry list 00202 pTemp = p->pEntriesFree; 00203 p->pEntriesFree = *((char **)pTemp); 00204 return pTemp; 00205 }
void Mem_FixedEntryRecycle | ( | Mem_Fixed_t * | p, | |
char * | pEntry | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 218 of file mem.c.
00219 { 00220 // decrement the counter of used entries 00221 p->nEntriesUsed--; 00222 // add the entry to the linked list of free entries 00223 *((char **)pEntry) = p->pEntriesFree; 00224 p->pEntriesFree = pEntry; 00225 }
int Mem_FixedReadMaxEntriesUsed | ( | Mem_Fixed_t * | p | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 292 of file mem.c.
00293 { 00294 return p->nEntriesMax; 00295 }
int Mem_FixedReadMemUsage | ( | Mem_Fixed_t * | p | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 276 of file mem.c.
00277 { 00278 return p->nMemoryAlloc; 00279 }
void Mem_FixedRestart | ( | Mem_Fixed_t * | p | ) |
Function*************************************************************
Synopsis []
Description [Relocates all the memory except the first chunk.]
SideEffects []
SeeAlso []
Definition at line 238 of file mem.c.
00239 { 00240 int i; 00241 char * pTemp; 00242 00243 // deallocate all chunks except the first one 00244 for ( i = 1; i < p->nChunks; i++ ) 00245 free( p->pChunks[i] ); 00246 p->nChunks = 1; 00247 // transform these entries into a linked list 00248 pTemp = p->pChunks[0]; 00249 for ( i = 1; i < p->nChunkSize; i++ ) 00250 { 00251 *((char **)pTemp) = pTemp + p->nEntrySize; 00252 pTemp += p->nEntrySize; 00253 } 00254 // set the last link 00255 *((char **)pTemp) = NULL; 00256 // set the free entry list 00257 p->pEntriesFree = p->pChunks[0]; 00258 // set the correct statistics 00259 p->nMemoryAlloc = p->nEntrySize * p->nChunkSize; 00260 p->nMemoryUsed = 0; 00261 p->nEntriesAlloc = p->nChunkSize; 00262 p->nEntriesUsed = 0; 00263 }
Mem_Fixed_t* Mem_FixedStart | ( | int | nEntrySize | ) |
FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Allocates memory pieces of fixed size.]
Description [The size of the chunk is computed as the minimum of 1024 entries and 64K. Can only work with entry size at least 4 byte long.]
SideEffects []
SeeAlso []
Definition at line 99 of file mem.c.
00100 { 00101 Mem_Fixed_t * p; 00102 00103 p = ALLOC( Mem_Fixed_t, 1 ); 00104 memset( p, 0, sizeof(Mem_Fixed_t) ); 00105 00106 p->nEntrySize = nEntrySize; 00107 p->nEntriesAlloc = 0; 00108 p->nEntriesUsed = 0; 00109 p->pEntriesFree = NULL; 00110 00111 if ( nEntrySize * (1 << 10) < (1<<16) ) 00112 p->nChunkSize = (1 << 10); 00113 else 00114 p->nChunkSize = (1<<16) / nEntrySize; 00115 if ( p->nChunkSize < 8 ) 00116 p->nChunkSize = 8; 00117 00118 p->nChunksAlloc = 64; 00119 p->nChunks = 0; 00120 p->pChunks = ALLOC( char *, p->nChunksAlloc ); 00121 00122 p->nMemoryUsed = 0; 00123 p->nMemoryAlloc = 0; 00124 return p; 00125 }
void Mem_FixedStop | ( | Mem_Fixed_t * | p, | |
int | fVerbose | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 138 of file mem.c.
00139 { 00140 int i; 00141 if ( p == NULL ) 00142 return; 00143 if ( fVerbose ) 00144 { 00145 printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n", 00146 p->nEntrySize, p->nChunkSize, p->nChunks ); 00147 printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n", 00148 p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc ); 00149 } 00150 for ( i = 0; i < p->nChunks; i++ ) 00151 free( p->pChunks[i] ); 00152 free( p->pChunks ); 00153 free( p ); 00154 }
char* Mem_FlexEntryFetch | ( | Mem_Flex_t * | p, | |
int | nBytes | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 371 of file mem.c.
00372 { 00373 char * pTemp; 00374 // check if there are still free entries 00375 if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd ) 00376 { // need to allocate more entries 00377 if ( p->nChunks == p->nChunksAlloc ) 00378 { 00379 p->nChunksAlloc *= 2; 00380 p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc ); 00381 } 00382 if ( nBytes > p->nChunkSize ) 00383 { 00384 // resize the chunk size if more memory is requested than it can give 00385 // (ideally, this should never happen) 00386 p->nChunkSize = 2 * nBytes; 00387 } 00388 p->pCurrent = ALLOC( char, p->nChunkSize ); 00389 p->pEnd = p->pCurrent + p->nChunkSize; 00390 p->nMemoryAlloc += p->nChunkSize; 00391 // add the chunk to the chunk storage 00392 p->pChunks[ p->nChunks++ ] = p->pCurrent; 00393 } 00394 assert( p->pCurrent + nBytes <= p->pEnd ); 00395 // increment the counter of used entries 00396 p->nEntriesUsed++; 00397 // keep track of the memory used 00398 p->nMemoryUsed += nBytes; 00399 // return the next entry 00400 pTemp = p->pCurrent; 00401 p->pCurrent += nBytes; 00402 return pTemp; 00403 }
int Mem_FlexReadMemUsage | ( | Mem_Flex_t * | p | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 444 of file mem.c.
00445 { 00446 return p->nMemoryUsed; 00447 }
void Mem_FlexRestart | ( | Mem_Flex_t * | p | ) |
Function*************************************************************
Synopsis []
Description [Relocates all the memory except the first chunk.]
SideEffects []
SeeAlso []
Definition at line 416 of file mem.c.
00417 { 00418 int i; 00419 if ( p->nChunks == 0 ) 00420 return; 00421 // deallocate all chunks except the first one 00422 for ( i = 1; i < p->nChunks; i++ ) 00423 free( p->pChunks[i] ); 00424 p->nChunks = 1; 00425 p->nMemoryAlloc = p->nChunkSize; 00426 // transform these entries into a linked list 00427 p->pCurrent = p->pChunks[0]; 00428 p->pEnd = p->pCurrent + p->nChunkSize; 00429 p->nEntriesUsed = 0; 00430 p->nMemoryUsed = 0; 00431 }
Mem_Flex_t* Mem_FlexStart | ( | ) |
Function*************************************************************
Synopsis [Allocates entries of flexible size.]
Description [Can only work with entry size at least 4 byte long.]
SideEffects []
SeeAlso []
Definition at line 310 of file mem.c.
00311 { 00312 Mem_Flex_t * p; 00313 00314 p = ALLOC( Mem_Flex_t, 1 ); 00315 memset( p, 0, sizeof(Mem_Flex_t) ); 00316 00317 p->nEntriesUsed = 0; 00318 p->pCurrent = NULL; 00319 p->pEnd = NULL; 00320 00321 p->nChunkSize = (1 << 14); 00322 p->nChunksAlloc = 64; 00323 p->nChunks = 0; 00324 p->pChunks = ALLOC( char *, p->nChunksAlloc ); 00325 00326 p->nMemoryUsed = 0; 00327 p->nMemoryAlloc = 0; 00328 return p; 00329 }
void Mem_FlexStop | ( | Mem_Flex_t * | p, | |
int | fVerbose | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 342 of file mem.c.
00343 { 00344 int i; 00345 if ( p == NULL ) 00346 return; 00347 if ( fVerbose ) 00348 { 00349 printf( "Flexible memory manager: Chunk size = %d. Chunks used = %d.\n", 00350 p->nChunkSize, p->nChunks ); 00351 printf( " Entries used = %d. Memory used = %d. Memory alloc = %d.\n", 00352 p->nEntriesUsed, p->nMemoryUsed, p->nMemoryAlloc ); 00353 } 00354 for ( i = 0; i < p->nChunks; i++ ) 00355 free( p->pChunks[i] ); 00356 free( p->pChunks ); 00357 free( p ); 00358 }
char* Mem_StepEntryFetch | ( | Mem_Step_t * | p, | |
int | nBytes | |||
) |
Function*************************************************************
Synopsis [Creates the entry.]
Description []
SideEffects []
SeeAlso []
Definition at line 536 of file mem.c.
00537 { 00538 if ( nBytes == 0 ) 00539 return NULL; 00540 if ( nBytes > p->nMapSize ) 00541 { 00542 // printf( "Allocating %d bytes.\n", nBytes ); 00543 /* 00544 if ( p->nLargeChunks == p->nLargeChunksAlloc ) 00545 { 00546 if ( p->nLargeChunksAlloc == 0 ) 00547 p->nLargeChunksAlloc = 5; 00548 p->nLargeChunksAlloc *= 2; 00549 p->pLargeChunks = REALLOC( char *, p->pLargeChunks, p->nLargeChunksAlloc ); 00550 } 00551 p->pLargeChunks[ p->nLargeChunks++ ] = ALLOC( char, nBytes ); 00552 return p->pLargeChunks[ p->nLargeChunks - 1 ]; 00553 */ 00554 return ALLOC( char, nBytes ); 00555 } 00556 return Mem_FixedEntryFetch( p->pMap[nBytes] ); 00557 }
void Mem_StepEntryRecycle | ( | Mem_Step_t * | p, | |
char * | pEntry, | |||
int | nBytes | |||
) |
Function*************************************************************
Synopsis [Recycles the entry.]
Description []
SideEffects []
SeeAlso []
Definition at line 571 of file mem.c.
00572 { 00573 if ( nBytes == 0 ) 00574 return; 00575 if ( nBytes > p->nMapSize ) 00576 { 00577 free( pEntry ); 00578 return; 00579 } 00580 Mem_FixedEntryRecycle( p->pMap[nBytes], pEntry ); 00581 }
int Mem_StepReadMemUsage | ( | Mem_Step_t * | p | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 594 of file mem.c.
00595 { 00596 int i, nMemTotal = 0; 00597 for ( i = 0; i < p->nMems; i++ ) 00598 nMemTotal += p->pMems[i]->nMemoryAlloc; 00599 return nMemTotal; 00600 }
Mem_Step_t* Mem_StepStart | ( | int | nSteps | ) |
Function*************************************************************
Synopsis [Starts the hierarchical memory manager.]
Description [This manager can allocate entries of any size. Iternally they are mapped into the entries with the number of bytes equal to the power of 2. The smallest entry size is 8 bytes. The next one is 16 bytes etc. So, if the user requests 6 bytes, he gets 8 byte entry. If we asks for 25 bytes, he gets 32 byte entry etc. The input parameters "nSteps" says how many fixed memory managers are employed internally. Calling this procedure with nSteps equal to 10 results in 10 hierarchically arranged internal memory managers, which can allocate up to 4096 (1Kb) entries. Requests for larger entries are handed over to malloc() and then free()ed.]
SideEffects []
SeeAlso []
Definition at line 473 of file mem.c.
00474 { 00475 Mem_Step_t * p; 00476 int i, k; 00477 p = ALLOC( Mem_Step_t, 1 ); 00478 memset( p, 0, sizeof(Mem_Step_t) ); 00479 p->nMems = nSteps; 00480 // start the fixed memory managers 00481 p->pMems = ALLOC( Mem_Fixed_t *, p->nMems ); 00482 for ( i = 0; i < p->nMems; i++ ) 00483 p->pMems[i] = Mem_FixedStart( (8<<i) ); 00484 // set up the mapping of the required memory size into the corresponding manager 00485 p->nMapSize = (4<<p->nMems); 00486 p->pMap = ALLOC( Mem_Fixed_t *, p->nMapSize+1 ); 00487 p->pMap[0] = NULL; 00488 for ( k = 1; k <= 4; k++ ) 00489 p->pMap[k] = p->pMems[0]; 00490 for ( i = 0; i < p->nMems; i++ ) 00491 for ( k = (4<<i)+1; k <= (8<<i); k++ ) 00492 p->pMap[k] = p->pMems[i]; 00493 //for ( i = 1; i < 100; i ++ ) 00494 //printf( "%10d: size = %10d\n", i, p->pMap[i]->nEntrySize ); 00495 return p; 00496 }
void Mem_StepStop | ( | Mem_Step_t * | p, | |
int | fVerbose | |||
) |
Function*************************************************************
Synopsis [Stops the memory manager.]
Description []
SideEffects []
SeeAlso []
Definition at line 509 of file mem.c.
00510 { 00511 int i; 00512 for ( i = 0; i < p->nMems; i++ ) 00513 Mem_FixedStop( p->pMems[i], fVerbose ); 00514 // if ( p->pLargeChunks ) 00515 // { 00516 // for ( i = 0; i < p->nLargeChunks; i++ ) 00517 // free( p->pLargeChunks[i] ); 00518 // free( p->pLargeChunks ); 00519 // } 00520 free( p->pMems ); 00521 free( p->pMap ); 00522 free( p ); 00523 }