1*1eaf0ac3Slogwang /*- 2*1eaf0ac3Slogwang * Copyright (c) 2008, Jeffrey Roberson <[email protected]> 3*1eaf0ac3Slogwang * All rights reserved. 4*1eaf0ac3Slogwang * 5*1eaf0ac3Slogwang * Copyright (c) 2008 Nokia Corporation 6*1eaf0ac3Slogwang * All rights reserved. 7*1eaf0ac3Slogwang * 8*1eaf0ac3Slogwang * Redistribution and use in source and binary forms, with or without 9*1eaf0ac3Slogwang * modification, are permitted provided that the following conditions 10*1eaf0ac3Slogwang * are met: 11*1eaf0ac3Slogwang * 1. Redistributions of source code must retain the above copyright 12*1eaf0ac3Slogwang * notice unmodified, this list of conditions, and the following 13*1eaf0ac3Slogwang * disclaimer. 14*1eaf0ac3Slogwang * 2. Redistributions in binary form must reproduce the above copyright 15*1eaf0ac3Slogwang * notice, this list of conditions and the following disclaimer in the 16*1eaf0ac3Slogwang * documentation and/or other materials provided with the distribution. 17*1eaf0ac3Slogwang * 18*1eaf0ac3Slogwang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19*1eaf0ac3Slogwang * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20*1eaf0ac3Slogwang * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21*1eaf0ac3Slogwang * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22*1eaf0ac3Slogwang * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23*1eaf0ac3Slogwang * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24*1eaf0ac3Slogwang * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25*1eaf0ac3Slogwang * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26*1eaf0ac3Slogwang * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27*1eaf0ac3Slogwang * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*1eaf0ac3Slogwang * 29*1eaf0ac3Slogwang * $FreeBSD$ 30*1eaf0ac3Slogwang */ 31*1eaf0ac3Slogwang 32*1eaf0ac3Slogwang #ifndef _SYS_BITSET_H_ 33*1eaf0ac3Slogwang #define _SYS_BITSET_H_ 34*1eaf0ac3Slogwang 35*1eaf0ac3Slogwang #define __bitset_mask(_s, n) \ 36*1eaf0ac3Slogwang (1L << ((__bitset_words((_s)) == 1) ? \ 37*1eaf0ac3Slogwang (__size_t)(n) : ((n) % _BITSET_BITS))) 38*1eaf0ac3Slogwang 39*1eaf0ac3Slogwang #define __bitset_word(_s, n) \ 40*1eaf0ac3Slogwang ((__bitset_words((_s)) == 1) ? 0 : ((n) / _BITSET_BITS)) 41*1eaf0ac3Slogwang 42*1eaf0ac3Slogwang #define BIT_CLR(_s, n, p) \ 43*1eaf0ac3Slogwang ((p)->__bits[__bitset_word(_s, n)] &= ~__bitset_mask((_s), (n))) 44*1eaf0ac3Slogwang 45*1eaf0ac3Slogwang #define BIT_COPY(_s, f, t) (void)(*(t) = *(f)) 46*1eaf0ac3Slogwang 47*1eaf0ac3Slogwang #define BIT_ISSET(_s, n, p) \ 48*1eaf0ac3Slogwang ((((p)->__bits[__bitset_word(_s, n)] & __bitset_mask((_s), (n))) != 0)) 49*1eaf0ac3Slogwang 50*1eaf0ac3Slogwang #define BIT_SET(_s, n, p) \ 51*1eaf0ac3Slogwang ((p)->__bits[__bitset_word(_s, n)] |= __bitset_mask((_s), (n))) 52*1eaf0ac3Slogwang 53*1eaf0ac3Slogwang #define BIT_ZERO(_s, p) do { \ 54*1eaf0ac3Slogwang __size_t __i; \ 55*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) \ 56*1eaf0ac3Slogwang (p)->__bits[__i] = 0L; \ 57*1eaf0ac3Slogwang } while (0) 58*1eaf0ac3Slogwang 59*1eaf0ac3Slogwang #define BIT_FILL(_s, p) do { \ 60*1eaf0ac3Slogwang __size_t __i; \ 61*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) \ 62*1eaf0ac3Slogwang (p)->__bits[__i] = -1L; \ 63*1eaf0ac3Slogwang } while (0) 64*1eaf0ac3Slogwang 65*1eaf0ac3Slogwang #define BIT_SETOF(_s, n, p) do { \ 66*1eaf0ac3Slogwang BIT_ZERO(_s, p); \ 67*1eaf0ac3Slogwang (p)->__bits[__bitset_word(_s, n)] = __bitset_mask((_s), (n)); \ 68*1eaf0ac3Slogwang } while (0) 69*1eaf0ac3Slogwang 70*1eaf0ac3Slogwang /* Is p empty. */ 71*1eaf0ac3Slogwang #define BIT_EMPTY(_s, p) __extension__ ({ \ 72*1eaf0ac3Slogwang __size_t __i; \ 73*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) \ 74*1eaf0ac3Slogwang if ((p)->__bits[__i]) \ 75*1eaf0ac3Slogwang break; \ 76*1eaf0ac3Slogwang __i == __bitset_words((_s)); \ 77*1eaf0ac3Slogwang }) 78*1eaf0ac3Slogwang 79*1eaf0ac3Slogwang /* Is p full set. */ 80*1eaf0ac3Slogwang #define BIT_ISFULLSET(_s, p) __extension__ ({ \ 81*1eaf0ac3Slogwang __size_t __i; \ 82*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) \ 83*1eaf0ac3Slogwang if ((p)->__bits[__i] != (long)-1) \ 84*1eaf0ac3Slogwang break; \ 85*1eaf0ac3Slogwang __i == __bitset_words((_s)); \ 86*1eaf0ac3Slogwang }) 87*1eaf0ac3Slogwang 88*1eaf0ac3Slogwang /* Is c a subset of p. */ 89*1eaf0ac3Slogwang #define BIT_SUBSET(_s, p, c) __extension__ ({ \ 90*1eaf0ac3Slogwang __size_t __i; \ 91*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) \ 92*1eaf0ac3Slogwang if (((c)->__bits[__i] & \ 93*1eaf0ac3Slogwang (p)->__bits[__i]) != \ 94*1eaf0ac3Slogwang (c)->__bits[__i]) \ 95*1eaf0ac3Slogwang break; \ 96*1eaf0ac3Slogwang __i == __bitset_words((_s)); \ 97*1eaf0ac3Slogwang }) 98*1eaf0ac3Slogwang 99*1eaf0ac3Slogwang /* Are there any common bits between b & c? */ 100*1eaf0ac3Slogwang #define BIT_OVERLAP(_s, p, c) __extension__ ({ \ 101*1eaf0ac3Slogwang __size_t __i; \ 102*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) \ 103*1eaf0ac3Slogwang if (((c)->__bits[__i] & \ 104*1eaf0ac3Slogwang (p)->__bits[__i]) != 0) \ 105*1eaf0ac3Slogwang break; \ 106*1eaf0ac3Slogwang __i != __bitset_words((_s)); \ 107*1eaf0ac3Slogwang }) 108*1eaf0ac3Slogwang 109*1eaf0ac3Slogwang /* Compare two sets, returns 0 if equal 1 otherwise. */ 110*1eaf0ac3Slogwang #define BIT_CMP(_s, p, c) __extension__ ({ \ 111*1eaf0ac3Slogwang __size_t __i; \ 112*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) \ 113*1eaf0ac3Slogwang if (((c)->__bits[__i] != \ 114*1eaf0ac3Slogwang (p)->__bits[__i])) \ 115*1eaf0ac3Slogwang break; \ 116*1eaf0ac3Slogwang __i != __bitset_words((_s)); \ 117*1eaf0ac3Slogwang }) 118*1eaf0ac3Slogwang 119*1eaf0ac3Slogwang #define BIT_OR(_s, d, s) do { \ 120*1eaf0ac3Slogwang __size_t __i; \ 121*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) \ 122*1eaf0ac3Slogwang (d)->__bits[__i] |= (s)->__bits[__i]; \ 123*1eaf0ac3Slogwang } while (0) 124*1eaf0ac3Slogwang 125*1eaf0ac3Slogwang #define BIT_AND(_s, d, s) do { \ 126*1eaf0ac3Slogwang __size_t __i; \ 127*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) \ 128*1eaf0ac3Slogwang (d)->__bits[__i] &= (s)->__bits[__i]; \ 129*1eaf0ac3Slogwang } while (0) 130*1eaf0ac3Slogwang 131*1eaf0ac3Slogwang #define BIT_NAND(_s, d, s) do { \ 132*1eaf0ac3Slogwang __size_t __i; \ 133*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) \ 134*1eaf0ac3Slogwang (d)->__bits[__i] &= ~(s)->__bits[__i]; \ 135*1eaf0ac3Slogwang } while (0) 136*1eaf0ac3Slogwang 137*1eaf0ac3Slogwang #define BIT_CLR_ATOMIC(_s, n, p) \ 138*1eaf0ac3Slogwang atomic_clear_long(&(p)->__bits[__bitset_word(_s, n)], \ 139*1eaf0ac3Slogwang __bitset_mask((_s), n)) 140*1eaf0ac3Slogwang 141*1eaf0ac3Slogwang #define BIT_SET_ATOMIC(_s, n, p) \ 142*1eaf0ac3Slogwang atomic_set_long(&(p)->__bits[__bitset_word(_s, n)], \ 143*1eaf0ac3Slogwang __bitset_mask((_s), n)) 144*1eaf0ac3Slogwang 145*1eaf0ac3Slogwang #define BIT_SET_ATOMIC_ACQ(_s, n, p) \ 146*1eaf0ac3Slogwang atomic_set_acq_long(&(p)->__bits[__bitset_word(_s, n)], \ 147*1eaf0ac3Slogwang __bitset_mask((_s), n)) 148*1eaf0ac3Slogwang 149*1eaf0ac3Slogwang /* Convenience functions catering special cases. */ 150*1eaf0ac3Slogwang #define BIT_AND_ATOMIC(_s, d, s) do { \ 151*1eaf0ac3Slogwang __size_t __i; \ 152*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) \ 153*1eaf0ac3Slogwang atomic_clear_long(&(d)->__bits[__i], \ 154*1eaf0ac3Slogwang ~(s)->__bits[__i]); \ 155*1eaf0ac3Slogwang } while (0) 156*1eaf0ac3Slogwang 157*1eaf0ac3Slogwang #define BIT_OR_ATOMIC(_s, d, s) do { \ 158*1eaf0ac3Slogwang __size_t __i; \ 159*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) \ 160*1eaf0ac3Slogwang atomic_set_long(&(d)->__bits[__i], \ 161*1eaf0ac3Slogwang (s)->__bits[__i]); \ 162*1eaf0ac3Slogwang } while (0) 163*1eaf0ac3Slogwang 164*1eaf0ac3Slogwang #define BIT_COPY_STORE_REL(_s, f, t) do { \ 165*1eaf0ac3Slogwang __size_t __i; \ 166*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) \ 167*1eaf0ac3Slogwang atomic_store_rel_long(&(t)->__bits[__i], \ 168*1eaf0ac3Slogwang (f)->__bits[__i]); \ 169*1eaf0ac3Slogwang } while (0) 170*1eaf0ac3Slogwang 171*1eaf0ac3Slogwang #define BIT_FFS(_s, p) __extension__ ({ \ 172*1eaf0ac3Slogwang __size_t __i; \ 173*1eaf0ac3Slogwang int __bit; \ 174*1eaf0ac3Slogwang \ 175*1eaf0ac3Slogwang __bit = 0; \ 176*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) { \ 177*1eaf0ac3Slogwang if ((p)->__bits[__i] != 0) { \ 178*1eaf0ac3Slogwang __bit = ffsl((p)->__bits[__i]); \ 179*1eaf0ac3Slogwang __bit += __i * _BITSET_BITS; \ 180*1eaf0ac3Slogwang break; \ 181*1eaf0ac3Slogwang } \ 182*1eaf0ac3Slogwang } \ 183*1eaf0ac3Slogwang __bit; \ 184*1eaf0ac3Slogwang }) 185*1eaf0ac3Slogwang 186*1eaf0ac3Slogwang #define BIT_COUNT(_s, p) __extension__ ({ \ 187*1eaf0ac3Slogwang __size_t __i; \ 188*1eaf0ac3Slogwang int __count; \ 189*1eaf0ac3Slogwang \ 190*1eaf0ac3Slogwang __count = 0; \ 191*1eaf0ac3Slogwang for (__i = 0; __i < __bitset_words((_s)); __i++) \ 192*1eaf0ac3Slogwang __count += __bitcountl((p)->__bits[__i]); \ 193*1eaf0ac3Slogwang __count; \ 194*1eaf0ac3Slogwang }) 195*1eaf0ac3Slogwang 196*1eaf0ac3Slogwang #define BITSET_T_INITIALIZER(x) \ 197*1eaf0ac3Slogwang { .__bits = { x } } 198*1eaf0ac3Slogwang 199*1eaf0ac3Slogwang #define BITSET_FSET(n) \ 200*1eaf0ac3Slogwang [ 0 ... ((n) - 1) ] = (-1L) 201*1eaf0ac3Slogwang 202*1eaf0ac3Slogwang /* 203*1eaf0ac3Slogwang * Dynamically allocate a bitset. 204*1eaf0ac3Slogwang */ 205*1eaf0ac3Slogwang #define BITSET_ALLOC(_s, mt, mf) \ 206*1eaf0ac3Slogwang malloc(__bitset_words(_s) * sizeof(long), mt, (mf)) 207*1eaf0ac3Slogwang 208*1eaf0ac3Slogwang #endif /* !_SYS_BITSET_H_ */ 209