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