/* util.c */
#include "../SubMtxManager.h"
#define MYDEBUG 0
/*--------------------------------------------------------------------*/
/*
-----------------------------------------------
return a pointer to a SubMtx object that has
been initialized with the input parameters
created -- 98may02, cca
-----------------------------------------------
*/
SubMtx *
SubMtxManager_newObjectOfSizeNbytes (
SubMtxManager *manager,
int nbytesNeeded
) {
SubMtx *mtx, *prev ;
int nbytesAvailable, newinstance ;
/*
---------------
check the input
---------------
*/
if ( manager == NULL || nbytesNeeded <= 0 ) {
fprintf(stderr,
"\n fatal error in SubMtxMananger_newObjectOfSizeNbytes(%p,%d)"
"\n bad input\n", manager, nbytesNeeded) ;
exit(-1) ;
}
#if MYDEBUG > 1
fprintf(stdout,
"\n\n new mtx request, nbytes needed = %d", nbytesNeeded) ;
fflush(stdout) ;
#endif
if ( manager->lock != NULL ) {
/*
-----------------------------------------------
lock the lock, get exclusive access to the list
-----------------------------------------------
*/
Lock_lock(manager->lock) ;
#if MYDEBUG > 1
fprintf(stdout, "\n manager: lock is locked") ;
fflush(stdout) ;
#endif
manager->nlocks++ ;
#if MYDEBUG > 1
fprintf(stdout, "\n %d locks so far", manager->nlocks) ;
fflush(stdout) ;
#endif
}
/*
---------------------------------------------------------
find a SubMtx object with the required number of bytes
---------------------------------------------------------
*/
for ( mtx = manager->head, prev = NULL ;
mtx != NULL ;
mtx = mtx->next ) {
nbytesAvailable = SubMtx_nbytesInWorkspace(mtx) ;
#if MYDEBUG > 1
fprintf(stdout, "\n free mtx %p, nbytes = %d",
mtx, nbytesAvailable) ;
fflush(stdout) ;
#endif
if ( nbytesNeeded <= nbytesAvailable ) {
break ;
}
prev = mtx ;
}
if ( mtx != NULL ) {
/*
---------------------------------------
suitable object found, remove from list
---------------------------------------
*/
#if MYDEBUG > 1
fprintf(stdout, "\n mtx = %p, %d nbytes available",
mtx, nbytesAvailable) ;
fflush(stdout) ;
#endif
if ( prev == NULL ) {
manager->head = mtx->next ;
} else {
prev->next = mtx->next ;
}
newinstance = 0 ;
} else {
/*
------------------------------------------------------------------
no suitable object found, create new instance and allocate storage
------------------------------------------------------------------
*/
mtx = SubMtx_new() ;
#if MYDEBUG > 1
fprintf(stdout,
"\n no suitable object found, new mtx = %p, bytes = %d",
mtx, nbytesNeeded) ;
fflush(stdout) ;
#endif
newinstance = 1 ;
DV_setSize(&mtx->wrkDV, nbytesNeeded/sizeof(double)) ;
}
if ( newinstance == 1 ) {
manager->nbytesalloc += SubMtx_nbytesInWorkspace(mtx) ;
}
manager->nactive++ ;
manager->nbytesactive += SubMtx_nbytesInWorkspace(mtx) ;
manager->nbytesrequested += nbytesNeeded ;
#if MYDEBUG > 1
fprintf(stdout, "\n %d bytes active, %d bytes requested",
manager->nbytesactive, manager->nbytesrequested) ;
#endif
manager->nrequests++ ;
if ( manager->lock != NULL ) {
/*
-----------------------------------------------------
unlock the lock, release exclusive access to the list
-----------------------------------------------------
*/
manager->nunlocks++ ;
#if MYDEBUG > 1
fprintf(stdout, "\n manager: unlocking, %d unlocks so far",
manager->nunlocks) ;
fflush(stdout) ;
#endif
Lock_unlock(manager->lock) ;
}
return(mtx) ; }
/*--------------------------------------------------------------------*/
/*
----------------------------
release a SubMtx instance
created -- 98may02, cca
----------------------------
*/
void
SubMtxManager_releaseObject (
SubMtxManager *manager,
SubMtx *mtx1
) {
SubMtx *mtx2, *prev ;
int nbytes1, nbytes2 ;
/*
---------------
check the input
---------------
*/
if ( manager == NULL || mtx1 == NULL ) {
fprintf(stderr,
"\n fatal error in SubMtxManager_releaseObject(%p,%p)"
"\n bad input\n", manager, mtx1) ;
exit(-1) ;
}
if ( manager->lock != NULL ) {
/*
-----------------------------------------------
lock the lock, get exclusive access to the list
-----------------------------------------------
*/
Lock_lock(manager->lock) ;
manager->nlocks++ ;
#if MYDEBUG > 1
fprintf(stdout, "\n\n manager : locking in releaseObject, %d locks",
manager->nlocks) ;
fflush(stdout) ;
#endif
}
manager->nreleases++ ;
manager->nbytesactive -= SubMtx_nbytesInWorkspace(mtx1) ;
manager->nactive-- ;
if ( manager->mode == 0 ) {
/*
---------------
release storage
---------------
*/
SubMtx_free(mtx1) ;
} else {
/*
--------------------------------------------------------
find a place in the list where the SubMtx objects are
sorted in ascending order of the size of their workspace
--------------------------------------------------------
*/
nbytes1 = SubMtx_nbytesInWorkspace(mtx1) ;
#if MYDEBUG > 1
fprintf(stdout, "\n\n trying to release mtx %p with %d bytes",
mtx1, nbytes1) ;
#endif
for ( mtx2 = manager->head, prev = NULL ;
mtx2 != NULL ;
mtx2 = mtx2->next ) {
nbytes2 = SubMtx_nbytesInWorkspace(mtx2) ;
#if MYDEBUG > 1
fprintf(stdout, "\n list mtx %p with %d bytes", mtx2, nbytes2) ;
#endif
if ( nbytes2 >= nbytes1 ) {
break ;
}
prev = mtx2 ;
}
if ( prev == NULL ) {
manager->head = mtx1 ;
#if MYDEBUG > 1
fprintf(stdout, "\n manager->head = %p", mtx1) ;
#endif
} else {
prev->next = mtx1 ;
#if MYDEBUG > 1
fprintf(stdout, "\n %p->next = %p", prev, mtx1) ;
#endif
}
mtx1->next = mtx2 ;
#if MYDEBUG > 1
fprintf(stdout, "\n %p->next = %p", mtx1, mtx2) ;
#endif
}
if ( manager->lock != NULL ) {
/*
-----------------------------------------------------
unlock the lock, release exclusive access to the list
-----------------------------------------------------
*/
manager->nunlocks++ ;
#if MYDEBUG > 1
fprintf(stdout,
"\n manager : unlocking in releaseObject, %d unlocks",
manager->nunlocks) ;
fflush(stdout) ;
#endif
Lock_unlock(manager->lock) ;
}
return ; }
/*--------------------------------------------------------------------*/
/*
-----------------------------------
release a list of SubMtx objects
created -- 98may02, cca
-----------------------------------
*/
void
SubMtxManager_releaseListOfObjects (
SubMtxManager *manager,
SubMtx *head
) {
SubMtx *mtx1, *mtx2, *prev ;
int nbytes1, nbytes2 ;
/*
---------------
check the input
---------------
*/
if ( manager == NULL || head == NULL ) {
fprintf(stderr,
"\n fatal error in SubMtxManager_releaseListOfObjects(%p,%p)"
"\n bad input\n", manager, head) ;
exit(-1) ;
}
if ( manager->lock != NULL ) {
/*
-----------------------------------------------
lock the lock, get exclusive access to the list
-----------------------------------------------
*/
Lock_lock(manager->lock) ;
manager->nlocks++ ;
#if MYDEBUG > 1
fprintf(stdout,
"\n\n manager : locking in releaseListOfObjects, %d locks",
manager->nlocks) ;
fflush(stdout) ;
#endif
}
if ( manager->mode == 0 ) {
/*
---------------
release storage
---------------
*/
while ( (mtx1 = head) != NULL ) {
head = head->next ;
manager->nbytesactive -= SubMtx_nbytesInWorkspace(mtx1) ;
manager->nactive-- ;
manager->nreleases++ ;
SubMtx_free(mtx1) ;
}
} else {
/*
-------------------
recycle the objects
-------------------
*/
while ( head != NULL ) {
mtx1 = head ;
head = mtx1->next ;
/*
--------------------------------------------------------
find a place in the list where the SubMtx objects are
sorted in ascending order of the size of their workspace
--------------------------------------------------------
*/
nbytes1 = SubMtx_nbytesInWorkspace(mtx1) ;
#if MYDEBUG > 1
fprintf(stdout, "\n\n trying to release mtx %p with %d bytes",
mtx1, nbytes1) ;
#endif
for ( mtx2 = manager->head, prev = NULL ;
mtx2 != NULL ;
mtx2 = mtx2->next ) {
nbytes2 = SubMtx_nbytesInWorkspace(mtx2) ;
#if MYDEBUG > 1
fprintf(stdout,
"\n list mtx %p with %d bytes", mtx2, nbytes2) ;
#endif
if ( nbytes2 >= nbytes1 ) {
break ;
}
prev = mtx2 ;
}
if ( prev == NULL ) {
manager->head = mtx1 ;
#if MYDEBUG > 1
fprintf(stdout, "\n manager->head = %p", mtx1) ;
#endif
} else {
prev->next = mtx1 ;
#if MYDEBUG > 1
fprintf(stdout, "\n %p->next = %p", prev, mtx1) ;
#endif
}
mtx1->next = mtx2 ;
#if MYDEBUG > 1
fprintf(stdout, "\n %p->next = %p", mtx1, mtx2) ;
#endif
manager->nbytesactive -= SubMtx_nbytesInWorkspace(mtx1) ;
manager->nactive-- ;
manager->nreleases++ ;
#if MYDEBUG > 1
fprintf(stdout, "\n # releases = %d", manager->nreleases) ;
for ( mtx1 = manager->head ; mtx1 != NULL ; mtx1 = mtx1->next ) {
fprintf(stdout, "\n mtx (%d,%d), nbytes %d",
mtx1->rowid, mtx1->colid,
SubMtx_nbytesInWorkspace(mtx1)) ;
}
#endif
}
}
if ( manager->lock != NULL ) {
/*
-----------------------------------------------------
unlock the lock, release exclusive access to the list
-----------------------------------------------------
*/
manager->nunlocks++ ;
#if MYDEBUG > 1
fprintf(stdout,
"\n manager : unlocking in releaseListOfObjects, %d unlocks",
manager->nunlocks) ;
fflush(stdout) ;
#endif
Lock_unlock(manager->lock) ;
}
return ; }
/*--------------------------------------------------------------------*/
syntax highlighted by Code2HTML, v. 0.9.1