xref: /onnv-gate/usr/src/uts/common/sys/bitmap.h (revision 2712:f74a135872bc)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5713Swesolows  * Common Development and Distribution License (the "License").
6713Swesolows  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21713Swesolows 
220Sstevel@tonic-gate /*
23*2712Snn35248  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
280Sstevel@tonic-gate /*	  All Rights Reserved  	*/
290Sstevel@tonic-gate 
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #ifndef _SYS_BITMAP_H
320Sstevel@tonic-gate #define	_SYS_BITMAP_H
330Sstevel@tonic-gate 
34713Swesolows #pragma ident	"%Z%%M%	%I%	%E% SMI"
350Sstevel@tonic-gate 
360Sstevel@tonic-gate #ifdef	__cplusplus
370Sstevel@tonic-gate extern "C" {
380Sstevel@tonic-gate #endif
390Sstevel@tonic-gate 
400Sstevel@tonic-gate #include <sys/feature_tests.h>
41713Swesolows #if defined(__GNUC__) && defined(_ASM_INLINES) && \
42713Swesolows 	(defined(__i386) || defined(__amd64))
430Sstevel@tonic-gate #include <asm/bitmap.h>
440Sstevel@tonic-gate #endif
450Sstevel@tonic-gate 
460Sstevel@tonic-gate /*
470Sstevel@tonic-gate  * Operations on bitmaps of arbitrary size
480Sstevel@tonic-gate  * A bitmap is a vector of 1 or more ulong_t's.
490Sstevel@tonic-gate  * The user of the package is responsible for range checks and keeping
500Sstevel@tonic-gate  * track of sizes.
510Sstevel@tonic-gate  */
520Sstevel@tonic-gate 
530Sstevel@tonic-gate #ifdef _LP64
540Sstevel@tonic-gate #define	BT_ULSHIFT	6 /* log base 2 of BT_NBIPUL, to extract word index */
550Sstevel@tonic-gate #define	BT_ULSHIFT32	5 /* log base 2 of BT_NBIPUL, to extract word index */
560Sstevel@tonic-gate #else
570Sstevel@tonic-gate #define	BT_ULSHIFT	5 /* log base 2 of BT_NBIPUL, to extract word index */
580Sstevel@tonic-gate #endif
590Sstevel@tonic-gate 
600Sstevel@tonic-gate #define	BT_NBIPUL	(1 << BT_ULSHIFT)	/* n bits per ulong_t */
610Sstevel@tonic-gate #define	BT_ULMASK	(BT_NBIPUL - 1)		/* to extract bit index */
620Sstevel@tonic-gate 
630Sstevel@tonic-gate #ifdef _LP64
640Sstevel@tonic-gate #define	BT_NBIPUL32	(1 << BT_ULSHIFT32)	/* n bits per ulong_t */
650Sstevel@tonic-gate #define	BT_ULMASK32	(BT_NBIPUL32 - 1)	/* to extract bit index */
660Sstevel@tonic-gate #define	BT_ULMAXMASK	0xffffffffffffffff	/* used by bt_getlowbit */
670Sstevel@tonic-gate #else
680Sstevel@tonic-gate #define	BT_ULMAXMASK	0xffffffff
690Sstevel@tonic-gate #endif
700Sstevel@tonic-gate 
710Sstevel@tonic-gate /*
720Sstevel@tonic-gate  * bitmap is a ulong_t *, bitindex an index_t
730Sstevel@tonic-gate  *
740Sstevel@tonic-gate  * The macros BT_WIM and BT_BIW internal; there is no need
750Sstevel@tonic-gate  * for users of this package to use them.
760Sstevel@tonic-gate  */
770Sstevel@tonic-gate 
780Sstevel@tonic-gate /*
790Sstevel@tonic-gate  * word in map
800Sstevel@tonic-gate  */
810Sstevel@tonic-gate #define	BT_WIM(bitmap, bitindex) \
820Sstevel@tonic-gate 	((bitmap)[(bitindex) >> BT_ULSHIFT])
830Sstevel@tonic-gate /*
840Sstevel@tonic-gate  * bit in word
850Sstevel@tonic-gate  */
860Sstevel@tonic-gate #define	BT_BIW(bitindex) \
870Sstevel@tonic-gate 	(1UL << ((bitindex) & BT_ULMASK))
880Sstevel@tonic-gate 
890Sstevel@tonic-gate #ifdef _LP64
900Sstevel@tonic-gate #define	BT_WIM32(bitmap, bitindex) \
910Sstevel@tonic-gate 	((bitmap)[(bitindex) >> BT_ULSHIFT32])
920Sstevel@tonic-gate 
930Sstevel@tonic-gate #define	BT_BIW32(bitindex) \
940Sstevel@tonic-gate 	(1UL << ((bitindex) & BT_ULMASK32))
950Sstevel@tonic-gate #endif
960Sstevel@tonic-gate 
970Sstevel@tonic-gate /*
980Sstevel@tonic-gate  * These are public macros
990Sstevel@tonic-gate  *
1000Sstevel@tonic-gate  * BT_BITOUL == n bits to n ulong_t's
1010Sstevel@tonic-gate  */
1020Sstevel@tonic-gate #define	BT_BITOUL(nbits) \
1030Sstevel@tonic-gate 	(((nbits) + BT_NBIPUL - 1l) / BT_NBIPUL)
1040Sstevel@tonic-gate #define	BT_SIZEOFMAP(nbits) \
1050Sstevel@tonic-gate 	(BT_BITOUL(nbits) * sizeof (ulong_t))
1060Sstevel@tonic-gate #define	BT_TEST(bitmap, bitindex) \
1070Sstevel@tonic-gate 	((BT_WIM((bitmap), (bitindex)) & BT_BIW(bitindex)) ? 1 : 0)
1080Sstevel@tonic-gate #define	BT_SET(bitmap, bitindex) \
1090Sstevel@tonic-gate 	{ BT_WIM((bitmap), (bitindex)) |= BT_BIW(bitindex); }
1100Sstevel@tonic-gate #define	BT_CLEAR(bitmap, bitindex) \
1110Sstevel@tonic-gate 	{ BT_WIM((bitmap), (bitindex)) &= ~BT_BIW(bitindex); }
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate #ifdef _LP64
1140Sstevel@tonic-gate #define	BT_BITOUL32(nbits) \
1150Sstevel@tonic-gate 	(((nbits) + BT_NBIPUL32 - 1l) / BT_NBIPUL32)
1160Sstevel@tonic-gate #define	BT_SIZEOFMAP32(nbits) \
1170Sstevel@tonic-gate 	(BT_BITOUL32(nbits) * sizeof (uint_t))
1180Sstevel@tonic-gate #define	BT_TEST32(bitmap, bitindex) \
1190Sstevel@tonic-gate 	((BT_WIM32((bitmap), (bitindex)) & BT_BIW32(bitindex)) ? 1 : 0)
1200Sstevel@tonic-gate #define	BT_SET32(bitmap, bitindex) \
1210Sstevel@tonic-gate 	{ BT_WIM32((bitmap), (bitindex)) |= BT_BIW32(bitindex); }
1220Sstevel@tonic-gate #define	BT_CLEAR32(bitmap, bitindex) \
1230Sstevel@tonic-gate 	{ BT_WIM32((bitmap), (bitindex)) &= ~BT_BIW32(bitindex); }
1240Sstevel@tonic-gate #endif /* _LP64 */
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate 
127*2712Snn35248 /*
128*2712Snn35248  * BIT_ONLYONESET is a private macro not designed for bitmaps of
129*2712Snn35248  * arbitrary size.  u must be an unsigned integer/long.  It returns
130*2712Snn35248  * true if one and only one bit is set in u.
131*2712Snn35248  */
132*2712Snn35248 #define	BIT_ONLYONESET(u) \
133*2712Snn35248 	((((u) == 0) ? 0 : ((u) & ((u) - 1)) == 0))
134*2712Snn35248 
1350Sstevel@tonic-gate #if defined(_KERNEL) && !defined(_ASM)
1360Sstevel@tonic-gate #include <sys/atomic.h>
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate /*
1390Sstevel@tonic-gate  * return next available bit index from map with specified number of bits
1400Sstevel@tonic-gate  */
1410Sstevel@tonic-gate extern index_t	bt_availbit(ulong_t *bitmap, size_t nbits);
1420Sstevel@tonic-gate /*
1430Sstevel@tonic-gate  * find the highest order bit that is on, and is within or below
1440Sstevel@tonic-gate  * the word specified by wx
1450Sstevel@tonic-gate  */
1460Sstevel@tonic-gate extern int	bt_gethighbit(ulong_t *mapp, int wx);
1470Sstevel@tonic-gate extern int	bt_range(ulong_t *bitmap, size_t *pos1, size_t *pos2,
1480Sstevel@tonic-gate 			size_t end_pos);
1490Sstevel@tonic-gate /*
1500Sstevel@tonic-gate  * Find highest and lowest one bit set.
1510Sstevel@tonic-gate  *	Returns bit number + 1 of bit that is set, otherwise returns 0.
1520Sstevel@tonic-gate  * Low order bit is 0, high order bit is 31.
1530Sstevel@tonic-gate  */
1540Sstevel@tonic-gate extern int	highbit(ulong_t);
1550Sstevel@tonic-gate extern int	lowbit(ulong_t);
1560Sstevel@tonic-gate extern int	bt_getlowbit(ulong_t *bitmap, size_t start, size_t stop);
1570Sstevel@tonic-gate extern void	bt_copy(ulong_t *, ulong_t *, ulong_t);
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate /*
1600Sstevel@tonic-gate  * find the parity
1610Sstevel@tonic-gate  */
1620Sstevel@tonic-gate extern int	odd_parity(ulong_t);
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate /*
1650Sstevel@tonic-gate  * Atomically set/clear bits
1660Sstevel@tonic-gate  * Atomic exclusive operations will set "result" to "-1"
1670Sstevel@tonic-gate  * if the bit is already set/cleared. "result" will be set
1680Sstevel@tonic-gate  * to 0 otherwise.
1690Sstevel@tonic-gate  */
1700Sstevel@tonic-gate #define	BT_ATOMIC_SET(bitmap, bitindex) \
1710Sstevel@tonic-gate 	{ atomic_or_long(&(BT_WIM(bitmap, bitindex)), BT_BIW(bitindex)); }
1720Sstevel@tonic-gate #define	BT_ATOMIC_CLEAR(bitmap, bitindex) \
1730Sstevel@tonic-gate 	{ atomic_and_long(&(BT_WIM(bitmap, bitindex)), ~BT_BIW(bitindex)); }
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate #define	BT_ATOMIC_SET_EXCL(bitmap, bitindex, result) \
1760Sstevel@tonic-gate 	{ result = atomic_set_long_excl(&(BT_WIM(bitmap, bitindex)),	\
1770Sstevel@tonic-gate 	    (bitindex) % BT_NBIPUL); }
1780Sstevel@tonic-gate #define	BT_ATOMIC_CLEAR_EXCL(bitmap, bitindex, result) \
1790Sstevel@tonic-gate 	{ result = atomic_clear_long_excl(&(BT_WIM(bitmap, bitindex)),	\
1800Sstevel@tonic-gate 	    (bitindex) % BT_NBIPUL); }
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate /*
1830Sstevel@tonic-gate  * Extracts bits between index h (high, inclusive) and l (low, exclusive) from
1840Sstevel@tonic-gate  * u, which must be an unsigned integer.
1850Sstevel@tonic-gate  */
1860Sstevel@tonic-gate #define	BITX(u, h, l)	(((u) >> (l)) & ((1LU << ((h) - (l) + 1LU)) - 1LU))
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate #endif	/* _KERNEL && !_ASM */
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate #ifdef	__cplusplus
1910Sstevel@tonic-gate }
1920Sstevel@tonic-gate #endif
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate #endif	/* _SYS_BITMAP_H */
195