1 /*  util.c  */
2 
3 #include "../ChvManager.h"
4 
5 #define MYDEBUG 0
6 
7 /*--------------------------------------------------------------------*/
8 /*
9    ------------------------------------------
10    return a pointer to a Chv object that has
11    been initialized with the input parameters
12 
13    created -- 98may02, cca
14    ------------------------------------------
15 */
16 Chv *
ChvManager_newObjectOfSizeNbytes(ChvManager * manager,int nbytesNeeded)17 ChvManager_newObjectOfSizeNbytes (
18    ChvManager   *manager,
19    int          nbytesNeeded
20 ) {
21 Chv   *chv, *prev ;
22 int    nbytesAvailable, newinstance ;
23 /*
24    ---------------
25    check the input
26    ---------------
27 */
28 if ( manager == NULL || nbytesNeeded <= 0 ) {
29    fprintf(stderr,
30            "\n fatal error in ChvMananger_newObjectOfSizeNbytes(%p,%d)"
31            "\n bad input\n", manager, nbytesNeeded) ;
32    exit(-1) ;
33 }
34 #if MYDEBUG > 0
35 fprintf(stdout, "\n\n %d bytes needed", nbytesNeeded) ;
36 fflush(stdout) ;
37 #endif
38 if ( manager->lock != NULL ) {
39 /*
40    -----------------------------------------------
41    lock the lock, get exclusive access to the list
42    -----------------------------------------------
43 */
44 #if MYDEBUG > 0
45    fprintf(stdout, "\n manager: locking") ;
46    fflush(stdout) ;
47 #endif
48    Lock_lock(manager->lock) ;
49    manager->nlocks++ ;
50 #if MYDEBUG > 0
51    fprintf(stdout, ", %d locks so far", manager->nlocks) ;
52    fflush(stdout) ;
53 #endif
54 }
55 /*
56    ----------------------------------------------------
57    find a Chv object with the required number of bytes
58    ----------------------------------------------------
59 */
60 for ( chv = manager->head, prev = NULL ;
61       chv != NULL ;
62       chv = chv->next ) {
63    nbytesAvailable = Chv_nbytesInWorkspace(chv) ;
64 #if MYDEBUG > 0
65    fprintf(stdout, "\n free chev %p, nbytes = %d",
66            chv, nbytesAvailable) ;
67    fflush(stdout) ;
68 #endif
69    if ( nbytesNeeded <= nbytesAvailable ) {
70       break ;
71    }
72    prev = chv ;
73 }
74 if ( chv != NULL ) {
75 /*
76    ---------------------------------------
77    suitable object found, remove from list
78    ---------------------------------------
79 */
80 #if MYDEBUG > 0
81    fprintf(stdout, "\n chv = %p, %d nbytes available",
82            chv, nbytesAvailable) ;
83    fflush(stdout) ;
84 #endif
85    if ( prev == NULL ) {
86       manager->head = chv->next ;
87    } else {
88       prev->next = chv->next ;
89    }
90    newinstance = 0 ;
91 } else {
92 /*
93    ------------------------------------------------------------------
94    no suitable object found, create new instance and allocate storage
95    ------------------------------------------------------------------
96 */
97    chv = Chv_new() ;
98 #if MYDEBUG > 0
99    fprintf(stdout, "\n new postponed chv = %p", chv) ;
100    fflush(stdout) ;
101 #endif
102    newinstance = 1 ;
103    DV_setSize(&chv->wrkDV, nbytesNeeded/sizeof(double)) ;
104 }
105 /*
106    -------------------------------
107    increment the statistics fields
108    -------------------------------
109 */
110 if ( newinstance == 1 ) {
111    manager->nbytesalloc += Chv_nbytesInWorkspace(chv) ;
112 }
113 manager->nactive++ ;
114 manager->nbytesactive += Chv_nbytesInWorkspace(chv) ;
115 manager->nbytesrequested += nbytesNeeded ;
116 #if MYDEBUG > 0
117 fprintf(stdout, "\n %d bytes active, %d bytes requested",
118         manager->nbytesactive, manager->nbytesrequested) ;
119 #endif
120 manager->nrequests++ ;
121 if ( manager->lock != NULL ) {
122 /*
123    -----------------------------------------------------
124    unlock the lock, release exclusive access to the list
125    -----------------------------------------------------
126 */
127    manager->nunlocks++ ;
128    Lock_unlock(manager->lock) ;
129 #if MYDEBUG > 0
130    fprintf(stdout, "\n manager: unlocking, %d unlocks so far",
131            manager->nunlocks) ;
132    fflush(stdout) ;
133 #endif
134 }
135 return(chv) ; }
136 
137 /*--------------------------------------------------------------------*/
138 /*
139    -----------------------
140    release a Chv instance
141 
142    created -- 98may02, cca
143    -----------------------
144 */
145 void
ChvManager_releaseObject(ChvManager * manager,Chv * chv1)146 ChvManager_releaseObject (
147    ChvManager   *manager,
148    Chv          *chv1
149 ) {
150 Chv   *chv2, *prev ;
151 int    nbytes1, nbytes2 ;
152 /*
153    ---------------
154    check the input
155    ---------------
156 */
157 if ( manager == NULL || chv1 == NULL ) {
158    fprintf(stderr,
159            "\n fatal error in ChvMananger_releaseObject(%p,%p)"
160            "\n bad input\n", manager, chv1) ;
161    exit(-1) ;
162 }
163 if ( manager->lock != NULL ) {
164 /*
165    -----------------------------------------------
166    lock the lock, get exclusive access to the list
167    -----------------------------------------------
168 */
169    Lock_lock(manager->lock) ;
170    manager->nlocks++ ;
171 }
172 manager->nreleases++ ;
173 manager->nbytesactive -= Chv_nbytesInWorkspace(chv1) ;
174 manager->nactive-- ;
175 if ( manager->mode == 0 ) {
176 /*
177    -------------------
178    release the storage
179    -------------------
180 */
181    Chv_free(chv1) ;
182 } else {
183 /*
184    --------------------------------------------------------
185    find a place in the list where the Chv objects are
186    sorted in ascending order of the size of their workspace
187    --------------------------------------------------------
188 */
189    nbytes1 = Chv_nbytesInWorkspace(chv1) ;
190 #if MYDEBUG > 0
191    fprintf(stdout, "\n\n trying to release chevron %p with %d bytes",
192            chv1, nbytes1) ;
193 #endif
194    for ( chv2 = manager->head, prev = NULL ;
195          chv2 != NULL ;
196          chv2 = chv2->next ) {
197       nbytes2 = Chv_nbytesInWorkspace(chv2) ;
198 #if MYDEBUG > 0
199       fprintf(stdout, "\n list chv %p with %d bytes", chv2, nbytes2) ;
200 #endif
201       if ( nbytes2 > nbytes1 ) {
202          break ;
203       }
204       prev = chv2 ;
205    }
206    if ( prev == NULL ) {
207       manager->head = chv1 ;
208 #if MYDEBUG > 0
209       fprintf(stdout, "\n manager->head = %p", chv1) ;
210 #endif
211    } else {
212       prev->next = chv1 ;
213 #if MYDEBUG > 0
214       fprintf(stdout, "\n %p->next = %p", prev, chv1) ;
215 #endif
216    }
217    chv1->next = chv2 ;
218 #if MYDEBUG > 0
219    fprintf(stdout, "\n %p->next = %p", chv1, chv2) ;
220 #endif
221 }
222 if ( manager->lock != NULL ) {
223 /*
224    -----------------------------------------------------
225    unlock the lock, release exclusive access to the list
226    -----------------------------------------------------
227 */
228    manager->nunlocks++ ;
229    Lock_unlock(manager->lock) ;
230 }
231 return ; }
232 
233 /*--------------------------------------------------------------------*/
234 /*
235    ------------------------------
236    release a list of Chv objects
237 
238    created -- 98may02, cca
239    ------------------------------
240 */
241 void
ChvManager_releaseListOfObjects(ChvManager * manager,Chv * head)242 ChvManager_releaseListOfObjects (
243    ChvManager   *manager,
244    Chv          *head
245 ) {
246 Chv   *chv1, *chv2, *prev ;
247 int    nbytes1, nbytes2 ;
248 /*
249    ---------------
250    check the input
251    ---------------
252 */
253 if ( manager == NULL || head == NULL ) {
254    fprintf(stderr,
255        "\n fatal error in ChvManager_releaseListOfObjects(%p,%p)"
256        "\n bad input\n", manager, head) ;
257    exit(-1) ;
258 }
259 if ( manager->lock != NULL ) {
260 /*
261    -----------------------------------------------
262    lock the lock, get exclusive access to the list
263    -----------------------------------------------
264 */
265    Lock_lock(manager->lock) ;
266    manager->nlocks++ ;
267 }
268 if ( manager->mode == 0 ) {
269 /*
270    ---------------
271    release storage
272    ---------------
273 */
274    while ( (chv1 = head) != NULL ) {
275       head = head->next ;
276       manager->nbytesactive -= Chv_nbytesInWorkspace(chv1) ;
277       manager->nactive-- ;
278       manager->nreleases++ ;
279       Chv_free(chv1) ;
280    }
281 } else {
282 /*
283    -------------------
284    recycle the objects
285    -------------------
286 */
287    while ( head != NULL ) {
288       chv1 = head ;
289       head = chv1->next ;
290 /*
291       --------------------------------------------------------
292       find a place in the list where the Chv objects are
293       sorted in ascending order of the size of their workspace
294       --------------------------------------------------------
295 */
296       nbytes1 = Chv_nbytesInWorkspace(chv1) ;
297 #if MYDEBUG > 0
298       fprintf(stdout, "\n\n trying to release chevron %p with %d bytes",
299               chv1, nbytes1) ;
300 #endif
301       for ( chv2 = manager->head, prev = NULL ;
302             chv2 != NULL ;
303             chv2 = chv2->next ) {
304          nbytes2 = Chv_nbytesInWorkspace(chv2) ;
305 #if MYDEBUG > 0
306          fprintf(stdout,
307                  "\n list chevron %p with %d bytes", chv2, nbytes2) ;
308 #endif
309          if ( nbytes2 > nbytes1 ) {
310             break ;
311          }
312          prev = chv2 ;
313       }
314       if ( prev == NULL ) {
315          manager->head = chv1 ;
316 #if MYDEBUG > 0
317          fprintf(stdout, "\n manager->head = %p", chv1) ;
318 #endif
319       } else {
320          prev->next = chv1 ;
321 #if MYDEBUG > 0
322          fprintf(stdout, "\n %p->next = %p", prev, chv1) ;
323 #endif
324       }
325       chv1->next = chv2 ;
326 #if MYDEBUG > 0
327       fprintf(stdout, "\n %p->next = %p", chv1, chv2) ;
328 #endif
329       manager->nbytesactive -= Chv_nbytesInWorkspace(chv1) ;
330       manager->nactive-- ;
331       manager->nreleases++ ;
332    }
333 }
334 if ( manager->lock != NULL ) {
335 /*
336    -----------------------------------------------------
337    unlock the lock, release exclusive access to the list
338    -----------------------------------------------------
339 */
340    manager->nunlocks++ ;
341    Lock_unlock(manager->lock) ;
342 }
343 return ; }
344 
345 /*--------------------------------------------------------------------*/
346