#ifndef _SYS_BITMAP_H
#define _SYS_BITMAP_H
#pragma ident "@(#)bitmap.h 1.28 05/09/28 SMI"
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(__APPLE__)
#include <sys/feature_tests.h>
#else
#ifdef KERNEL
#ifndef _KERNEL
#define _KERNEL
#endif
#endif
#endif
#if defined(__GNUC__) && defined(_ASM_INLINES) && \
(defined(__i386) || defined(__amd64))
#include <asm/bitmap.h>
#endif
#ifdef _LP64
#define BT_ULSHIFT 6
#define BT_ULSHIFT32 5
#else
#define BT_ULSHIFT 5
#endif
#define BT_NBIPUL (1 << BT_ULSHIFT)
#define BT_ULMASK (BT_NBIPUL - 1)
#ifdef _LP64
#define BT_NBIPUL32 (1 << BT_ULSHIFT32)
#define BT_ULMASK32 (BT_NBIPUL32 - 1)
#define BT_ULMAXMASK 0xffffffffffffffff
#else
#define BT_ULMAXMASK 0xffffffff
#endif
#define BT_WIM(bitmap, bitindex) \
((bitmap)[(bitindex) >> BT_ULSHIFT])
#define BT_BIW(bitindex) \
(1UL << ((bitindex) & BT_ULMASK))
#ifdef _LP64
#define BT_WIM32(bitmap, bitindex) \
((bitmap)[(bitindex) >> BT_ULSHIFT32])
#define BT_BIW32(bitindex) \
(1UL << ((bitindex) & BT_ULMASK32))
#endif
#define BT_BITOUL(nbits) \
(((nbits) + BT_NBIPUL - 1l) / BT_NBIPUL)
#define BT_SIZEOFMAP(nbits) \
(BT_BITOUL(nbits) * sizeof (ulong_t))
#define BT_TEST(bitmap, bitindex) \
((BT_WIM((bitmap), (bitindex)) & BT_BIW(bitindex)) ? 1 : 0)
#define BT_SET(bitmap, bitindex) \
{ BT_WIM((bitmap), (bitindex)) |= BT_BIW(bitindex); }
#define BT_CLEAR(bitmap, bitindex) \
{ BT_WIM((bitmap), (bitindex)) &= ~BT_BIW(bitindex); }
#ifdef _LP64
#define BT_BITOUL32(nbits) \
(((nbits) + BT_NBIPUL32 - 1l) / BT_NBIPUL32)
#define BT_SIZEOFMAP32(nbits) \
(BT_BITOUL32(nbits) * sizeof (uint_t))
#define BT_TEST32(bitmap, bitindex) \
((BT_WIM32((bitmap), (bitindex)) & BT_BIW32(bitindex)) ? 1 : 0)
#define BT_SET32(bitmap, bitindex) \
{ BT_WIM32((bitmap), (bitindex)) |= BT_BIW32(bitindex); }
#define BT_CLEAR32(bitmap, bitindex) \
{ BT_WIM32((bitmap), (bitindex)) &= ~BT_BIW32(bitindex); }
#endif
#if defined(_KERNEL) && !defined(_ASM)
#include <sys/atomic.h>
extern index_t bt_availbit(ulong_t *bitmap, size_t nbits);
extern int bt_gethighbit(ulong_t *mapp, int wx);
extern int bt_range(ulong_t *bitmap, size_t *pos1, size_t *pos2,
size_t end_pos);
extern int highbit(ulong_t);
extern int lowbit(ulong_t);
extern int bt_getlowbit(ulong_t *bitmap, size_t start, size_t stop);
extern void bt_copy(ulong_t *, ulong_t *, ulong_t);
extern int odd_parity(ulong_t);
#define BT_ATOMIC_SET(bitmap, bitindex) \
{ atomic_or_long(&(BT_WIM(bitmap, bitindex)), BT_BIW(bitindex)); }
#define BT_ATOMIC_CLEAR(bitmap, bitindex) \
{ atomic_and_long(&(BT_WIM(bitmap, bitindex)), ~BT_BIW(bitindex)); }
#define BT_ATOMIC_SET_EXCL(bitmap, bitindex, result) \
{ result = atomic_set_long_excl(&(BT_WIM(bitmap, bitindex)), \
(bitindex) % BT_NBIPUL); }
#define BT_ATOMIC_CLEAR_EXCL(bitmap, bitindex, result) \
{ result = atomic_clear_long_excl(&(BT_WIM(bitmap, bitindex)), \
(bitindex) % BT_NBIPUL); }
#define BITX(u, h, l) (((u) >> (l)) & ((1LU << ((h) - (l) + 1LU)) - 1LU))
#endif
#ifdef __cplusplus
}
#endif
#endif