Changeset 1385 for trunk/psLib/src/sysUtils
- Timestamp:
- Aug 4, 2004, 1:37:39 PM (22 years ago)
- Location:
- trunk/psLib/src/sysUtils
- Files:
-
- 11 edited
-
psAbort.c (modified) (1 diff)
-
psError.c (modified) (1 diff)
-
psHash.c (modified) (13 diffs)
-
psHash.h (modified) (1 diff)
-
psLogMsg.c (modified) (3 diffs)
-
psLogMsg.h (modified) (1 diff)
-
psMemory.c (modified) (24 diffs)
-
psMemory.h (modified) (1 diff)
-
psString.c (modified) (1 diff)
-
psTrace.c (modified) (1 diff)
-
psType.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/sysUtils/psAbort.c
r1138 r1385 9 9 * @author Eric Van Alst, MHPCC 10 10 * 11 * @version $Revision: 1. 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-0 6-30 01:17:20$11 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sysUtils/psError.c
r1138 r1385 10 10 * @author Eric Van Alst, MHPCC 11 11 * 12 * @version $Revision: 1. 7$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 6-30 01:17:20$12 * @version $Revision: 1.8 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sysUtils/psHash.c
r1375 r1385 10 10 * @author George Gusciora, MHPCC 11 11 * 12 * @version $Revision: 1.1 3$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-08-04 01:21:33$12 * @version $Revision: 1.14 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 28 28 static void hashBucketFree( psHashBucket *bucket ); 29 29 static void *doHashWork( psHash* table, const char* key, void* data, bool remove 30 )31 ;30 ) 31 ; 32 32 static void hashFree( psHash *table ); 33 33 … … 45 45 psList *myLinkList = NULL; // The output data structure 46 46 psHashBucket *ptr = NULL; // Used to step thru linked list. 47 47 48 48 if ( table == NULL ) { 49 return NULL;50 }51 49 return NULL; 50 } 51 52 52 // Create the linked list 53 53 myLinkList = psListAlloc( NULL ); 54 54 55 55 // Loop through every bucket in the hash table. If that bucket is not 56 56 // NULL, then add the bucket's key to the linked list. 57 57 for ( i = 0;i < table->nbucket;i++ ) { 58 if ( table->buckets[ i ] != NULL ) { 59 // Since a bucket contains a linked list of keys/data, we must 60 // step trough each key in that linked list: 61 62 ptr = table->buckets[ i ]; 63 while ( ptr != NULL ) { 64 psListAdd( myLinkList, ptr->key, PS_LIST_HEAD ); 65 ptr = ptr->next; 66 } 67 } 58 if ( table->buckets[ i ] != NULL ) { 59 // Since a bucket contains a linked list of keys/data, we must 60 // step trough each key in that linked list: 61 62 ptr = table->buckets[ i ]; 63 while ( ptr != NULL ) { 64 psListAdd( myLinkList, ptr->key, PS_LIST_HEAD ); 65 ptr = ptr->next; 66 } 68 67 } 69 68 } 69 70 70 // Return the linked list 71 71 return ( myLinkList ); … … 89 89 { 90 90 if ( key == NULL ) { 91 psAbort( __func__, "psHashBucket() called with NULL key." );92 }93 91 psAbort( __func__, "psHashBucket() called with NULL key." ); 92 } 93 94 94 // Allocate memory for the new hash bucket. 95 95 psHashBucket *bucket = psAlloc( sizeof( psHashBucket ) ); 96 96 p_psMemSetDeallocator( bucket, ( psFreeFcn ) hashBucketFree ); 97 97 98 98 // Initialize the bucket. 99 99 bucket->key = psStringCopy( key ); 100 100 101 101 if ( data == NULL ) { 102 // NOTE: Should we flag a warning message?103 bucket->data = NULL;104 } else {105 bucket->data = psMemIncrRefCounter( data );106 }107 102 // NOTE: Should we flag a warning message? 103 bucket->data = NULL; 104 } else { 105 bucket->data = psMemIncrRefCounter( data ); 106 } 107 108 108 bucket->next = next; 109 109 110 110 return bucket; 111 111 } … … 123 123 { 124 124 if ( bucket == NULL ) { 125 return ;126 }127 125 return ; 126 } 127 128 128 // A bucket is actually a linked list of buckets. We recursively step 129 129 // through that linked list, free each bucket. 130 130 psFree( bucket->next ); 131 131 132 132 psFree( bucket->key ); 133 133 134 134 psFree( bucket->data ); 135 135 } … … 150 150 psHash *table = psAlloc( sizeof( psHash ) ); 151 151 p_psMemSetDeallocator( table, ( psFreeFcn ) hashFree ); 152 152 153 153 // Allocate memory for the buckets. 154 154 table->buckets = psAlloc( nbucket * sizeof( psHashBucket * ) ); 155 155 table->nbucket = nbucket; 156 156 157 157 psTrace( "utils.hash", 1, "Creating %d-element hash table\n", nbucket ); 158 158 159 159 // Initialize all buckets to NULL. 160 160 for ( i = 0; i < nbucket; i++ ) 161 {162 table->buckets[ i ] = NULL;163 }164 161 { 162 table->buckets[ i ] = NULL; 163 } 164 165 165 // Return the new hash table. 166 166 return table; … … 182 182 { 183 183 int i = 0; // Loop index variable. 184 184 185 185 if ( table == NULL ) { 186 return ;187 }188 186 return ; 187 } 188 189 189 // Loop through each bucket in the hash table. If that bucket is not 190 190 // NULL, then free the bucket via a function call to hashBucketFree(); 191 191 for ( i = 0; i < table->nbucket; i++ ) { 192 193 // A bucket is composed of a linked list of buckets. 194 if ( table->buckets[ i ] != NULL ) { 195 psFree( table->buckets[ i ] ); 196 } 192 193 // A bucket is composed of a linked list of buckets. 194 if ( table->buckets[ i ] != NULL ) { 195 psFree( table->buckets[ i ] ); 197 196 } 198 197 } 198 199 199 // Free the bucket structure, then the hash table. 200 200 psFree( table->buckets ); … … 221 221 *****************************************************************************/ 222 222 static void *doHashWork( psHash *table, const char *key, void *data, bool remove 223 )223 ) 224 224 { 225 225 long int hash = 1; // This will contain an integer value … … 229 229 psHashBucket *optr = NULL; // "original pointer": used to step 230 230 // thru the linked list for a bucket. 231 231 232 232 // The following condition should never be true, since this is a private 233 233 // function, but I'm checking it anyway since future coders might change 234 234 // the way this procedure is called. 235 235 if ( ( table == NULL ) || ( key == NULL ) ) { 236 237 psAbort( __func__, "psHashRemove() called with NULL key or table." );238 }239 236 237 psAbort( __func__, "psHashRemove() called with NULL key or table." ); 238 } 239 240 240 // NOTE: This is the originally supplied hash function. 241 241 // for (int i = 0, len = strlen(key); i < len; i++) { … … 243 243 // } 244 244 // hash &= (table->nbucket - 1); 245 245 246 246 // This hash algorithm is from Sedgewick. NOTE: must reread to ensure that 247 247 // the size of the hash table is not required to be a prime number. 248 248 tmpchar = ( char * ) key; 249 249 for ( hash = 0; *tmpchar != '\0'; tmpchar++ ) { 250 hash = ( 64 * hash + *tmpchar ) % ( table->nbucket );251 }252 250 hash = ( 64 * hash + *tmpchar ) % ( table->nbucket ); 251 } 252 253 253 // NOTE: This should not be necessary, but for now, I'm checking bounds 254 254 // anyway. 255 255 if ( ( hash < 0 ) || ( hash >= table->nbucket ) ) { 256 psAbort( __func__, "Internal hash function out of range (%d)", hash );257 }258 256 psAbort( __func__, "Internal hash function out of range (%d)", hash ); 257 } 258 259 259 // ptr will have the correct hash bucket. 260 260 ptr = table->buckets[ hash ]; 261 261 262 262 // We know the correct hash bucket, now we need to know what to do. 263 263 // If the data parameter is NULL, then, by definition, this is a retrieve 264 264 // or a remove operation on the hash table. 265 265 266 266 if ( data == NULL ) { 267 if ( remove267 if ( remove 268 268 ) { 269 // We search through the linked list for this bucket in 270 // the hash table and look for an entry for this key. 271 269 // We search through the linked list for this bucket in 270 // the hash table and look for an entry for this key. 271 272 optr = ptr; 273 while ( ptr != NULL ) { 274 // Dtermine if this entry holds the correct key. 275 if ( strcmp( key, ptr->key ) == 0 ) { 276 // The following lines of code are fairly standard ways 277 // of removing an item from a single-linked list. 278 279 void * data = ptr->data; 280 optr->next = ptr->next; 281 if ( ptr == table->buckets[ hash ] ) { 282 table->buckets[ hash ] = ptr->next; 283 } 284 285 psFree( ptr ); 286 287 // By definition, the data associated with that key 288 // must be returned, not freed. 289 return data; 290 } 272 291 optr = ptr; 273 while ( ptr != NULL ) {274 // Dtermine if this entry holds the correct key.275 if ( strcmp( key, ptr->key ) == 0 ) {276 // The following lines of code are fairly standard ways277 // of removing an item from a single-linked list.278 279 void * data = ptr->data;280 optr->next = ptr->next;281 if ( ptr == table->buckets[ hash ] ) {282 table->buckets[ hash ] = ptr->next;283 }284 285 psFree( ptr );286 287 // By definition, the data associated with that key288 // must be returned, not freed.289 return data;290 }291 optr = ptr;292 ptr = ptr->next;293 }294 return NULL; // not in hash295 }296 else {297 // If we get here, then a retrieve operation is requested. So,298 // we step trough the linked list at this bucket, and return the299 // data once we find it, or return NULL if we don't.300 while ( ptr != NULL ) {301 if ( strcmp( key, ptr->key ) == 0 ) {302 return ptr->data;303 }304 ptr = ptr->next;305 }306 return NULL; // not in hash307 }308 } else {309 // We get here if this procedure was called with non-NULL data.310 // Therefore, we should insert that data into the hash table.311 // First, we search through the linked list for this bucket in312 // the hash table and look for a duplicate entry for this key.313 314 while ( ptr != NULL ) {315 if ( strcmp( key, ptr->key ) == 0 ) {316 // We have found this key in the hash table.317 318 psTrace( "utils.hash.insert", 3, "Replacing data for %s\n",319 key );320 321 // NOTE: I have changed this behavior from the originally322 // supplied code. Formerly, if itemFree was NULL, then323 // the new data was not inserted into the hash table.324 325 psFree( ptr->data );326 327 ptr->data = psMemIncrRefCounter( data );328 return data;329 }330 292 ptr = ptr->next; 331 293 } 332 // We did not found key in the linked list for this bucket of the hash 333 // table. So, we insert this data at the head of that linked list. 334 335 table->buckets[ hash ] = hashBucketAlloc( key, 336 data, 337 table->buckets[ hash ] ); 338 return data; 294 return NULL; // not in hash 295 } 296 else { 297 // If we get here, then a retrieve operation is requested. So, 298 // we step trough the linked list at this bucket, and return the 299 // data once we find it, or return NULL if we don't. 300 while ( ptr != NULL ) { 301 if ( strcmp( key, ptr->key ) == 0 ) { 302 return ptr->data; 303 } 304 ptr = ptr->next; 305 } 306 return NULL; // not in hash 339 307 } 308 } else { 309 // We get here if this procedure was called with non-NULL data. 310 // Therefore, we should insert that data into the hash table. 311 // First, we search through the linked list for this bucket in 312 // the hash table and look for a duplicate entry for this key. 313 314 while ( ptr != NULL ) { 315 if ( strcmp( key, ptr->key ) == 0 ) { 316 // We have found this key in the hash table. 317 318 psTrace( "utils.hash.insert", 3, "Replacing data for %s\n", 319 key ); 320 321 // NOTE: I have changed this behavior from the originally 322 // supplied code. Formerly, if itemFree was NULL, then 323 // the new data was not inserted into the hash table. 324 325 psFree( ptr->data ); 326 327 ptr->data = psMemIncrRefCounter( data ); 328 return data; 329 } 330 ptr = ptr->next; 331 } 332 // We did not found key in the linked list for this bucket of the hash 333 // table. So, we insert this data at the head of that linked list. 334 335 table->buckets[ hash ] = hashBucketAlloc( key, 336 data, 337 table->buckets[ hash ] ); 338 return data; 339 } 340 340 } 341 341 … … 354 354 { 355 355 if ( table == NULL ) { 356 psAbort( __func__, "psHashInsert() called with NULL hash table." );357 }356 psAbort( __func__, "psHashInsert() called with NULL hash table." ); 357 } 358 358 if ( key == NULL ) { 359 psAbort( __func__, "psHashInsert() called with NULL key." );360 }359 psAbort( __func__, "psHashInsert() called with NULL key." ); 360 } 361 361 if ( data == NULL ) { 362 psAbort( __func__, "psHashLookup() called with NULL data." );363 }364 362 psAbort( __func__, "psHashLookup() called with NULL data." ); 363 } 364 365 365 return ( doHashWork( table, key, data, 0 ) != NULL ); 366 366 } … … 381 381 { 382 382 if ( table == NULL ) { 383 psAbort( __func__, "psHashLookup() called with NULL hash table." );384 }383 psAbort( __func__, "psHashLookup() called with NULL hash table." ); 384 } 385 385 if ( key == NULL ) { 386 psAbort( __func__, "psHashLookup() called with NULL key." );387 }388 389 386 psAbort( __func__, "psHashLookup() called with NULL key." ); 387 } 388 389 390 390 return doHashWork( table, key, NULL, 0 ); 391 391 } … … 405 405 void * data = NULL; 406 406 bool retVal = false; 407 407 408 408 if ( table == NULL ) { 409 psAbort( __func__, "psHashRemove() called with NULL hash table." );410 }409 psAbort( __func__, "psHashRemove() called with NULL hash table." ); 410 } 411 411 if ( key == NULL ) { 412 psAbort( __func__, "psHashRemove() called with NULL key." );413 }414 412 psAbort( __func__, "psHashRemove() called with NULL key." ); 413 } 414 415 415 data = doHashWork( table, key, NULL, 1 ); 416 416 if ( data != NULL ) { 417 psFree( data );418 retVal = true;419 } else {420 retVal = false;421 }417 psFree( data ); 418 retVal = true; 419 } else { 420 retVal = false; 421 } 422 422 return retVal; 423 423 } -
trunk/psLib/src/sysUtils/psHash.h
r1301 r1385 10 10 * @author George Gusciora, MHPCC 11 11 * 12 * @version $Revision: 1.1 6$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 7-27 23:09:23$12 * @version $Revision: 1.17 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sysUtils/psLogMsg.c
r1153 r1385 11 11 * @author George Gusciora, MHPCC 12 12 * 13 * @version $Revision: 1.2 0$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-0 6-30 20:22:37$13 * @version $Revision: 1.21 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-04 23:37:39 $ 15 15 * 16 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 132 132 psError(__func__,"The location, %s, for protocol 'dest' is invalid.",location); 133 133 return 1; 134 } else if (strcmp(protocol,"file") == 0) { 135 FILE* file = fopen(location,"w"); 136 if (file == NULL) { 137 psError(__func__,"Could not open file '%s' for output.",location); 138 return 1; 139 } 140 if (logDest != NULL && logDest != stderr && logDest != stdout) { 141 fclose(logDest); 142 } 143 logDest = file; 144 return 0; 145 } 134 } else 135 if (strcmp(protocol,"file") == 0) { 136 FILE* file = fopen(location,"w"); 137 if (file == NULL) { 138 psError(__func__,"Could not open file '%s' for output.",location); 139 return 1; 140 } 141 if (logDest != NULL && logDest != stderr && logDest != stdout) { 142 fclose(logDest); 143 } 144 logDest = file; 145 return 0; 146 } 146 147 147 148 psError(__func__,"Do not know how to handle the protocol '%s'.",protocol); … … 336 337 if (head_ptr > head) { 337 338 *head_ptr++ = '|'; 338 } else if (!logMsg) { // no output desired 339 return; 340 } 339 } else 340 if (!logMsg) { // no output desired 341 return; 342 } 341 343 *head_ptr = '\0'; 342 344 -
trunk/psLib/src/sysUtils/psLogMsg.h
r1153 r1385 11 11 * @author George Gusciora, MHPCC 12 12 * 13 * @version $Revision: 1.1 0$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-0 6-30 20:22:37$13 * @version $Revision: 1.11 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-04 23:37:39 $ 15 15 * 16 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sysUtils/psMemory.c
r1360 r1385 8 8 * @author Robert Lupton, Princeton University 9 9 * 10 * @version $Revision: 1.3 0$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-0 7-31 02:28:10$10 * @version $Revision: 1.31 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-04 23:37:39 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 47 47 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 48 48 }; 49 49 50 50 #ifdef PS_MEM_DEBUG 51 51 static psMemBlock* deadBlockList; // a place to put dead memBlocks in debug mode. … … 62 62 { 63 63 void * ptr = NULL; 64 64 65 65 pthread_mutex_lock( &recycleMemBlockListMutex ); 66 66 int level = recycleBins - 1; 67 67 while ( level >= 0 && ptr == NULL ) { 68 while ( recycleMemBlockList[ level ] != NULL && ptr == NULL ) {69 psMemBlock * old = recycleMemBlockList[ level ];70 recycleMemBlockList[ level ] = recycleMemBlockList[ level ] ->nextBlock;71 free( old );72 ptr = malloc( size );73 }74 level--;75 }68 while ( recycleMemBlockList[ level ] != NULL && ptr == NULL ) { 69 psMemBlock * old = recycleMemBlockList[ level ]; 70 recycleMemBlockList[ level ] = recycleMemBlockList[ level ] ->nextBlock; 71 free( old ); 72 ptr = malloc( size ); 73 } 74 level--; 75 } 76 76 pthread_mutex_unlock( &recycleMemBlockListMutex ); 77 77 78 78 return ptr; 79 79 } … … 84 84 { 85 85 psMemExhaustedCallback old = memExhaustedCallback; 86 86 87 87 if ( func != NULL ) { 88 memExhaustedCallback = func;89 } else {90 memExhaustedCallback = memExhaustedCallbackDefault;91 }92 88 memExhaustedCallback = func; 89 } else { 90 memExhaustedCallback = memExhaustedCallbackDefault; 91 } 92 93 93 return old; 94 94 } … … 98 98 { 99 99 if ( ptr->refCounter < 1 ) { 100 psError( __func__,101 "Block %ld allocated at %s:%d freed more than once at %s:%d\n",102 ptr->id, ptr->file, ptr->lineno, file, lineno );103 }104 100 psError( __func__, 101 "Block %ld allocated at %s:%d freed more than once at %s:%d\n", 102 ptr->id, ptr->file, ptr->lineno, file, lineno ); 103 } 104 105 105 if ( lineno > 0 ) { 106 psAbort( __func__, "Detected a problem in the memory system at %s:%d", file, lineno );107 }106 psAbort( __func__, "Detected a problem in the memory system at %s:%d", file, lineno ); 107 } 108 108 } 109 109 static psMemProblemCallback memProblemCallback = memProblemCallbackDefault; … … 112 112 { 113 113 psMemProblemCallback old = memProblemCallback; 114 114 115 115 if ( func != NULL ) { 116 memProblemCallback = func;117 } else {118 memProblemCallback = memProblemCallbackDefault;119 }120 116 memProblemCallback = func; 117 } else { 118 memProblemCallback = memProblemCallbackDefault; 119 } 120 121 121 return old; 122 122 } … … 133 133 psMemoryId old = p_psMemAllocateID; 134 134 p_psMemAllocateID = id; 135 135 136 136 return old; 137 137 } … … 141 141 psMemoryId old = p_psMemFreeID; 142 142 p_psMemFreeID = id; 143 143 144 144 return old; 145 145 } … … 154 154 { 155 155 static psMemoryId incr = 0; // "p_psMemAllocateID += incr" 156 156 157 157 return incr; 158 158 } … … 161 161 { 162 162 static psMemoryId incr = 0; // "p_psMemFreeID += incr" 163 163 164 164 return incr; 165 165 } … … 174 174 { 175 175 psMemFreeCallback old = memAllocateCallback; 176 176 177 177 if ( func != NULL ) { 178 memAllocateCallback = func;179 } else {180 memAllocateCallback = memAllocateCallbackDefault;181 }182 178 memAllocateCallback = func; 179 } else { 180 memAllocateCallback = memAllocateCallbackDefault; 181 } 182 183 183 return old; 184 184 } … … 187 187 { 188 188 psMemFreeCallback old = memFreeCallback; 189 189 190 190 if ( func != NULL ) { 191 memFreeCallback = func;192 } else {193 memFreeCallback = memFreeCallbackDefault;194 }195 191 memFreeCallback = func; 192 } else { 193 memFreeCallback = memFreeCallbackDefault; 194 } 195 196 196 return old; 197 197 } … … 206 206 id = memid + 1; 207 207 pthread_mutex_unlock( &memIdMutex ); 208 208 209 209 return id; 210 210 } … … 220 220 // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked, 221 221 // we shouldn't call such things as p_psAlloc/p_psFree here. 222 222 223 223 if ( m == NULL ) { 224 psError( funcName, "Memory Corruption: NULL memory block found." );225 return 1;226 }227 224 psError( funcName, "Memory Corruption: NULL memory block found." ); 225 return 1; 226 } 227 228 228 if ( m->refCounter == 0 ) { 229 // using an unreferenced block of memory, are you?230 psError( __func__, "Memory Corruption: memory block %ld was freed but still used.",231 m->id );232 return 1;233 }234 229 // using an unreferenced block of memory, are you? 230 psError( __func__, "Memory Corruption: memory block %ld was freed but still used.", 231 m->id ); 232 return 1; 233 } 234 235 235 if ( m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC ) { 236 psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer underflow)",237 m->id );238 return 1;239 }236 psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer underflow)", 237 m->id ); 238 return 1; 239 } 240 240 if ( *( void** ) ( ( int8_t* ) ( m + 1 ) + m->userMemorySize ) != P_PS_MEMMAGIC ) { 241 psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer overflow)",242 m->id );243 return 1;244 }245 241 psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer overflow)", 242 m->id ); 243 return 1; 244 } 245 246 246 return 0; 247 247 } … … 250 250 { 251 251 int nbad = 0; // number of bad blocks 252 252 253 253 // get exclusive access to the memBlock list to avoid it changing on us while we use it. 254 254 pthread_mutex_lock( &memBlockListMutex ); 255 255 256 256 for ( psMemBlock * iter = lastMemBlockAllocated; iter != NULL; iter = iter->nextBlock ) { 257 if ( checkMemBlock( iter, __func__ ) ) {258 nbad++;259 260 memProblemCallback( iter, __func__, __LINE__ );261 262 if ( abort_on_error ) {263 // release the lock on the memblock list264 pthread_mutex_unlock( &memBlockListMutex );265 psAbort( __func__, "Detected memory corruption" );266 return nbad;267 }268 }269 }270 257 if ( checkMemBlock( iter, __func__ ) ) { 258 nbad++; 259 260 memProblemCallback( iter, __func__, __LINE__ ); 261 262 if ( abort_on_error ) { 263 // release the lock on the memblock list 264 pthread_mutex_unlock( &memBlockListMutex ); 265 psAbort( __func__, "Detected memory corruption" ); 266 return nbad; 267 } 268 } 269 } 270 271 271 // release the lock on the memblock list 272 272 pthread_mutex_unlock( &memBlockListMutex ); … … 278 278 279 279 psMemBlock * ptr = NULL; 280 280 281 281 // memory is of the size I want to bother recycling? 282 282 if ( size < P_PS_LARGE_BLOCK_SIZE ) { 283 // find the bin we need. 284 int level = 0; 285 while ( size > recycleBinSize[ level ] ) { 286 level++; 283 // find the bin we need. 284 int level = 0; 285 while ( size > recycleBinSize[ level ] ) { 286 level++; 287 } 288 // Are we in one of the bins 289 if ( level < recycleBins ) { 290 291 size = recycleBinSize[ level ]; // round-up size to next sized bin. 292 293 pthread_mutex_lock( &recycleMemBlockListMutex ); 294 295 if ( recycleMemBlockList[ level ] != NULL ) { 296 ptr = recycleMemBlockList[ level ]; 297 recycleMemBlockList[ level ] = ptr->nextBlock; 298 if ( recycleMemBlockList[ level ] != NULL ) { 299 recycleMemBlockList[ level ] ->previousBlock = NULL; 287 300 } 288 // Are we in one of the bins 289 if ( level < recycleBins ) { 290 291 size = recycleBinSize[ level ]; // round-up size to next sized bin. 292 293 pthread_mutex_lock( &recycleMemBlockListMutex ); 294 295 if ( recycleMemBlockList[ level ] != NULL ) { 296 ptr = recycleMemBlockList[ level ]; 297 recycleMemBlockList[ level ] = ptr->nextBlock; 298 if ( recycleMemBlockList[ level ] != NULL ) { 299 recycleMemBlockList[ level ] ->previousBlock = NULL; 300 } 301 size = ptr->userMemorySize; 302 } 303 304 pthread_mutex_unlock( &recycleMemBlockListMutex ); 305 } 306 } 307 301 size = ptr->userMemorySize; 302 } 303 304 pthread_mutex_unlock( &recycleMemBlockListMutex ); 305 } 306 } 307 308 308 if ( ptr == NULL ) { 309 ptr = malloc( sizeof( psMemBlock ) + size + sizeof( void* ) ); 310 309 ptr = malloc( sizeof( psMemBlock ) + size + sizeof( void* ) ); 310 311 if ( ptr == NULL ) { 312 ptr = memExhaustedCallback( size ); 311 313 if ( ptr == NULL ) { 312 ptr = memExhaustedCallback( size ); 313 if ( ptr == NULL ) { 314 psAbort( __func__, "Failed to allocate %u bytes at %s:%d", 315 size, file, lineno ); 316 } 317 } 318 319 ptr->startblock = P_PS_MEMMAGIC; 320 ptr->endblock = P_PS_MEMMAGIC; 321 ptr->userMemorySize = size; 322 pthread_mutex_init( &ptr->refCounterMutex, NULL ); 323 } 324 314 psAbort( __func__, "Failed to allocate %u bytes at %s:%d", 315 size, file, lineno ); 316 } 317 } 318 319 ptr->startblock = P_PS_MEMMAGIC; 320 ptr->endblock = P_PS_MEMMAGIC; 321 ptr->userMemorySize = size; 322 pthread_mutex_init( &ptr->refCounterMutex, NULL ); 323 } 324 325 325 // increment the memory id safely. 326 326 pthread_mutex_lock( &memBlockListMutex ); 327 327 *( psMemoryId* ) & ptr->id = ++memid; 328 328 pthread_mutex_unlock( &memBlockListMutex ); 329 329 330 330 ptr->file = file; 331 331 ptr->freeFcn = NULL; … … 333 333 *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size ) = P_PS_MEMMAGIC; 334 334 ptr->previousBlock = NULL; 335 335 336 336 ptr->refCounter = 1; // one user so far 337 337 338 338 // need exclusive access of the memory block list now... 339 339 pthread_mutex_lock( &memBlockListMutex ); 340 340 341 341 // insert the new block to the front of the memBlock linked-list 342 342 ptr->nextBlock = lastMemBlockAllocated; 343 343 if ( ptr->nextBlock != NULL ) { 344 ptr->nextBlock->previousBlock = ptr;345 }344 ptr->nextBlock->previousBlock = ptr; 345 } 346 346 lastMemBlockAllocated = ptr; 347 347 348 348 pthread_mutex_unlock( &memBlockListMutex ); 349 349 350 350 // Did the user ask to be informed about this allocation? 351 351 if ( ptr->id == p_psMemAllocateID ) { 352 p_psMemAllocateID += memAllocateCallback( ptr );353 }354 352 p_psMemAllocateID += memAllocateCallback( ptr ); 353 } 354 355 355 // And return the user the memory that they allocated 356 356 return ptr + 1; // user memory … … 360 360 { 361 361 if ( vptr == NULL ) { 362 return p_psAlloc( size, file, lineno );363 } else {364 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1;365 bool isBlockLast = false;366 367 if ( checkMemBlock( ptr, __func__ ) != 0 ) {368 memProblemCallback( ptr, file, lineno );369 psAbort( file, "Realloc detected a memory corruption (id %ld @ %s:%d).",370 ptr->id, ptr->file, ptr->lineno );371 }372 373 pthread_mutex_lock( &memBlockListMutex );374 375 isBlockLast = ( ptr == lastMemBlockAllocated );376 377 ptr = ( psMemBlock* ) realloc( ptr, sizeof( psMemBlock ) + size + sizeof( void* ) );378 379 if ( ptr == NULL ) {380 psAbort( __func__, "Failed to reallocate %ld bytes at %s:%d",381 size, file, lineno );382 }383 384 ptr->userMemorySize = size;385 *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size ) = P_PS_MEMMAGIC;386 387 if ( isBlockLast ) {388 lastMemBlockAllocated = ptr;389 }390 391 // the block location may have changed, so fix the linked list addresses.392 if ( ptr->nextBlock != NULL ) {393 ptr->nextBlock->previousBlock = ptr;394 }395 if ( ptr->previousBlock != NULL ) {396 ptr->previousBlock->nextBlock = ptr;397 }398 399 pthread_mutex_unlock( &memBlockListMutex );400 401 // Did the user ask to be informed about this allocation?402 if ( ptr->id == p_psMemAllocateID ) {403 p_psMemAllocateID += memAllocateCallback( ptr );404 }405 406 return ptr + 1; // usr memory407 }362 return p_psAlloc( size, file, lineno ); 363 } else { 364 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1; 365 bool isBlockLast = false; 366 367 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 368 memProblemCallback( ptr, file, lineno ); 369 psAbort( file, "Realloc detected a memory corruption (id %ld @ %s:%d).", 370 ptr->id, ptr->file, ptr->lineno ); 371 } 372 373 pthread_mutex_lock( &memBlockListMutex ); 374 375 isBlockLast = ( ptr == lastMemBlockAllocated ); 376 377 ptr = ( psMemBlock* ) realloc( ptr, sizeof( psMemBlock ) + size + sizeof( void* ) ); 378 379 if ( ptr == NULL ) { 380 psAbort( __func__, "Failed to reallocate %ld bytes at %s:%d", 381 size, file, lineno ); 382 } 383 384 ptr->userMemorySize = size; 385 *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size ) = P_PS_MEMMAGIC; 386 387 if ( isBlockLast ) { 388 lastMemBlockAllocated = ptr; 389 } 390 391 // the block location may have changed, so fix the linked list addresses. 392 if ( ptr->nextBlock != NULL ) { 393 ptr->nextBlock->previousBlock = ptr; 394 } 395 if ( ptr->previousBlock != NULL ) { 396 ptr->previousBlock->nextBlock = ptr; 397 } 398 399 pthread_mutex_unlock( &memBlockListMutex ); 400 401 // Did the user ask to be informed about this allocation? 402 if ( ptr->id == p_psMemAllocateID ) { 403 p_psMemAllocateID += memAllocateCallback( ptr ); 404 } 405 406 return ptr + 1; // usr memory 407 } 408 408 } 409 409 … … 421 421 int j = 0; 422 422 psMemBlock* topBlock = lastMemBlockAllocated; 423 423 424 424 pthread_mutex_lock( &memBlockListMutex ); 425 425 426 426 for ( psMemBlock * iter = topBlock; iter != NULL; iter = iter->nextBlock ) { 427 if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) { 428 nleak++; 429 430 if ( fd != NULL ) { 431 if ( nleak == 1 ) { 432 fprintf( fd, " %20s:line ID\n", "file" ); 433 } 434 435 fprintf( fd, " %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id ); 436 } 427 if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) { 428 nleak++; 429 430 if ( fd != NULL ) { 431 if ( nleak == 1 ) { 432 fprintf( fd, " %20s:line ID\n", "file" ); 437 433 } 438 } 439 434 435 fprintf( fd, " %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id ); 436 } 437 } 438 } 439 440 440 pthread_mutex_unlock( &memBlockListMutex ); 441 441 442 442 if ( nleak == 0 || arr == NULL ) { 443 return nleak;444 }445 443 return nleak; 444 } 445 446 446 *arr = p_psAlloc( nleak * sizeof( psMemBlock ), __FILE__, __LINE__ ); 447 447 pthread_mutex_lock( &memBlockListMutex ); 448 448 449 449 for ( psMemBlock * iter = topBlock; iter != NULL; iter = iter->nextBlock ) { 450 if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) {451 ( *arr ) [ j++ ] = iter;452 if ( j == nleak ) { // found them all453 break;454 }455 }456 }457 450 if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) { 451 ( *arr ) [ j++ ] = iter; 452 if ( j == nleak ) { // found them all 453 break; 454 } 455 } 456 } 457 458 458 pthread_mutex_unlock( &memBlockListMutex ); 459 459 460 460 return nleak; 461 461 } … … 463 463 /* 464 464 * Reference counting APIs 465 */ 465 */ 466 466 // return refCounter 467 467 psReferenceCount psMemGetRefCounter( void *vptr ) … … 469 469 psMemBlock * ptr; 470 470 unsigned int refCount; 471 471 472 472 if ( vptr == NULL ) { 473 return 0;474 }475 473 return 0; 474 } 475 476 476 ptr = ( ( psMemBlock * ) vptr ) - 1; 477 477 478 478 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 479 memProblemCallback( ptr, __func__, __LINE__ );480 }481 479 memProblemCallback( ptr, __func__, __LINE__ ); 480 } 481 482 482 pthread_mutex_lock( &ptr->refCounterMutex ); 483 483 refCount = ptr->refCounter; 484 484 pthread_mutex_unlock( &ptr->refCounterMutex ); 485 485 486 486 return refCount; 487 487 } … … 490 490 { 491 491 psMemBlock * ptr; 492 492 493 493 if ( vptr == NULL ) { 494 return vptr;495 }496 494 return vptr; 495 } 496 497 497 ptr = ( ( psMemBlock * ) vptr ) - 1; 498 498 499 499 if ( checkMemBlock( ptr, __func__ ) ) { 500 memProblemCallback( ptr, file, lineno );501 }502 500 memProblemCallback( ptr, file, lineno ); 501 } 502 503 503 pthread_mutex_lock( &ptr->refCounterMutex ); 504 504 ptr->refCounter++; 505 505 pthread_mutex_unlock( &ptr->refCounterMutex ); 506 506 507 507 return vptr; 508 508 } … … 512 512 { 513 513 if ( vptr == NULL ) { 514 return NULL;515 }516 514 return NULL; 515 } 516 517 517 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1; 518 518 519 519 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 520 memProblemCallback( ptr, file, lineno );521 return NULL;522 }523 520 memProblemCallback( ptr, file, lineno ); 521 return NULL; 522 } 523 524 524 pthread_mutex_lock( &ptr->refCounterMutex ); 525 525 526 526 if ( ptr->refCounter > 1 ) { 527 /// XXX - Probably should have another mutex here. 528 ptr->refCounter--; // multiple references, just decrement the count. 529 pthread_mutex_unlock( &ptr->refCounterMutex ); 530 527 /// XXX - Probably should have another mutex here. 528 ptr->refCounter--; // multiple references, just decrement the count. 529 pthread_mutex_unlock( &ptr->refCounterMutex ); 530 531 } else { 532 pthread_mutex_unlock( &ptr->refCounterMutex ); 533 534 // Did the user ask to be informed about this deallocation? 535 if ( ptr->id == p_psMemFreeID ) { 536 p_psMemFreeID += memFreeCallback( ptr ); 537 } 538 539 if ( ptr->freeFcn != NULL ) { 540 ptr->freeFcn( vptr ); 541 } 542 543 pthread_mutex_lock( &memBlockListMutex ); 544 545 // cut the memBlock out of the memBlock list 546 if ( ptr->nextBlock != NULL ) { 547 ptr->nextBlock->previousBlock = ptr->previousBlock; 548 } 549 if ( ptr->previousBlock != NULL ) { 550 ptr->previousBlock->nextBlock = ptr->nextBlock; 551 } 552 if ( lastMemBlockAllocated == ptr ) { 553 lastMemBlockAllocated = ptr->nextBlock; 554 } 555 556 pthread_mutex_unlock( &memBlockListMutex ); 557 558 559 // do we need to recycle? 560 if ( ptr->userMemorySize < P_PS_LARGE_BLOCK_SIZE ) { 561 562 int level = 1; 563 while ( ptr->userMemorySize >= recycleBinSize[ level ] ) { 564 level++; 565 } 566 level--; 567 568 ptr->refCounter = 0; 569 ptr->previousBlock = NULL; 570 571 pthread_mutex_lock( &recycleMemBlockListMutex ); 572 ptr->nextBlock = recycleMemBlockList[ level ]; 573 if ( recycleMemBlockList[ level ] != NULL ) { 574 recycleMemBlockList[ level ] ->previousBlock = ptr; 575 } 576 recycleMemBlockList[ level ] = ptr; 577 pthread_mutex_unlock( &recycleMemBlockListMutex ); 578 531 579 } else { 532 pthread_mutex_unlock( &ptr->refCounterMutex ); 533 534 // Did the user ask to be informed about this deallocation? 535 if ( ptr->id == p_psMemFreeID ) { 536 p_psMemFreeID += memFreeCallback( ptr ); 537 } 538 539 if ( ptr->freeFcn != NULL ) { 540 ptr->freeFcn( vptr ); 541 } 542 543 pthread_mutex_lock( &memBlockListMutex ); 544 545 // cut the memBlock out of the memBlock list 546 if ( ptr->nextBlock != NULL ) { 547 ptr->nextBlock->previousBlock = ptr->previousBlock; 548 } 549 if ( ptr->previousBlock != NULL ) { 550 ptr->previousBlock->nextBlock = ptr->nextBlock; 551 } 552 if ( lastMemBlockAllocated == ptr ) { 553 lastMemBlockAllocated = ptr->nextBlock; 554 } 555 556 pthread_mutex_unlock( &memBlockListMutex ); 557 558 559 // do we need to recycle? 560 if ( ptr->userMemorySize < P_PS_LARGE_BLOCK_SIZE ) { 561 562 int level = 1; 563 while ( ptr->userMemorySize >= recycleBinSize[ level ] ) { 564 level++; 565 } 566 level--; 567 568 ptr->refCounter = 0; 569 ptr->previousBlock = NULL; 570 571 pthread_mutex_lock( &recycleMemBlockListMutex ); 572 ptr->nextBlock = recycleMemBlockList[ level ]; 573 if ( recycleMemBlockList[ level ] != NULL ) { 574 recycleMemBlockList[ level ] ->previousBlock = ptr; 575 } 576 recycleMemBlockList[ level ] = ptr; 577 pthread_mutex_unlock( &recycleMemBlockListMutex ); 578 579 } else { 580 // memory is larger than I want to recycle. 581 #ifdef PS_MEM_DEBUG 582 ( void ) p_psRealloc( vptr, 0, file, lineno ); 583 ptr->previousBlock = NULL; 584 ptr->nextBlock = deadBlockList; 585 if ( deadBlockList != NULL ) { 586 deadBlockList->previous = ptr; 587 } 588 deadBlockList = ptr; 589 #else 590 591 pthread_mutex_destroy( &ptr->refCounterMutex ); 592 free( ptr ); 593 #endif 594 595 } 596 597 vptr = NULL; // since we freed it, make sure we return NULL. 598 } 599 580 // memory is larger than I want to recycle. 581 #ifdef PS_MEM_DEBUG 582 ( void ) p_psRealloc( vptr, 0, file, lineno ); 583 ptr->previousBlock = NULL; 584 ptr->nextBlock = deadBlockList; 585 if ( deadBlockList != NULL ) { 586 deadBlockList->previous = ptr; 587 } 588 deadBlockList = ptr; 589 #else 590 591 pthread_mutex_destroy( &ptr->refCounterMutex ); 592 free( ptr ); 593 #endif 594 595 } 596 597 vptr = NULL; // since we freed it, make sure we return NULL. 598 } 599 600 600 return vptr; 601 601 } … … 604 604 { 605 605 if ( vptr == NULL ) { 606 return ;607 }608 606 return ; 607 } 608 609 609 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1; 610 610 611 611 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 612 memProblemCallback( ptr, __func__, __LINE__ );613 }614 612 memProblemCallback( ptr, __func__, __LINE__ ); 613 } 614 615 615 ptr->freeFcn = freeFcn; 616 616 617 617 } 618 618 psFreeFcn p_psMemGetDeallocator( void* vptr ) 619 619 { 620 620 if ( vptr == NULL ) { 621 return NULL;622 }623 621 return NULL; 622 } 623 624 624 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1; 625 625 626 626 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 627 memProblemCallback( ptr, __func__, __LINE__ );628 }629 627 memProblemCallback( ptr, __func__, __LINE__ ); 628 } 629 630 630 return ptr->freeFcn; 631 631 } -
trunk/psLib/src/sysUtils/psMemory.h
r1233 r1385 14 14 * @ingroup MemoryManagement 15 15 * 16 * @version $Revision: 1.2 1$ $Name: not supported by cvs2svn $17 * @date $Date: 2004-0 7-15 23:52:34$16 * @version $Revision: 1.22 $ $Name: not supported by cvs2svn $ 17 * @date $Date: 2004-08-04 23:37:39 $ 18 18 * 19 19 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sysUtils/psString.c
r635 r1385 8 8 * @author Eric Van Alst, MHPCC 9 9 * 10 * @version $Revision: 1. 5$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-0 5-10 23:37:36$10 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-04 23:37:39 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sysUtils/psTrace.c
r1137 r1385 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1.1 1$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-0 6-30 01:09:12$11 * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sysUtils/psType.h
r1360 r1385 10 10 * @author Ross Harman, MHPCC 11 11 * 12 * @version $Revision: 1.1 5$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 7-31 02:28:10$12 * @version $Revision: 1.16 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 142 142 */ 143 143 typedef struct 144 {145 psElemType type; ///< Primitive type.146 psDimen dimen; ///< Dimensionality.147 }144 { 145 psElemType type; ///< Primitive type. 146 psDimen dimen; ///< Dimensionality. 147 } 148 148 psType; 149 149
Note:
See TracChangeset
for help on using the changeset viewer.
