/* * 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); }