103 lines
2.4 KiB
C
103 lines
2.4 KiB
C
/*
|
|
* Copyright 2007 The Android Open Source Project
|
|
*
|
|
* Simple bit vector.
|
|
*/
|
|
#include "Common.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
#define kBitVectorGrowth 4 /* increase by 4 uint32_t when limit hit */
|
|
|
|
|
|
/*
|
|
* Allocate a bit vector with enough space to hold at least the specified
|
|
* number of bits.
|
|
*/
|
|
BitVector* wsAllocBitVector(int startBits, int isExpandable)
|
|
{
|
|
BitVector* bv;
|
|
int count;
|
|
|
|
assert(sizeof(bv->storage[0]) == 4); /* assuming 32-bit units */
|
|
assert(startBits > 0);
|
|
|
|
bv = (BitVector*) malloc(sizeof(BitVector));
|
|
|
|
count = (startBits + 31) >> 5;
|
|
|
|
bv->storageSize = count;
|
|
bv->isExpandable = isExpandable;
|
|
bv->storage = (uint32_t*) malloc(count * sizeof(uint32_t));
|
|
memset(bv->storage, 0xff, count * sizeof(uint32_t));
|
|
return bv;
|
|
}
|
|
|
|
/*
|
|
* Free a BitVector.
|
|
*/
|
|
void wsFreeBitVector(BitVector* pBits)
|
|
{
|
|
if (pBits == NULL)
|
|
return;
|
|
|
|
free(pBits->storage);
|
|
free(pBits);
|
|
}
|
|
|
|
/*
|
|
* "Allocate" the first-available bit in the bitmap.
|
|
*
|
|
* This is not synchronized. The caller is expected to hold some sort of
|
|
* lock that prevents multiple threads from executing simultaneously in
|
|
* dvmAllocBit/dvmFreeBit.
|
|
*
|
|
* The bitmap indicates which resources are free, so we use '1' to indicate
|
|
* available and '0' to indicate allocated.
|
|
*/
|
|
int wsAllocBit(BitVector* pBits)
|
|
{
|
|
int word, bit;
|
|
|
|
retry:
|
|
for (word = 0; word < pBits->storageSize; word++) {
|
|
if (pBits->storage[word] != 0) {
|
|
/*
|
|
* There are unallocated bits in this word. Return the first.
|
|
*/
|
|
bit = ffs(pBits->storage[word]) -1;
|
|
assert(bit >= 0 && bit < 32);
|
|
pBits->storage[word] &= ~(1 << bit);
|
|
return (word << 5) | bit;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Ran out of space, allocate more if we're allowed to.
|
|
*/
|
|
if (!pBits->isExpandable)
|
|
return -1;
|
|
|
|
pBits->storage = realloc(pBits->storage,
|
|
(pBits->storageSize + kBitVectorGrowth) * sizeof(uint32_t));
|
|
memset(&pBits->storage[pBits->storageSize], 0xff,
|
|
kBitVectorGrowth * sizeof(uint32_t));
|
|
pBits->storageSize += kBitVectorGrowth;
|
|
goto retry;
|
|
}
|
|
|
|
/*
|
|
* Mark the specified bit as "free".
|
|
*/
|
|
void wsFreeBit(BitVector* pBits, int num)
|
|
{
|
|
assert(num >= 0 &&
|
|
num < (int) pBits->storageSize * (int)sizeof(uint32_t) * 8);
|
|
|
|
pBits->storage[num >> 5] |= 1 << (num & 0x1f);
|
|
}
|
|
|