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