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