/* util.c */
#include "../ChvManager.h"
#define MYDEBUG 0
/*--------------------------------------------------------------------*/
/*
------------------------------------------
return a pointer to a Chv object that has
been initialized with the input parameters
created -- 98may02, cca
------------------------------------------
*/
Chv *
ChvManager_newObjectOfSizeNbytes (
ChvManager *manager,
int nbytesNeeded
) {
Chv *chv, *prev ;
int nbytesAvailable, newinstance ;
/*
---------------
check the input
---------------
*/
if ( manager == NULL || nbytesNeeded <= 0 ) {
fprintf(stderr,
"\n fatal error in ChvMananger_newObjectOfSizeNbytes(%p,%d)"
"\n bad input\n", manager, nbytesNeeded) ;
exit(-1) ;
}
#if MYDEBUG > 0
fprintf(stdout, "\n\n %d bytes needed", nbytesNeeded) ;
fflush(stdout) ;
#endif
if ( manager->lock != NULL ) {
/*
-----------------------------------------------
lock the lock, get exclusive access to the list
-----------------------------------------------
*/
#if MYDEBUG > 0
fprintf(stdout, "\n manager: locking") ;
fflush(stdout) ;
#endif
Lock_lock(manager->lock) ;
manager->nlocks++ ;
#if MYDEBUG > 0
fprintf(stdout, ", %d locks so far", manager->nlocks) ;
fflush(stdout) ;
#endif
}
/*
----------------------------------------------------
find a Chv object with the required number of bytes
----------------------------------------------------
*/
for ( chv = manager->head, prev = NULL ;
chv != NULL ;
chv = chv->next ) {
nbytesAvailable = Chv_nbytesInWorkspace(chv) ;
#if MYDEBUG > 0
fprintf(stdout, "\n free chev %p, nbytes = %d",
chv, nbytesAvailable) ;
fflush(stdout) ;
#endif
if ( nbytesNeeded <= nbytesAvailable ) {
break ;
}
prev = chv ;
}
if ( chv != NULL ) {
/*
---------------------------------------
suitable object found, remove from list
---------------------------------------
*/
#if MYDEBUG > 0
fprintf(stdout, "\n chv = %p, %d nbytes available",
chv, nbytesAvailable) ;
fflush(stdout) ;
#endif
if ( prev == NULL ) {
manager->head = chv->next ;
} else {
prev->next = chv->next ;
}
newinstance = 0 ;
} else {
/*
------------------------------------------------------------------
no suitable object found, create new instance and allocate storage
------------------------------------------------------------------
*/
chv = Chv_new() ;
#if MYDEBUG > 0
fprintf(stdout, "\n new postponed chv = %p", chv) ;
fflush(stdout) ;
#endif
newinstance = 1 ;
DV_setSize(&chv->wrkDV, nbytesNeeded/sizeof(double)) ;
}
/*
-------------------------------
increment the statistics fields
-------------------------------
*/
if ( newinstance == 1 ) {
manager->nbytesalloc += Chv_nbytesInWorkspace(chv) ;
}
manager->nactive++ ;
manager->nbytesactive += Chv_nbytesInWorkspace(chv) ;
manager->nbytesrequested += nbytesNeeded ;
#if MYDEBUG > 0
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++ ;
Lock_unlock(manager->lock) ;
#if MYDEBUG > 0
fprintf(stdout, "\n manager: unlocking, %d unlocks so far",
manager->nunlocks) ;
fflush(stdout) ;
#endif
}
return(chv) ; }
/*--------------------------------------------------------------------*/
/*
-----------------------
release a Chv instance
created -- 98may02, cca
-----------------------
*/
void
ChvManager_releaseObject (
ChvManager *manager,
Chv *chv1
) {
Chv *chv2, *prev ;
int nbytes1, nbytes2 ;
/*
---------------
check the input
---------------
*/
if ( manager == NULL || chv1 == NULL ) {
fprintf(stderr,
"\n fatal error in ChvMananger_releaseObject(%p,%p)"
"\n bad input\n", manager, chv1) ;
exit(-1) ;
}
if ( manager->lock != NULL ) {
/*
-----------------------------------------------
lock the lock, get exclusive access to the list
-----------------------------------------------
*/
Lock_lock(manager->lock) ;
manager->nlocks++ ;
}
manager->nreleases++ ;
manager->nbytesactive -= Chv_nbytesInWorkspace(chv1) ;
manager->nactive-- ;
if ( manager->mode == 0 ) {
/*
-------------------
release the storage
-------------------
*/
Chv_free(chv1) ;
} else {
/*
--------------------------------------------------------
find a place in the list where the Chv objects are
sorted in ascending order of the size of their workspace
--------------------------------------------------------
*/
nbytes1 = Chv_nbytesInWorkspace(chv1) ;
#if MYDEBUG > 0
fprintf(stdout, "\n\n trying to release chevron %p with %d bytes",
chv1, nbytes1) ;
#endif
for ( chv2 = manager->head, prev = NULL ;
chv2 != NULL ;
chv2 = chv2->next ) {
nbytes2 = Chv_nbytesInWorkspace(chv2) ;
#if MYDEBUG > 0
fprintf(stdout, "\n list chv %p with %d bytes", chv2, nbytes2) ;
#endif
if ( nbytes2 > nbytes1 ) {
break ;
}
prev = chv2 ;
}
if ( prev == NULL ) {
manager->head = chv1 ;
#if MYDEBUG > 0
fprintf(stdout, "\n manager->head = %p", chv1) ;
#endif
} else {
prev->next = chv1 ;
#if MYDEBUG > 0
fprintf(stdout, "\n %p->next = %p", prev, chv1) ;
#endif
}
chv1->next = chv2 ;
#if MYDEBUG > 0
fprintf(stdout, "\n %p->next = %p", chv1, chv2) ;
#endif
}
if ( manager->lock != NULL ) {
/*
-----------------------------------------------------
unlock the lock, release exclusive access to the list
-----------------------------------------------------
*/
manager->nunlocks++ ;
Lock_unlock(manager->lock) ;
}
return ; }
/*--------------------------------------------------------------------*/
/*
------------------------------
release a list of Chv objects
created -- 98may02, cca
------------------------------
*/
void
ChvManager_releaseListOfObjects (
ChvManager *manager,
Chv *head
) {
Chv *chv1, *chv2, *prev ;
int nbytes1, nbytes2 ;
/*
---------------
check the input
---------------
*/
if ( manager == NULL || head == NULL ) {
fprintf(stderr,
"\n fatal error in ChvManager_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 ( manager->mode == 0 ) {
/*
---------------
release storage
---------------
*/
while ( (chv1 = head) != NULL ) {
head = head->next ;
manager->nbytesactive -= Chv_nbytesInWorkspace(chv1) ;
manager->nactive-- ;
manager->nreleases++ ;
Chv_free(chv1) ;
}
} else {
/*
-------------------
recycle the objects
-------------------
*/
while ( head != NULL ) {
chv1 = head ;
head = chv1->next ;
/*
--------------------------------------------------------
find a place in the list where the Chv objects are
sorted in ascending order of the size of their workspace
--------------------------------------------------------
*/
nbytes1 = Chv_nbytesInWorkspace(chv1) ;
#if MYDEBUG > 0
fprintf(stdout, "\n\n trying to release chevron %p with %d bytes",
chv1, nbytes1) ;
#endif
for ( chv2 = manager->head, prev = NULL ;
chv2 != NULL ;
chv2 = chv2->next ) {
nbytes2 = Chv_nbytesInWorkspace(chv2) ;
#if MYDEBUG > 0
fprintf(stdout,
"\n list chevron %p with %d bytes", chv2, nbytes2) ;
#endif
if ( nbytes2 > nbytes1 ) {
break ;
}
prev = chv2 ;
}
if ( prev == NULL ) {
manager->head = chv1 ;
#if MYDEBUG > 0
fprintf(stdout, "\n manager->head = %p", chv1) ;
#endif
} else {
prev->next = chv1 ;
#if MYDEBUG > 0
fprintf(stdout, "\n %p->next = %p", prev, chv1) ;
#endif
}
chv1->next = chv2 ;
#if MYDEBUG > 0
fprintf(stdout, "\n %p->next = %p", chv1, chv2) ;
#endif
manager->nbytesactive -= Chv_nbytesInWorkspace(chv1) ;
manager->nactive-- ;
manager->nreleases++ ;
}
}
if ( manager->lock != NULL ) {
/*
-----------------------------------------------------
unlock the lock, release exclusive access to the list
-----------------------------------------------------
*/
manager->nunlocks++ ;
Lock_unlock(manager->lock) ;
}
return ; }
/*--------------------------------------------------------------------*/
syntax highlighted by Code2HTML, v. 0.9.1