1 /**CFile****************************************************************
2 
3   FileName    [utilMem.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Memory recycling utilities.]
8 
9   Synopsis    [Memory recycling utilities.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 20, 2005.]
16 
17   Revision    [$Id: utilMem.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <assert.h>
25 
26 #include "abc_global.h"
27 
28 ABC_NAMESPACE_IMPL_START
29 
30 ////////////////////////////////////////////////////////////////////////
31 ///                        DECLARATIONS                              ///
32 ////////////////////////////////////////////////////////////////////////
33 
34 
35 typedef struct Vec_Mem_t_       Vec_Mem_t;
36 struct Vec_Mem_t_
37 {
38     int              nCap;
39     int              nSize;
40     void **          pArray;
41 };
42 
43 void * s_vAllocs = NULL;
44 void * s_vFrees  = NULL;
45 int    s_fInterrupt = 0;
46 
47 #define ABC_MEM_ALLOC(type, num)     ((type *) malloc(sizeof(type) * (num)))
48 #define ABC_MEM_CALLOC(type, num)     ((type *) calloc((num), sizeof(type)))
49 #define ABC_MEM_FALLOC(type, num)     ((type *) memset(malloc(sizeof(type) * (num)), 0xff, sizeof(type) * (num)))
50 #define ABC_MEM_FREE(obj)             ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
51 #define ABC_MEM_REALLOC(type, obj, num)    \
52         ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
53          ((type *) malloc(sizeof(type) * (num))))
54 
55 ////////////////////////////////////////////////////////////////////////
56 ///                     FUNCTION DEFINITIONS                         ///
57 ////////////////////////////////////////////////////////////////////////
58 
59 /**Function*************************************************************
60 
61   Synopsis    [Allocates a vector with the given capacity.]
62 
63   Description []
64 
65   SideEffects []
66 
67   SeeAlso     []
68 
69 ***********************************************************************/
Vec_MemAlloc(int nCap)70 static inline Vec_Mem_t * Vec_MemAlloc( int nCap )
71 {
72     Vec_Mem_t * p;
73     p = ABC_MEM_ALLOC( Vec_Mem_t, 1 );
74     if ( nCap > 0 && nCap < 8 )
75         nCap = 8;
76     p->nSize  = 0;
77     p->nCap   = nCap;
78     p->pArray = p->nCap? ABC_MEM_ALLOC( void *, p->nCap ) : NULL;
79     return p;
80 }
81 
82 /**Function*************************************************************
83 
84   Synopsis    [Frees the vector.]
85 
86   Description []
87 
88   SideEffects []
89 
90   SeeAlso     []
91 
92 ***********************************************************************/
Vec_MemFree(Vec_Mem_t * p)93 static inline void Vec_MemFree( Vec_Mem_t * p )
94 {
95     ABC_MEM_FREE( p->pArray );
96     ABC_MEM_FREE( p );
97 }
98 
99 /**Function*************************************************************
100 
101   Synopsis    [Resizes the vector to the given capacity.]
102 
103   Description []
104 
105   SideEffects []
106 
107   SeeAlso     []
108 
109 ***********************************************************************/
Vec_MemGrow(Vec_Mem_t * p,int nCapMin)110 static inline void Vec_MemGrow( Vec_Mem_t * p, int nCapMin )
111 {
112     if ( p->nCap >= nCapMin )
113         return;
114     p->pArray = ABC_MEM_REALLOC( void *, p->pArray, nCapMin );
115     p->nCap   = nCapMin;
116 }
117 
118 /**Function*************************************************************
119 
120   Synopsis    []
121 
122   Description []
123 
124   SideEffects []
125 
126   SeeAlso     []
127 
128 ***********************************************************************/
Vec_MemPush(Vec_Mem_t * p,void * Entry)129 static inline void Vec_MemPush( Vec_Mem_t * p, void * Entry )
130 {
131     if ( p->nSize == p->nCap )
132     {
133         if ( p->nCap < 16 )
134             Vec_MemGrow( p, 16 );
135         else
136             Vec_MemGrow( p, 2 * p->nCap );
137     }
138     p->pArray[p->nSize++] = Entry;
139 }
140 
141 /**Function*************************************************************
142 
143   Synopsis    [Sorting the entries by their integer value.]
144 
145   Description []
146 
147   SideEffects []
148 
149   SeeAlso     []
150 
151 ***********************************************************************/
Vec_MemSort(Vec_Mem_t * p,int (* Vec_MemSortCompare)())152 static void Vec_MemSort( Vec_Mem_t * p, int (*Vec_MemSortCompare)() )
153 {
154     if ( p->nSize < 2 )
155         return;
156     qsort( (void *)p->pArray, (size_t)p->nSize, sizeof(void *),
157             (int (*)(const void *, const void *)) Vec_MemSortCompare );
158 }
159 
160 
161 /**Function*************************************************************
162 
163   Synopsis    [Remembers an allocated pointer.]
164 
165   Description []
166 
167   SideEffects []
168 
169   SeeAlso     []
170 
171 ***********************************************************************/
Util_MemRecAlloc(void * pMem)172 void * Util_MemRecAlloc( void * pMem )
173 {
174     if ( s_vAllocs )
175         Vec_MemPush( (Vec_Mem_t *)s_vAllocs, pMem );
176     return pMem;
177 }
178 
179 /**Function*************************************************************
180 
181   Synopsis    [Remembers a deallocated pointer.]
182 
183   Description []
184 
185   SideEffects []
186 
187   SeeAlso     []
188 
189 ***********************************************************************/
Util_MemRecFree(void * pMem)190 void * Util_MemRecFree( void * pMem )
191 {
192     if ( s_vFrees )
193         Vec_MemPush( (Vec_Mem_t *)s_vFrees, pMem );
194     return pMem;
195 }
196 
197 /**Function*************************************************************
198 
199   Synopsis    [Procedure used for sorting the nodes in decreasing order of levels.]
200 
201   Description []
202 
203   SideEffects []
204 
205   SeeAlso     []
206 
207 ***********************************************************************/
Util_ComparePointers(void ** pp1,void ** pp2)208 int Util_ComparePointers( void ** pp1, void ** pp2 )
209 {
210     if ( *pp1 < *pp2 )
211         return -1;
212     if ( *pp1 > *pp2 )
213         return 1;
214     return 0;
215 }
216 
217 /**Function*************************************************************
218 
219   Synopsis    [Finds entries that do not appear in both lists.]
220 
221   Description [Assumes that the vectors are sorted in the increasing order.]
222 
223   SideEffects []
224 
225   SeeAlso     []
226 
227 ***********************************************************************/
Vec_MemTwoMerge(Vec_Mem_t * vArr1,Vec_Mem_t * vArr2)228 static inline Vec_Mem_t * Vec_MemTwoMerge( Vec_Mem_t * vArr1, Vec_Mem_t * vArr2 )
229 {
230     Vec_Mem_t * vArr = Vec_MemAlloc( vArr1->nSize + vArr2->nSize );
231     void ** pBeg  = vArr->pArray;
232     void ** pBeg1 = vArr1->pArray;
233     void ** pBeg2 = vArr2->pArray;
234     void ** pEnd1 = vArr1->pArray + vArr1->nSize;
235     void ** pEnd2 = vArr2->pArray + vArr2->nSize;
236     while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
237     {
238         if ( *pBeg1 == *pBeg2 )
239             pBeg1++, pBeg2++;
240         else if ( *pBeg1 < *pBeg2 )
241         {
242             free( *pBeg1 );
243             *pBeg++ = *pBeg1++;
244         }
245         else
246             assert( 0 );
247 //            *pBeg++ = *pBeg2++;
248     }
249     while ( pBeg1 < pEnd1 )
250         *pBeg++ = *pBeg1++;
251 //    while ( pBeg2 < pEnd2 )
252 //        *pBeg++ = *pBeg2++;
253     assert( pBeg2 >= pEnd2 );
254     vArr->nSize = pBeg - vArr->pArray;
255     assert( vArr->nSize <= vArr->nCap );
256     assert( vArr->nSize >= vArr1->nSize );
257     assert( vArr->nSize >= vArr2->nSize );
258     return vArr;
259 }
260 
261 /**Function*************************************************************
262 
263   Synopsis    [Recycles the accumulated memory.]
264 
265   Description []
266 
267   SideEffects []
268 
269   SeeAlso     []
270 
271 ***********************************************************************/
Util_MemRecRecycle()272 void Util_MemRecRecycle()
273 {
274     Vec_Mem_t * vMerge;
275     assert( s_vAllocs == NULL );
276     assert( s_vFrees == NULL );
277     Vec_MemSort( (Vec_Mem_t *)s_vAllocs, (int (*)())Util_ComparePointers );
278     Vec_MemSort( (Vec_Mem_t *)s_vFrees, (int (*)())Util_ComparePointers );
279     vMerge = (Vec_Mem_t *)Vec_MemTwoMerge( (Vec_Mem_t *)s_vAllocs, (Vec_Mem_t *)s_vFrees );
280     Vec_MemFree( vMerge );
281 }
282 
283 /**Function*************************************************************
284 
285   Synopsis    [Starts memory structures.]
286 
287   Description []
288 
289   SideEffects []
290 
291   SeeAlso     []
292 
293 ***********************************************************************/
Util_MemRecStart()294 void Util_MemRecStart()
295 {
296     assert( s_vAllocs == NULL && s_vFrees == NULL );
297     s_vAllocs = Vec_MemAlloc( 1000 );
298     s_vFrees = Vec_MemAlloc( 1000 );
299 }
300 
301 /**Function*************************************************************
302 
303   Synopsis    [Quits memory structures.]
304 
305   Description []
306 
307   SideEffects []
308 
309   SeeAlso     []
310 
311 ***********************************************************************/
Util_MemRecQuit()312 void Util_MemRecQuit()
313 {
314     assert( s_vAllocs != NULL && s_vFrees != NULL );
315     Vec_MemFree( (Vec_Mem_t *)s_vAllocs );
316     Vec_MemFree( (Vec_Mem_t *)s_vFrees );
317 }
318 
319 /**Function*************************************************************
320 
321   Synopsis    [Starts memory structures.]
322 
323   Description []
324 
325   SideEffects []
326 
327   SeeAlso     []
328 
329 ***********************************************************************/
Util_MemRecIsSet()330 int Util_MemRecIsSet()
331 {
332     return s_vAllocs != NULL && s_vFrees != NULL;
333 }
334 
335 ////////////////////////////////////////////////////////////////////////
336 ///                       END OF FILE                                ///
337 ////////////////////////////////////////////////////////////////////////
338 
339 
340 ABC_NAMESPACE_IMPL_END
341 
342