/** * Free unused memory. */ void BITSET_Trim(BitSet * bs) { if (bs->alloc > bs->inuse) { if (bs->inuse == 0) { ASSERT(bs->storage.units); MEM_Free(bs->storage.units); bs->storage.units = NULL; bs->alloc = 0; } else { BitUnit * savebuf = bs->storage.units; size_t size = sizeof(BitUnit) * bs->inuse; #ifdef NO_REALLOC bs->storage.units = (BitUnit*)MEM_Alloc(size); if (bs->storage.units) { memcpy(bs->storage.units, savebuf, size); MEM_Free(bs->storage.units); } #else bs->storage.units = (BitUnit*)MEM_Realloc(savebuf, size); #endif /* NO_REALLOC */ if (bs->storage.units) { bs->alloc = bs->inuse; } else { bs->storage.units = savebuf; } } } }
/** * Returns available RWEntry for the calling thread. Reallocates array * of thread entries if necessary. Obviously, this function must be called * under synchronization. Returns NULL only if we run out of thread entries * and memory allocation fails. */ STATIC RWEntry * RWLOCK_GetEntry(RWLock * lock) { int i; ThrID self = THREAD_Self(); RWEntry * empty = NULL; /* vacant empty entry */ /* * try to find existing entry for this thread. At the same time * pick up the first available empty slot. */ for (i=0; i<lock->entriesInUse; i++) { RWEntry * entry = GET_ENTRY(lock,i); if (entry->id == self) { return entry; } else if (!empty && !entry->id) { empty = entry; } } /* * we didn't find existing slot for the calling thread. * We have to find an empty slot. */ if (!empty) { for (; i<lock->numEntries; i++) { RWEntry * entry = GET_ENTRY(lock,i); if (!entry->id) { empty = entry; break; } } /* * looks like we are out of luck. We need to reallocate the array * of thread entries. */ if (!empty) { int count = lock->numEntries + STATIC_ENTRIES; size_t size = count * sizeof(RWEntry); RWEntry * newEntries = (RWEntry*) MEM_Realloc(lock->moreEntries, size); if (!newEntries) { return NULL; } lock->moreEntries = newEntries; lock->numEntries = count; empty = lock->moreEntries + i - STATIC_ENTRIES; memset(empty, 0, sizeof(RWEntry) * STATIC_ENTRIES); } lock->entriesInUse = i + 1; } lock->entriesActive++; /* * initialize the empty entry. */ empty->id = self; empty->read = empty->write = 0L; return empty; }