abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
extraUtilMemory.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [extraUtilMemory.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [extra]
8 
9  Synopsis [Memory managers.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - June 20, 2005.]
16 
17  Revision [$Id: extraUtilMemory.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "extra.h"
22 
24 
25 
26 /*---------------------------------------------------------------------------*/
27 /* Constant declarations */
28 /*---------------------------------------------------------------------------*/
29 
30 /*---------------------------------------------------------------------------*/
31 /* Stucture declarations */
32 /*---------------------------------------------------------------------------*/
33 
35 {
36  // information about individual entries
37  int nEntrySize; // the size of one entry
38  int nEntriesAlloc; // the total number of entries allocated
39  int nEntriesUsed; // the number of entries in use
40  int nEntriesMax; // the max number of entries in use
41  char * pEntriesFree; // the linked list of free entries
42 
43  // this is where the memory is stored
44  int nChunkSize; // the size of one chunk
45  int nChunksAlloc; // the maximum number of memory chunks
46  int nChunks; // the current number of memory chunks
47  char ** pChunks; // the allocated memory
48 
49  // statistics
50  int nMemoryUsed; // memory used in the allocated entries
51  int nMemoryAlloc; // memory allocated
52 };
53 
55 {
56  // information about individual entries
57  int nEntriesUsed; // the number of entries allocated
58  char * pCurrent; // the current pointer to free memory
59  char * pEnd; // the first entry outside the free memory
60 
61  // this is where the memory is stored
62  int nChunkSize; // the size of one chunk
63  int nChunksAlloc; // the maximum number of memory chunks
64  int nChunks; // the current number of memory chunks
65  char ** pChunks; // the allocated memory
66 
67  // statistics
68  int nMemoryUsed; // memory used in the allocated entries
69  int nMemoryAlloc; // memory allocated
70 };
71 
72 
74 {
75  int nMems; // the number of fixed memory managers employed
76  Extra_MmFixed_t ** pMems; // memory managers: 2^1 words, 2^2 words, etc
77  int nMapSize; // the size of the memory array
78  Extra_MmFixed_t ** pMap; // maps the number of bytes into its memory manager
79  int nLargeChunksAlloc; // the maximum number of large memory chunks
80  int nLargeChunks; // the current number of large memory chunks
81  void ** pLargeChunks; // the allocated large memory chunks
82 };
83 
84 /*---------------------------------------------------------------------------*/
85 /* Type declarations */
86 /*---------------------------------------------------------------------------*/
87 
88 /*---------------------------------------------------------------------------*/
89 /* Variable declarations */
90 /*---------------------------------------------------------------------------*/
91 
92 /*---------------------------------------------------------------------------*/
93 /* Macro declarations */
94 /*---------------------------------------------------------------------------*/
95 
96 
97 /**AutomaticStart*************************************************************/
98 
99 /*---------------------------------------------------------------------------*/
100 /* Static function prototypes */
101 /*---------------------------------------------------------------------------*/
102 
103 /**AutomaticEnd***************************************************************/
104 
105 
106 /*---------------------------------------------------------------------------*/
107 /* Definition of exported functions */
108 /*---------------------------------------------------------------------------*/
109 
110 /**Function*************************************************************
111 
112  Synopsis [Allocates memory pieces of fixed size.]
113 
114  Description [The size of the chunk is computed as the minimum of
115  1024 entries and 64K. Can only work with entry size at least 4 byte long.]
116 
117  SideEffects []
118 
119  SeeAlso []
120 
121 ***********************************************************************/
123 {
124  Extra_MmFixed_t * p;
125 
126  p = ABC_ALLOC( Extra_MmFixed_t, 1 );
127  memset( p, 0, sizeof(Extra_MmFixed_t) );
128 
129  p->nEntrySize = nEntrySize;
130  p->nEntriesAlloc = 0;
131  p->nEntriesUsed = 0;
132  p->pEntriesFree = NULL;
133 
134  if ( nEntrySize * (1 << 10) < (1<<16) )
135  p->nChunkSize = (1 << 10);
136  else
137  p->nChunkSize = (1<<16) / nEntrySize;
138  if ( p->nChunkSize < 8 )
139  p->nChunkSize = 8;
140 
141  p->nChunksAlloc = 64;
142  p->nChunks = 0;
143  p->pChunks = ABC_ALLOC( char *, p->nChunksAlloc );
144 
145  p->nMemoryUsed = 0;
146  p->nMemoryAlloc = 0;
147  return p;
148 }
149 
150 /**Function*************************************************************
151 
152  Synopsis []
153 
154  Description []
155 
156  SideEffects []
157 
158  SeeAlso []
159 
160 ***********************************************************************/
162 {
163  printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n",
164  p->nEntrySize, p->nChunkSize, p->nChunks );
165  printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n",
167 }
168 
169 /**Function*************************************************************
170 
171  Synopsis []
172 
173  Description []
174 
175  SideEffects []
176 
177  SeeAlso []
178 
179 ***********************************************************************/
181 {
182  int i;
183  if ( p == NULL )
184  return;
185  for ( i = 0; i < p->nChunks; i++ )
186  ABC_FREE( p->pChunks[i] );
187  ABC_FREE( p->pChunks );
188  ABC_FREE( p );
189 }
190 
191 /**Function*************************************************************
192 
193  Synopsis []
194 
195  Description []
196 
197  SideEffects []
198 
199  SeeAlso []
200 
201 ***********************************************************************/
203 {
204  char * pTemp;
205  int i;
206 
207  // check if there are still free entries
208  if ( p->nEntriesUsed == p->nEntriesAlloc )
209  { // need to allocate more entries
210  assert( p->pEntriesFree == NULL );
211  if ( p->nChunks == p->nChunksAlloc )
212  {
213  p->nChunksAlloc *= 2;
214  p->pChunks = ABC_REALLOC( char *, p->pChunks, p->nChunksAlloc );
215  }
216  p->pEntriesFree = ABC_ALLOC( char, p->nEntrySize * p->nChunkSize );
217  p->nMemoryAlloc += p->nEntrySize * p->nChunkSize;
218  // transform these entries into a linked list
219  pTemp = p->pEntriesFree;
220  for ( i = 1; i < p->nChunkSize; i++ )
221  {
222  *((char **)pTemp) = pTemp + p->nEntrySize;
223  pTemp += p->nEntrySize;
224  }
225  // set the last link
226  *((char **)pTemp) = NULL;
227  // add the chunk to the chunk storage
228  p->pChunks[ p->nChunks++ ] = p->pEntriesFree;
229  // add to the number of entries allocated
230  p->nEntriesAlloc += p->nChunkSize;
231  }
232  // incrememt the counter of used entries
233  p->nEntriesUsed++;
234  if ( p->nEntriesMax < p->nEntriesUsed )
235  p->nEntriesMax = p->nEntriesUsed;
236  // return the first entry in the free entry list
237  pTemp = p->pEntriesFree;
238  p->pEntriesFree = *((char **)pTemp);
239  return pTemp;
240 }
241 
242 /**Function*************************************************************
243 
244  Synopsis []
245 
246  Description []
247 
248  SideEffects []
249 
250  SeeAlso []
251 
252 ***********************************************************************/
254 {
255  // decrement the counter of used entries
256  p->nEntriesUsed--;
257  // add the entry to the linked list of free entries
258  *((char **)pEntry) = p->pEntriesFree;
259  p->pEntriesFree = pEntry;
260 }
261 
262 /**Function*************************************************************
263 
264  Synopsis []
265 
266  Description [Relocates all the memory except the first chunk.]
267 
268  SideEffects []
269 
270  SeeAlso []
271 
272 ***********************************************************************/
274 {
275  int i;
276  char * pTemp;
277 
278  // deallocate all chunks except the first one
279  for ( i = 1; i < p->nChunks; i++ )
280  ABC_FREE( p->pChunks[i] );
281  p->nChunks = 1;
282  // transform these entries into a linked list
283  pTemp = p->pChunks[0];
284  for ( i = 1; i < p->nChunkSize; i++ )
285  {
286  *((char **)pTemp) = pTemp + p->nEntrySize;
287  pTemp += p->nEntrySize;
288  }
289  // set the last link
290  *((char **)pTemp) = NULL;
291  // set the free entry list
292  p->pEntriesFree = p->pChunks[0];
293  // set the correct statistics
294  p->nMemoryAlloc = p->nEntrySize * p->nChunkSize;
295  p->nMemoryUsed = 0;
296  p->nEntriesAlloc = p->nChunkSize;
297  p->nEntriesUsed = 0;
298 }
299 
300 /**Function*************************************************************
301 
302  Synopsis []
303 
304  Description []
305 
306  SideEffects []
307 
308  SeeAlso []
309 
310 ***********************************************************************/
312 {
313  return p->nMemoryAlloc;
314 }
315 
316 /**Function*************************************************************
317 
318  Synopsis []
319 
320  Description []
321 
322  SideEffects []
323 
324  SeeAlso []
325 
326 ***********************************************************************/
328 {
329  return p->nEntriesMax;
330 }
331 
332 
333 /**Function*************************************************************
334 
335  Synopsis [Allocates entries of flexible size.]
336 
337  Description [Can only work with entry size at least 4 byte long.]
338 
339  SideEffects []
340 
341  SeeAlso []
342 
343 ***********************************************************************/
345 {
346  Extra_MmFlex_t * p;
347 //printf( "allocing flex\n" );
348  p = ABC_ALLOC( Extra_MmFlex_t, 1 );
349  memset( p, 0, sizeof(Extra_MmFlex_t) );
350 
351  p->nEntriesUsed = 0;
352  p->pCurrent = NULL;
353  p->pEnd = NULL;
354 
355  p->nChunkSize = (1 << 12);
356  p->nChunksAlloc = 64;
357  p->nChunks = 0;
358  p->pChunks = ABC_ALLOC( char *, p->nChunksAlloc );
359 
360  p->nMemoryUsed = 0;
361  p->nMemoryAlloc = 0;
362  return p;
363 }
364 
365 /**Function*************************************************************
366 
367  Synopsis []
368 
369  Description []
370 
371  SideEffects []
372 
373  SeeAlso []
374 
375 ***********************************************************************/
377 {
378  printf( "Flexible memory manager: Chunk size = %d. Chunks used = %d.\n",
379  p->nChunkSize, p->nChunks );
380  printf( " Entries used = %d. Memory used = %d. Memory alloc = %d.\n",
382 }
383 
384 /**Function*************************************************************
385 
386  Synopsis []
387 
388  Description []
389 
390  SideEffects []
391 
392  SeeAlso []
393 
394 ***********************************************************************/
396 {
397  int i;
398  if ( p == NULL )
399  return;
400 //printf( "deleting flex\n" );
401  for ( i = 0; i < p->nChunks; i++ )
402  ABC_FREE( p->pChunks[i] );
403  ABC_FREE( p->pChunks );
404  ABC_FREE( p );
405 }
406 
407 /**Function*************************************************************
408 
409  Synopsis []
410 
411  Description []
412 
413  SideEffects []
414 
415  SeeAlso []
416 
417 ***********************************************************************/
418 char * Extra_MmFlexEntryFetch( Extra_MmFlex_t * p, int nBytes )
419 {
420  char * pTemp;
421  // check if there are still free entries
422  if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd )
423  { // need to allocate more entries
424  if ( p->nChunks == p->nChunksAlloc )
425  {
426  p->nChunksAlloc *= 2;
427  p->pChunks = ABC_REALLOC( char *, p->pChunks, p->nChunksAlloc );
428  }
429  if ( nBytes > p->nChunkSize )
430  {
431  // resize the chunk size if more memory is requested than it can give
432  // (ideally, this should never happen)
433  p->nChunkSize = 2 * nBytes;
434  }
435  p->pCurrent = ABC_ALLOC( char, p->nChunkSize );
436  p->pEnd = p->pCurrent + p->nChunkSize;
437  p->nMemoryAlloc += p->nChunkSize;
438  // add the chunk to the chunk storage
439  p->pChunks[ p->nChunks++ ] = p->pCurrent;
440  }
441  assert( p->pCurrent + nBytes <= p->pEnd );
442  // increment the counter of used entries
443  p->nEntriesUsed++;
444  // keep track of the memory used
445  p->nMemoryUsed += nBytes;
446  // return the next entry
447  pTemp = p->pCurrent;
448  p->pCurrent += nBytes;
449  return pTemp;
450 }
451 
452 /**Function*************************************************************
453 
454  Synopsis []
455 
456  Description []
457 
458  SideEffects []
459 
460  SeeAlso []
461 
462 ***********************************************************************/
464 {
465  return p->nMemoryAlloc;
466 }
467 
468 
469 
470 
471 
472 /**Function*************************************************************
473 
474  Synopsis [Starts the hierarchical memory manager.]
475 
476  Description [This manager can allocate entries of any size.
477  Iternally they are mapped into the entries with the number of bytes
478  equal to the power of 2. The smallest entry size is 8 bytes. The
479  next one is 16 bytes etc. So, if the user requests 6 bytes, he gets
480  8 byte entry. If we asks for 25 bytes, he gets 32 byte entry etc.
481  The input parameters "nSteps" says how many fixed memory managers
482  are employed internally. Calling this procedure with nSteps equal
483  to 10 results in 10 hierarchically arranged internal memory managers,
484  which can allocate up to 4096 (1Kb) entries. Requests for larger
485  entries are handed over to malloc() and then ABC_FREE()ed.]
486 
487  SideEffects []
488 
489  SeeAlso []
490 
491 ***********************************************************************/
493 {
494  Extra_MmStep_t * p;
495  int i, k;
496  p = ABC_ALLOC( Extra_MmStep_t, 1 );
497  memset( p, 0, sizeof(Extra_MmStep_t) );
498  p->nMems = nSteps;
499  // start the fixed memory managers
500  p->pMems = ABC_ALLOC( Extra_MmFixed_t *, p->nMems );
501  for ( i = 0; i < p->nMems; i++ )
502  p->pMems[i] = Extra_MmFixedStart( (8<<i) );
503  // set up the mapping of the required memory size into the corresponding manager
504  p->nMapSize = (4<<p->nMems);
505  p->pMap = ABC_ALLOC( Extra_MmFixed_t *, p->nMapSize+1 );
506  p->pMap[0] = NULL;
507  for ( k = 1; k <= 4; k++ )
508  p->pMap[k] = p->pMems[0];
509  for ( i = 0; i < p->nMems; i++ )
510  for ( k = (4<<i)+1; k <= (8<<i); k++ )
511  p->pMap[k] = p->pMems[i];
512 //for ( i = 1; i < 100; i ++ )
513 //printf( "%10d: size = %10d\n", i, p->pMap[i]->nEntrySize );
514  return p;
515 }
516 
517 /**Function*************************************************************
518 
519  Synopsis [Stops the memory manager.]
520 
521  Description []
522 
523  SideEffects []
524 
525  SeeAlso []
526 
527 ***********************************************************************/
529 {
530  int i;
531  for ( i = 0; i < p->nMems; i++ )
532  Extra_MmFixedStop( p->pMems[i] );
533  if ( p->pLargeChunks )
534  {
535  for ( i = 0; i < p->nLargeChunks; i++ )
536  ABC_FREE( p->pLargeChunks[i] );
537  ABC_FREE( p->pLargeChunks );
538  }
539  ABC_FREE( p->pMems );
540  ABC_FREE( p->pMap );
541  ABC_FREE( p );
542 }
543 
544 /**Function*************************************************************
545 
546  Synopsis [Creates the entry.]
547 
548  Description []
549 
550  SideEffects []
551 
552  SeeAlso []
553 
554 ***********************************************************************/
555 char * Extra_MmStepEntryFetch( Extra_MmStep_t * p, int nBytes )
556 {
557  if ( nBytes == 0 )
558  return NULL;
559  if ( nBytes > p->nMapSize )
560  {
561 // printf( "Allocating %d bytes.\n", nBytes );
562 // return ABC_ALLOC( char, nBytes );
563  if ( p->nLargeChunks == p->nLargeChunksAlloc )
564  {
565  if ( p->nLargeChunksAlloc == 0 )
566  p->nLargeChunksAlloc = 32;
567  p->nLargeChunksAlloc *= 2;
569  }
570  p->pLargeChunks[ p->nLargeChunks++ ] = ABC_ALLOC( char, nBytes );
571  return (char *)p->pLargeChunks[ p->nLargeChunks - 1 ];
572  }
573  return Extra_MmFixedEntryFetch( p->pMap[nBytes] );
574 }
575 
576 
577 /**Function*************************************************************
578 
579  Synopsis [Recycles the entry.]
580 
581  Description []
582 
583  SideEffects []
584 
585  SeeAlso []
586 
587 ***********************************************************************/
588 void Extra_MmStepEntryRecycle( Extra_MmStep_t * p, char * pEntry, int nBytes )
589 {
590  if ( nBytes == 0 )
591  return;
592  if ( nBytes > p->nMapSize )
593  {
594 // ABC_FREE( pEntry );
595  return;
596  }
597  Extra_MmFixedEntryRecycle( p->pMap[nBytes], pEntry );
598 }
599 
600 /**Function*************************************************************
601 
602  Synopsis []
603 
604  Description []
605 
606  SideEffects []
607 
608  SeeAlso []
609 
610 ***********************************************************************/
612 {
613  int i, nMemTotal = 0;
614  for ( i = 0; i < p->nMems; i++ )
615  nMemTotal += p->pMems[i]->nMemoryAlloc;
616  return nMemTotal;
617 }
618 
619 /*---------------------------------------------------------------------------*/
620 /* Definition of internal functions */
621 /*---------------------------------------------------------------------------*/
622 
623 /*---------------------------------------------------------------------------*/
624 /* Definition of static functions */
625 /*---------------------------------------------------------------------------*/
626 
628 
char * memset()
Extra_MmStep_t * Extra_MmStepStart(int nSteps)
char * Extra_MmStepEntryFetch(Extra_MmStep_t *p, int nBytes)
static Llb_Mgr_t * p
Definition: llb3Image.c:950
void Extra_MmStepEntryRecycle(Extra_MmStep_t *p, char *pEntry, int nBytes)
#define ABC_REALLOC(type, obj, num)
Definition: abc_global.h:233
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int Extra_MmFixedReadMaxEntriesUsed(Extra_MmFixed_t *p)
for(p=first;p->value< newval;p=p->next)
void Extra_MmFixedEntryRecycle(Extra_MmFixed_t *p, char *pEntry)
void Extra_MmFixedStop(Extra_MmFixed_t *p)
void Extra_MmFixedRestart(Extra_MmFixed_t *p)
void Extra_MmFlexStop(Extra_MmFlex_t *p)
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
void Extra_MmStepStop(Extra_MmStep_t *p)
Extra_MmFixed_t ** pMems
void Extra_MmFlexPrint(Extra_MmFlex_t *p)
int Extra_MmFlexReadMemUsage(Extra_MmFlex_t *p)
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
void Extra_MmFixedPrint(Extra_MmFixed_t *p)
#define ABC_FREE(obj)
Definition: abc_global.h:232
Extra_MmFixed_t ** pMap
Extra_MmFixed_t * Extra_MmFixedStart(int nEntrySize)
#define assert(ex)
Definition: util_old.h:213
char * Extra_MmFlexEntryFetch(Extra_MmFlex_t *p, int nBytes)
int Extra_MmStepReadMemUsage(Extra_MmStep_t *p)
int Extra_MmFixedReadMemUsage(Extra_MmFixed_t *p)
char * Extra_MmFixedEntryFetch(Extra_MmFixed_t *p)
Extra_MmFlex_t * Extra_MmFlexStart()