wanpipe/api/legacy/x25/pthread/bitmap.c

136 lines
3.9 KiB
C

// bitmap.c
// Routines to manage a bitmap -- an array of bits each of which
// can be either on or off. Represented as an array of integers.
#include "bitmap.h"
//----------------------------------------------------------------------
// BitMap::BitMap
// Initialize a bitmap with "nitems" bits, so that every bit is clear.
// it can be added somewhere on a list.
// "nitems" is the number of bits in the bitmap.
//----------------------------------------------------------------------
BitMap::BitMap(int nitems)
{
numBits = nitems;
numWords = divRoundUp(numBits, BitsInWord);
map = new unsigned int[numWords];
if (pthread_mutex_init(&mut,NULL) != 0)
perror("BitMap:BitMap");
for (int i = 1; i <= numBits; i++)
Clear(i);
Mark(numBits);
}
//----------------------------------------------------------------------
// BitMap::~BitMap
// De-allocate a bitmap.
//----------------------------------------------------------------------
BitMap::~BitMap()
{
delete map;
}
//----------------------------------------------------------------------
// BitMap::Set
// Set the "nth" bit in a bitmap.
// Makes this entry Unavailable
// "which" is the number of the bit to be set.
//----------------------------------------------------------------------
void BitMap::Mark(int which)
{
assert(which >= 0 && which <= numBits);
map[which / BitsInWord] |= 1 << (which % BitsInWord);
}
//----------------------------------------------------------------------
// BitMap::Clear
// Clear the "nth" bit in a bitmap. (in other words, it's made available)
// "which" is the number of the bit to be cleared.
//----------------------------------------------------------------------
void BitMap::Clear(int which)
{
assert(which > 0 && which <= numBits);
map[which / BitsInWord] &= ~(1 << (which % BitsInWord));
}
//----------------------------------------------------------------------
// BitMap::Test
// Return TRUE if the "nth" bit is set.
// "which" is the number of the bit to be tested.
//----------------------------------------------------------------------
bool BitMap::Test(int which)
{
assert(which >= 0 && which <= numBits);
if (map[which / BitsInWord] & (1 << (which % BitsInWord)))
return TRUE;
else
return FALSE;
}
//----------------------------------------------------------------------
// BitMap::Find
// Return the number of the first bit which is clear.
// As a side effect, set the bit (mark it as in use).
// (In other words, find and allocate a bit.)
// If no bits are clear, return -1.
//----------------------------------------------------------------------
int BitMap::Find()
{
pthread_mutex_lock(&mut); // provides mutual exclusion
for (int i = 1; i <= numBits; i++)
{
if (!Test(i))
{
Mark(i); // found it,so mark it as busy
pthread_mutex_unlock(&mut);
return i;
}
}
pthread_mutex_unlock(&mut);
return -1; // did not find an spot available, return -1
} // end of the Find method
//----------------------------------------------------------------------
// BitMap::NumClear
// Return the number of clear bits in the bitmap.
// (In other words, how many bits are unallocated?)
//----------------------------------------------------------------------
int BitMap::NumClear()
{
int count=0;
for (int i=1; i <= numBits; i++)
if (!Test(i))
count++;
return count;
}
//----------------------------------------------------------------------
// BitMap::Print
// Print the contents of the bitmap, for debugging.
//
// Could be done in a number of ways, but we just print the #'s of
// all the bits that are set in the bitmap.
//----------------------------------------------------------------------
void BitMap::Print()
{
printf("Bitmap set:\n");
for (int i = 1; i <= numBits; i++)
if (Test(i))
{
printf("%d, ", i);
if (i%25 == 0)
printf("\n");
}
printf("\n");
}