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