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