1250395Sattilio/*- 2250395Sattilio * Copyright (c) 2008, Jeffrey Roberson <jeff@freebsd.org> 3250395Sattilio * All rights reserved. 4250395Sattilio * 5250395Sattilio * Copyright (c) 2008 Nokia Corporation 6250395Sattilio * All rights reserved. 7250395Sattilio * 8250395Sattilio * Redistribution and use in source and binary forms, with or without 9250395Sattilio * modification, are permitted provided that the following conditions 10250395Sattilio * are met: 11250395Sattilio * 1. Redistributions of source code must retain the above copyright 12250395Sattilio * notice unmodified, this list of conditions, and the following 13250395Sattilio * disclaimer. 14250395Sattilio * 2. Redistributions in binary form must reproduce the above copyright 15250395Sattilio * notice, this list of conditions and the following disclaimer in the 16250395Sattilio * documentation and/or other materials provided with the distribution. 17250395Sattilio * 18250395Sattilio * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19250395Sattilio * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20250395Sattilio * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21250395Sattilio * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22250395Sattilio * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23250395Sattilio * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24250395Sattilio * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25250395Sattilio * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26250395Sattilio * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27250395Sattilio * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28250395Sattilio * 29250395Sattilio * $FreeBSD$ 30250395Sattilio */ 31250395Sattilio 32250395Sattilio#ifndef _SYS_BITSET_H_ 33250395Sattilio#define _SYS_BITSET_H_ 34250395Sattilio 35250395Sattilio#define BIT_CLR(_s, n, p) \ 36250395Sattilio ((p)->__bits[__bitset_word(_s, n)] &= ~__bitset_mask((_s), (n))) 37250395Sattilio 38250395Sattilio#define BIT_COPY(_s, f, t) (void)(*(t) = *(f)) 39250395Sattilio 40250395Sattilio#define BIT_ISSET(_s, n, p) \ 41250395Sattilio ((((p)->__bits[__bitset_word(_s, n)] & __bitset_mask((_s), (n))) != 0)) 42250395Sattilio 43250395Sattilio#define BIT_SET(_s, n, p) \ 44250395Sattilio ((p)->__bits[__bitset_word(_s, n)] |= __bitset_mask((_s), (n))) 45250395Sattilio 46250395Sattilio#define BIT_ZERO(_s, p) do { \ 47250395Sattilio __size_t __i; \ 48250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 49250395Sattilio (p)->__bits[__i] = 0L; \ 50250395Sattilio} while (0) 51250395Sattilio 52250395Sattilio#define BIT_FILL(_s, p) do { \ 53250395Sattilio __size_t __i; \ 54250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 55250395Sattilio (p)->__bits[__i] = -1L; \ 56250395Sattilio} while (0) 57250395Sattilio 58250395Sattilio#define BIT_SETOF(_s, n, p) do { \ 59250395Sattilio BIT_ZERO(_s, p); \ 60250395Sattilio (p)->__bits[__bitset_word(_s, n)] = __bitset_mask((_s), (n)); \ 61250395Sattilio} while (0) 62250395Sattilio 63250395Sattilio/* Is p empty. */ 64250395Sattilio#define BIT_EMPTY(_s, p) __extension__ ({ \ 65250395Sattilio __size_t __i; \ 66250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 67250395Sattilio if ((p)->__bits[__i]) \ 68250395Sattilio break; \ 69250395Sattilio __i == __bitset_words((_s)); \ 70250395Sattilio}) 71250395Sattilio 72250395Sattilio/* Is p full set. */ 73250395Sattilio#define BIT_ISFULLSET(_s, p) __extension__ ({ \ 74250395Sattilio __size_t __i; \ 75250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 76250395Sattilio if ((p)->__bits[__i] != (long)-1) \ 77250395Sattilio break; \ 78250395Sattilio __i == __bitset_words((_s)); \ 79250395Sattilio}) 80250395Sattilio 81250395Sattilio/* Is c a subset of p. */ 82250395Sattilio#define BIT_SUBSET(_s, p, c) __extension__ ({ \ 83250395Sattilio __size_t __i; \ 84250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 85250395Sattilio if (((c)->__bits[__i] & \ 86250395Sattilio (p)->__bits[__i]) != \ 87250395Sattilio (c)->__bits[__i]) \ 88250395Sattilio break; \ 89250395Sattilio __i == __bitset_words((_s)); \ 90250395Sattilio}) 91250395Sattilio 92250395Sattilio/* Are there any common bits between b & c? */ 93250395Sattilio#define BIT_OVERLAP(_s, p, c) __extension__ ({ \ 94250395Sattilio __size_t __i; \ 95250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 96250395Sattilio if (((c)->__bits[__i] & \ 97250395Sattilio (p)->__bits[__i]) != 0) \ 98250395Sattilio break; \ 99250395Sattilio __i != __bitset_words((_s)); \ 100250395Sattilio}) 101250395Sattilio 102250395Sattilio/* Compare two sets, returns 0 if equal 1 otherwise. */ 103250395Sattilio#define BIT_CMP(_s, p, c) __extension__ ({ \ 104250395Sattilio __size_t __i; \ 105250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 106250395Sattilio if (((c)->__bits[__i] != \ 107250395Sattilio (p)->__bits[__i])) \ 108250395Sattilio break; \ 109250395Sattilio __i != __bitset_words((_s)); \ 110250395Sattilio}) 111250395Sattilio 112250395Sattilio#define BIT_OR(_s, d, s) do { \ 113250395Sattilio __size_t __i; \ 114250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 115250395Sattilio (d)->__bits[__i] |= (s)->__bits[__i]; \ 116250395Sattilio} while (0) 117250395Sattilio 118250395Sattilio#define BIT_AND(_s, d, s) do { \ 119250395Sattilio __size_t __i; \ 120250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 121250395Sattilio (d)->__bits[__i] &= (s)->__bits[__i]; \ 122250395Sattilio} while (0) 123250395Sattilio 124250395Sattilio#define BIT_NAND(_s, d, s) do { \ 125250395Sattilio __size_t __i; \ 126250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 127250395Sattilio (d)->__bits[__i] &= ~(s)->__bits[__i]; \ 128250395Sattilio} while (0) 129250395Sattilio 130250395Sattilio#define BIT_CLR_ATOMIC(_s, n, p) \ 131250395Sattilio atomic_clear_long(&(p)->__bits[__bitset_word(_s, n)], \ 132250395Sattilio __bitset_mask((_s), n)) 133250395Sattilio 134250395Sattilio#define BIT_SET_ATOMIC(_s, n, p) \ 135250395Sattilio atomic_set_long(&(p)->__bits[__bitset_word(_s, n)], \ 136250395Sattilio __bitset_mask((_s), n)) 137250395Sattilio 138255059Skib/* Convenience functions catering special cases. */ 139255059Skib#define BIT_AND_ATOMIC(_s, d, s) do { \ 140255059Skib __size_t __i; \ 141255059Skib for (__i = 0; __i < __bitset_words((_s)); __i++) \ 142255059Skib atomic_clear_long(&(d)->__bits[__i], \ 143255059Skib ~(s)->__bits[__i]); \ 144255059Skib} while (0) 145255059Skib 146250395Sattilio#define BIT_OR_ATOMIC(_s, d, s) do { \ 147250395Sattilio __size_t __i; \ 148250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 149250395Sattilio atomic_set_long(&(d)->__bits[__i], \ 150250395Sattilio (s)->__bits[__i]); \ 151250395Sattilio} while (0) 152250395Sattilio 153250395Sattilio#define BIT_COPY_STORE_REL(_s, f, t) do { \ 154250395Sattilio __size_t __i; \ 155250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 156250395Sattilio atomic_store_rel_long(&(t)->__bits[__i], \ 157250395Sattilio (f)->__bits[__i]); \ 158250395Sattilio} while (0) 159250395Sattilio 160251703Sjeff#define BIT_FFS(_s, p) __extension__ ({ \ 161251703Sjeff __size_t __i; \ 162251703Sjeff int __bit; \ 163251703Sjeff \ 164251703Sjeff __bit = 0; \ 165251703Sjeff for (__i = 0; __i < __bitset_words((_s)); __i++) { \ 166251703Sjeff if ((p)->__bits[__i] != 0) { \ 167251703Sjeff __bit = ffsl((p)->__bits[__i]); \ 168251703Sjeff __bit += __i * _BITSET_BITS; \ 169251703Sjeff break; \ 170251703Sjeff } \ 171251703Sjeff } \ 172251703Sjeff __bit; \ 173251703Sjeff}) 174251703Sjeff 175250395Sattilio#endif /* !_SYS_BITSET_H_ */ 176