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