xref: /titanic_53/usr/src/uts/common/os/bitset.c (revision fb2f18f820d90b001aea4fb27dd654bc1263c440)
1*fb2f18f8Sesaxe /*
2*fb2f18f8Sesaxe  * CDDL HEADER START
3*fb2f18f8Sesaxe  *
4*fb2f18f8Sesaxe  * The contents of this file are subject to the terms of the
5*fb2f18f8Sesaxe  * Common Development and Distribution License (the "License").
6*fb2f18f8Sesaxe  * You may not use this file except in compliance with the License.
7*fb2f18f8Sesaxe  *
8*fb2f18f8Sesaxe  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fb2f18f8Sesaxe  * or http://www.opensolaris.org/os/licensing.
10*fb2f18f8Sesaxe  * See the License for the specific language governing permissions
11*fb2f18f8Sesaxe  * and limitations under the License.
12*fb2f18f8Sesaxe  *
13*fb2f18f8Sesaxe  * When distributing Covered Code, include this CDDL HEADER in each
14*fb2f18f8Sesaxe  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fb2f18f8Sesaxe  * If applicable, add the following below this CDDL HEADER, with the
16*fb2f18f8Sesaxe  * fields enclosed by brackets "[]" replaced with your own identifying
17*fb2f18f8Sesaxe  * information: Portions Copyright [yyyy] [name of copyright owner]
18*fb2f18f8Sesaxe  *
19*fb2f18f8Sesaxe  * CDDL HEADER END
20*fb2f18f8Sesaxe  */
21*fb2f18f8Sesaxe /*
22*fb2f18f8Sesaxe  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*fb2f18f8Sesaxe  * Use is subject to license terms.
24*fb2f18f8Sesaxe  */
25*fb2f18f8Sesaxe 
26*fb2f18f8Sesaxe #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*fb2f18f8Sesaxe 
28*fb2f18f8Sesaxe #include <sys/bitset.h>
29*fb2f18f8Sesaxe #include <sys/kmem.h>
30*fb2f18f8Sesaxe #include <sys/systm.h>
31*fb2f18f8Sesaxe #include <sys/cmn_err.h>
32*fb2f18f8Sesaxe #include <sys/sysmacros.h>
33*fb2f18f8Sesaxe 
34*fb2f18f8Sesaxe /*
35*fb2f18f8Sesaxe  * Initialize a bitset_t.
36*fb2f18f8Sesaxe  * After bitset_init(), the bitset will be zero sized.
37*fb2f18f8Sesaxe  */
38*fb2f18f8Sesaxe void
39*fb2f18f8Sesaxe bitset_init(bitset_t *b)
40*fb2f18f8Sesaxe {
41*fb2f18f8Sesaxe 	bzero(b, sizeof (bitset_t));
42*fb2f18f8Sesaxe }
43*fb2f18f8Sesaxe 
44*fb2f18f8Sesaxe /*
45*fb2f18f8Sesaxe  * Uninitialize a bitset_t.
46*fb2f18f8Sesaxe  * This will free the bitset's data, leaving it zero sized.
47*fb2f18f8Sesaxe  */
48*fb2f18f8Sesaxe void
49*fb2f18f8Sesaxe bitset_fini(bitset_t *b)
50*fb2f18f8Sesaxe {
51*fb2f18f8Sesaxe 	if (b->bs_words > 0)
52*fb2f18f8Sesaxe 		kmem_free(b->bs_set, b->bs_words * sizeof (ulong_t));
53*fb2f18f8Sesaxe }
54*fb2f18f8Sesaxe 
55*fb2f18f8Sesaxe /*
56*fb2f18f8Sesaxe  * Resize a bitset to where it can hold sz number of bits.
57*fb2f18f8Sesaxe  * This can either grow or shrink the bitset holding capacity.
58*fb2f18f8Sesaxe  * In the case of shrinkage, elements that reside outside the new
59*fb2f18f8Sesaxe  * holding capacity of the bitset are lost.
60*fb2f18f8Sesaxe  */
61*fb2f18f8Sesaxe void
62*fb2f18f8Sesaxe bitset_resize(bitset_t *b, uint_t sz)
63*fb2f18f8Sesaxe {
64*fb2f18f8Sesaxe 	uint_t	nwords;
65*fb2f18f8Sesaxe 	ulong_t	*bset_new, *bset_tmp;
66*fb2f18f8Sesaxe 
67*fb2f18f8Sesaxe 	nwords = BT_BITOUL(sz);
68*fb2f18f8Sesaxe 	if (b->bs_words == nwords)
69*fb2f18f8Sesaxe 		return;	/* already properly sized */
70*fb2f18f8Sesaxe 
71*fb2f18f8Sesaxe 	/*
72*fb2f18f8Sesaxe 	 * Allocate the new ulong_t array, and copy the old one.
73*fb2f18f8Sesaxe 	 */
74*fb2f18f8Sesaxe 	if (nwords > 0) {
75*fb2f18f8Sesaxe 		bset_new = kmem_zalloc(nwords * sizeof (ulong_t), KM_SLEEP);
76*fb2f18f8Sesaxe 		bcopy(b->bs_set, bset_new,
77*fb2f18f8Sesaxe 		    MIN(b->bs_words, nwords) * sizeof (ulong_t));
78*fb2f18f8Sesaxe 	} else {
79*fb2f18f8Sesaxe 		bset_new = NULL;
80*fb2f18f8Sesaxe 	}
81*fb2f18f8Sesaxe 
82*fb2f18f8Sesaxe 	/* swap out the old ulong_t array for new one */
83*fb2f18f8Sesaxe 	bset_tmp = b->bs_set;
84*fb2f18f8Sesaxe 	b->bs_set = bset_new;
85*fb2f18f8Sesaxe 
86*fb2f18f8Sesaxe 	/* free up the old array */
87*fb2f18f8Sesaxe 	kmem_free(bset_tmp, b->bs_words * sizeof (ulong_t));
88*fb2f18f8Sesaxe 	b->bs_words = nwords;
89*fb2f18f8Sesaxe }
90*fb2f18f8Sesaxe 
91*fb2f18f8Sesaxe /*
92*fb2f18f8Sesaxe  * Returns the current holding capacity of the bitset
93*fb2f18f8Sesaxe  */
94*fb2f18f8Sesaxe uint_t
95*fb2f18f8Sesaxe bitset_capacity(bitset_t *b)
96*fb2f18f8Sesaxe {
97*fb2f18f8Sesaxe 	return (b->bs_words * BT_NBIPUL);
98*fb2f18f8Sesaxe }
99*fb2f18f8Sesaxe 
100*fb2f18f8Sesaxe /*
101*fb2f18f8Sesaxe  * Add and delete bits in the bitset.
102*fb2f18f8Sesaxe  *
103*fb2f18f8Sesaxe  * Adding a bit that is already set, and clearing a bit that's already clear
104*fb2f18f8Sesaxe  * is legal.
105*fb2f18f8Sesaxe  *
106*fb2f18f8Sesaxe  * Adding or deleting an element that falls outside the bitset's current
107*fb2f18f8Sesaxe  * holding capacity is illegal.
108*fb2f18f8Sesaxe  */
109*fb2f18f8Sesaxe void
110*fb2f18f8Sesaxe bitset_add(bitset_t *b, uint_t elt)
111*fb2f18f8Sesaxe {
112*fb2f18f8Sesaxe 	ASSERT(b->bs_words * BT_NBIPUL > elt);
113*fb2f18f8Sesaxe 
114*fb2f18f8Sesaxe 	BT_SET(b->bs_set, elt);
115*fb2f18f8Sesaxe }
116*fb2f18f8Sesaxe 
117*fb2f18f8Sesaxe void
118*fb2f18f8Sesaxe bitset_del(bitset_t *b, uint_t elt)
119*fb2f18f8Sesaxe {
120*fb2f18f8Sesaxe 	ASSERT(b->bs_words * BT_NBIPUL > elt);
121*fb2f18f8Sesaxe 
122*fb2f18f8Sesaxe 	BT_CLEAR(b->bs_set, elt);
123*fb2f18f8Sesaxe }
124*fb2f18f8Sesaxe 
125*fb2f18f8Sesaxe /*
126*fb2f18f8Sesaxe  * Return non-zero if the bit is present in the set
127*fb2f18f8Sesaxe  */
128*fb2f18f8Sesaxe int
129*fb2f18f8Sesaxe bitset_in_set(bitset_t *b, uint_t elt)
130*fb2f18f8Sesaxe {
131*fb2f18f8Sesaxe 	ASSERT(b->bs_words * BT_NBIPUL > elt);
132*fb2f18f8Sesaxe 
133*fb2f18f8Sesaxe 	return (BT_TEST(b->bs_set, elt));
134*fb2f18f8Sesaxe }
135*fb2f18f8Sesaxe 
136*fb2f18f8Sesaxe /*
137*fb2f18f8Sesaxe  * Return non-zero if the bitset is empty
138*fb2f18f8Sesaxe  */
139*fb2f18f8Sesaxe int
140*fb2f18f8Sesaxe bitset_is_null(bitset_t *b)
141*fb2f18f8Sesaxe {
142*fb2f18f8Sesaxe 	int	i;
143*fb2f18f8Sesaxe 
144*fb2f18f8Sesaxe 	for (i = 0; i < b->bs_words; i++)
145*fb2f18f8Sesaxe 		if (b->bs_set[i] != 0)
146*fb2f18f8Sesaxe 			return (0);
147*fb2f18f8Sesaxe 	return (1);
148*fb2f18f8Sesaxe }
149*fb2f18f8Sesaxe 
150*fb2f18f8Sesaxe /*
151*fb2f18f8Sesaxe  * Find the first set bit in the bitset
152*fb2f18f8Sesaxe  * Return -1 if no bit was found
153*fb2f18f8Sesaxe  */
154*fb2f18f8Sesaxe uint_t
155*fb2f18f8Sesaxe bitset_find(bitset_t *b)
156*fb2f18f8Sesaxe {
157*fb2f18f8Sesaxe 	uint_t	i;
158*fb2f18f8Sesaxe 	uint_t	elt = (uint_t)-1;
159*fb2f18f8Sesaxe 
160*fb2f18f8Sesaxe 	for (i = 0; i < b->bs_words; i++) {
161*fb2f18f8Sesaxe 		elt = (uint_t)(lowbit(b->bs_set[i]) - 1);
162*fb2f18f8Sesaxe 		if (elt != (uint_t)-1) {
163*fb2f18f8Sesaxe 			elt += i * BT_NBIPUL;
164*fb2f18f8Sesaxe 			break;
165*fb2f18f8Sesaxe 		}
166*fb2f18f8Sesaxe 	}
167*fb2f18f8Sesaxe 	return (elt);
168*fb2f18f8Sesaxe }
169