| 1379 | |
| 1380 | #if !defined(TORQUE_DISABLE_MEMORY_MANAGER) |
| 1381 | static void free(void* mem, bool array) |
| 1382 | { |
| 1383 | // validate(); |
| 1384 | |
| 1385 | if (!mem) |
| 1386 | return; |
| 1387 | |
| 1388 | #ifdef TORQUE_MULTITHREAD |
| 1389 | if(!gMemMutex) |
| 1390 | gMemMutex = Mutex::createMutex(); |
| 1391 | |
| 1392 | if( mem != gMemMutex ) |
| 1393 | Mutex::lockMutex(gMemMutex); |
| 1394 | else |
| 1395 | gMemMutex = NULL; |
| 1396 | #endif |
| 1397 | |
| 1398 | PROFILE_START(MemoryFree); |
| 1399 | AllocatedHeader *hdr = ((AllocatedHeader *)mem) - 1; |
| 1400 | |
| 1401 | AssertFatal(hdr->flags & Allocated, avar("Not an allocated block!")); |
| 1402 | AssertFatal(((bool)((hdr->flags & Array)==Array))==array, avar("Array alloc mismatch. ")); |
| 1403 | |
| 1404 | gBlocksAllocated --; |
| 1405 | #ifdef TORQUE_DEBUG_GUARD |
| 1406 | gBytesAllocated -= hdr->realSize; |
| 1407 | if (gEnableLogging) |
| 1408 | logFree(hdr); |
| 1409 | #endif |
| 1410 | |
| 1411 | hdr->flags = 0; |
| 1412 | |
| 1413 | // fill the block with the fill value |
| 1414 | |
| 1415 | #ifdef TORQUE_DEBUG |
| 1416 | #ifndef TORQUE_ENABLE_PROFILE_PATH |
| 1417 | PROFILE_START(stompMem2); |
| 1418 | #endif |
| 1419 | dMemset(mem, 0xCE, hdr->size); |
| 1420 | #ifndef TORQUE_ENABLE_PROFILE_PATH |
| 1421 | PROFILE_END(); |
| 1422 | #endif |
| 1423 | #endif |
| 1424 | |
| 1425 | // see if we can merge hdr with the block after it. |
| 1426 | |
| 1427 | Header* next = hdr->next; |
| 1428 | if (next && next->flags == 0) |
| 1429 | { |
| 1430 | treeRemove((FreeHeader *) next); |
| 1431 | hdr->size += next->size + sizeof(Header); |
| 1432 | hdr->next = next->next; |
| 1433 | if(next->next) |
| 1434 | next->next->prev = (Header *) hdr; |
| 1435 | } |
| 1436 | |
| 1437 | // see if we can merge hdr with the block before it. |
| 1438 | Header* prev = hdr->prev; |