Exemplo n.º 1
0
/**
 * 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;
            }
        }
    }
}
Exemplo n.º 2
0
/**
 * 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;
}