4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
31 #pragma ident "%Z%%M% %I% %E% SMI"
34 * Operations on bitmaps of arbitrary size
35 * A bitmap is a vector of 1 or more ulongs.
36 * The user of the package is responsible for range checks and keeping
40 #include <sys/types.h>
41 #include <sys/bitmap.h>
42 #include <sys/debug.h> /* ASSERT */
45 * Return index of first available bit in denoted bitmap, or -1 for
46 * failure. Size is the cardinality of the bitmap; that is, the
48 * No side-effects. In particular, does not update bitmap.
49 * Caller is responsible for range checks.
52 bt_availbit(ulong_t
*bitmap
, size_t nbits
)
54 index_t maxword
; /* index of last in map */
55 index_t wx
; /* word index in map */
58 * Look for a word with a bit off.
59 * Subtract one from nbits because we're converting it to a
63 maxword
= nbits
>> BT_ULSHIFT
;
64 for (wx
= 0; wx
<= maxword
; wx
++)
70 * Found a word with a bit off. Now find the bit in the word.
72 index_t bx
; /* bit index in word */
73 index_t maxbit
; /* last bit to look at */
77 maxbit
= wx
== maxword
? nbits
& BT_ULMASK
: BT_NBIPUL
- 1;
80 for (bx
= 0; bx
<= maxbit
; bx
++, bit
<<= 1) {
82 return (wx
<< BT_ULSHIFT
| bx
);
91 * Find highest order bit that is on, and is within or below
92 * the word specified by wx.
95 bt_gethighbit(ulong_t
*mapp
, int wx
)
99 while ((word
= mapp
[wx
]) == 0) {
105 return (wx
<< BT_ULSHIFT
| (highbit(word
) - 1));
110 * Search the bitmap for a consecutive pattern of 1's.
111 * Search starts at position pos1.
112 * Returns 1 on success and 0 on failure.
114 * Returns indices to the first bit (pos1)
115 * and one past the last bit (pos2) in the pattern.
118 bt_range(ulong_t
*bitmap
, size_t *pos1
, size_t *pos2
, size_t end_pos
)
122 for (pos
= *pos1
; pos
< end_pos
; pos
++)
123 if (BT_TEST(bitmap
, pos
))
131 for (; pos
< end_pos
; pos
++)
132 if (!BT_TEST(bitmap
, pos
))
141 * return the parity of the supplied long
143 * this works by successively partitioning the argument in half, and
144 * setting the parity of the result to the parity of the 2 halfs, until
145 * only one bit is left
148 odd_parity(ulong_t i
)
164 * get the lowest bit in the range of 'start' and 'stop', inclusive.
165 * I.e., if caller calls bt_getlowbit(map, X, Y), any value between X and Y,
166 * including X and Y can be returned.
167 * Neither start nor stop is required to align with word boundaries.
168 * If a bit is set in the range, the bit position is returned; otherwise,
172 bt_getlowbit(ulong_t
*map
, size_t start
, size_t stop
)
175 int counter
= start
>> BT_ULSHIFT
;
176 int limit
= stop
>> BT_ULSHIFT
;
177 index_t partial_start
= start
& BT_ULMASK
;
178 index_t partial_stop
= stop
& BT_ULMASK
;
185 * The range between 'start' and 'stop' can be very large, and the
186 * '1' bits in this range can be sparse.
187 * For performance reason, the underlying implementation operates
188 * on words, not on bits.
194 * Since the start is not aligned on word boundary, we
195 * need to patch the unwanted low order bits with 0's before
196 * operating on the first bitmap word.
198 word
= word
& (BT_ULMAXMASK
<< partial_start
);
202 * Locate a word from the map array with one of the bits set.
205 while ((word
== 0) && (counter
< limit
)) {
206 word
= map
[++counter
];
210 * The end of range has similar problems if it is not aligned.
211 * Taking care of the end which is not aligned.
214 if ((counter
== limit
) && (partial_stop
!= BT_ULMASK
)) {
216 * Take care the partial word by patch the high order
217 * bits with 0's. Here we dealing with the case that
218 * the last word of the bitmap is not aligned.
221 ASSERT(partial_stop
< BT_ULMASK
);
222 word
= word
& (~(BT_ULMAXMASK
<< partial_stop
+ 1));
231 return ((counter
<< BT_ULSHIFT
) | (lowbit(word
) - 1));
239 bt_copy(ulong_t
*from
, ulong_t
*to
, ulong_t size
)
242 for (i
= 0; i
< size
; i
++)