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