Files
Arquivotheca.Solaris-2.5/uts/common/os/bitmap.c
seta75D 7c4988eac0 Init
2021-10-11 19:38:01 -03:00

191 lines
3.5 KiB
C
Executable File

/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ident "@(#)bitmap.c 1.13 94/09/16 SMI" /* from SVR4.0 1.4 */
/*
* Operations on bitmaps of arbitrary size
* A bitmap is a vector of 1 or more ulongs.
* The user of the package is responsible for range checks and keeping
* track of sizes.
*/
#include <sys/types.h>
#include <sys/bitmap.h>
int highbit(ulong i); /* find highest bit set */
/*
* Return index of first available bit in denoted bitmap, or -1 for
* failure. Size is the cardinality of the bitmap; that is, the
* number of bits.
* No side-effects. In particular, does not update bitmap.
* Caller is responsible for range checks.
*/
index_t
bt_availbit(bitmap, nbits)
register ulong *bitmap;
size_t nbits;
{
register index_t maxword; /* index of last in map */
register index_t wx; /* word index in map */
/*
* Look for a word with a bit off.
* Subtract one from nbits because we're converting it to a
* a range of indices.
*/
nbits -= 1;
maxword = nbits >> BT_ULSHIFT;
for (wx = 0; wx <= maxword; wx++) {
if (bitmap[wx] != ~0) {
break;
}
}
if (wx <= maxword) {
/*
* Found a word with a bit off. Now find the bit in the word.
*/
register index_t bx; /* bit index in word */
register index_t maxbit; /* last bit to look at */
register ulong word;
register ulong bit;
maxbit = wx == maxword ? nbits & BT_ULMASK : BT_NBIPUL - 1;
word = bitmap[wx];
bit = 1;
for (bx = 0; bx <= maxbit; bx++, bit <<= 1) {
if (!(word & bit)) {
return (wx << BT_ULSHIFT | bx);
}
}
}
return (-1);
}
/*
* Find highest order bit that is on, and is within or below
* the word specified by wx.
*/
void
bt_gethighbit(mapp, wx, bitposp)
register ulong *mapp;
register int wx;
int *bitposp;
{
register ulong word;
while ((word = mapp[wx]) == 0) {
wx--;
if (wx < 0) {
*bitposp = -1;
return;
}
}
*bitposp = wx << BT_ULSHIFT | (highbit(word) - 1);
}
/*
* Search the bitmap for a consecutive pattern of 1's.
* Search starts at position pos1.
* Returns 1 on success and 0 on failure.
* Side effects.
* Returns indices to the first bit (pos1)
* and the last bit (pos2) in the pattern.
*/
int
bt_range(bitmap, pos1, pos2, nbits)
register ulong *bitmap;
register size_t *pos1;
register size_t *pos2;
size_t nbits;
{
register size_t inx;
for (inx = *pos1; inx < nbits; inx++)
if (BT_TEST(bitmap, inx))
break;
if (inx == nbits)
return (0);
*pos1 = inx;
for (; inx < nbits; inx++)
if (!BT_TEST(bitmap, inx))
break;
*pos2 = inx - 1;
return (1);
}
/*
* Find highest one bit set.
* Returns bit number + 1 of highest bit that is set, otherwise returns 0.
* High order bit is 31.
*/
int
highbit(ulong i)
{
register int h = 1;
if (i == 0)
return (i);
if (i & 0xffff0000) {
h += 16; i >>= 16;
}
if (i & 0xff00) {
h += 8; i >>= 8;
}
if (i & 0xf0) {
h += 4; i >>= 4;
}
if (i & 0xc) {
h += 2; i >>= 2;
}
if (i & 0x2) {
h += 1;
}
return (h);
}
/*
* Find lowest one bit set.
* Returns bit number + 1 of lowest bit that is set, otherwise returns 0.
* Low order bit is 0.
*/
int
lowbit(ulong i)
{
register int h = 1;
if (i == 0)
return (i);
if (!(i & 0xffff)) {
h += 16; i >>= 16;
}
if (!(i & 0xff)) {
h += 8; i >>= 8;
}
if (!(i & 0xf)) {
h += 4; i >>= 4;
}
if (!(i & 0x3)) {
h += 2; i >>= 2;
}
if (!(i & 0x1)) {
h += 1;
}
return (h);
}