blob: aaa14085e976e1a2f71703656b81744115d6e56b [file] [log] [blame]
The Android Open Source Project52d4c302009-03-03 19:29:09 -08001/*
2 * Copyright 2007 The Android Open Source Project
3 *
4 * Simple bit vector.
5 */
6#include "Common.h"
7
8#include <stdlib.h>
9#include <stdint.h>
10#include <string.h>
11#include <assert.h>
12
13#define kBitVectorGrowth 4 /* increase by 4 uint32_t when limit hit */
14
15
16/*
17 * Allocate a bit vector with enough space to hold at least the specified
18 * number of bits.
19 */
20BitVector* wsAllocBitVector(int startBits, int isExpandable)
21{
22 BitVector* bv;
23 int count;
24
25 assert(sizeof(bv->storage[0]) == 4); /* assuming 32-bit units */
26 assert(startBits > 0);
27
28 bv = (BitVector*) malloc(sizeof(BitVector));
29
30 count = (startBits + 31) >> 5;
31
32 bv->storageSize = count;
33 bv->isExpandable = isExpandable;
34 bv->storage = (uint32_t*) malloc(count * sizeof(uint32_t));
35 memset(bv->storage, 0xff, count * sizeof(uint32_t));
36 return bv;
37}
38
39/*
40 * Free a BitVector.
41 */
42void wsFreeBitVector(BitVector* pBits)
43{
44 if (pBits == NULL)
45 return;
46
47 free(pBits->storage);
48 free(pBits);
49}
50
51/*
52 * "Allocate" the first-available bit in the bitmap.
53 *
54 * This is not synchronized. The caller is expected to hold some sort of
55 * lock that prevents multiple threads from executing simultaneously in
56 * dvmAllocBit/dvmFreeBit.
57 *
58 * The bitmap indicates which resources are free, so we use '1' to indicate
59 * available and '0' to indicate allocated.
60 */
61int wsAllocBit(BitVector* pBits)
62{
63 int word, bit;
64
65retry:
66 for (word = 0; word < pBits->storageSize; word++) {
67 if (pBits->storage[word] != 0) {
68 /*
69 * There are unallocated bits in this word. Return the first.
70 */
71 bit = ffs(pBits->storage[word]) -1;
72 assert(bit >= 0 && bit < 32);
73 pBits->storage[word] &= ~(1 << bit);
74 return (word << 5) | bit;
75 }
76 }
77
78 /*
79 * Ran out of space, allocate more if we're allowed to.
80 */
81 if (!pBits->isExpandable)
82 return -1;
83
84 pBits->storage = realloc(pBits->storage,
85 (pBits->storageSize + kBitVectorGrowth) * sizeof(uint32_t));
86 memset(&pBits->storage[pBits->storageSize], 0xff,
87 kBitVectorGrowth * sizeof(uint32_t));
88 pBits->storageSize += kBitVectorGrowth;
89 goto retry;
90}
91
92/*
93 * Mark the specified bit as "free".
94 */
95void wsFreeBit(BitVector* pBits, int num)
96{
97 assert(num >= 0 &&
98 num < (int) pBits->storageSize * (int)sizeof(uint32_t) * 8);
99
100 pBits->storage[num >> 5] |= 1 << (num & 0x1f);
101}
102