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: stable/10/sys/sys/bitset.h 320940 2017-07-13 08:33:02Z kib $ 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 118319652Skib#define BIT_OR2(_s, d, s1, s2) do { \ 119319652Skib __size_t __i; \ 120319652Skib for (__i = 0; __i < __bitset_words((_s)); __i++) \ 121319652Skib (d)->__bits[__i] = (s1)->__bits[__i] | (s2)->__bits[__i];\ 122319652Skib} while (0) 123319652Skib 124250395Sattilio#define BIT_AND(_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 130319652Skib#define BIT_AND2(_s, d, s1, s2) do { \ 131319652Skib __size_t __i; \ 132319652Skib for (__i = 0; __i < __bitset_words((_s)); __i++) \ 133319652Skib (d)->__bits[__i] = (s1)->__bits[__i] & (s2)->__bits[__i];\ 134319652Skib} while (0) 135319652Skib 136250395Sattilio#define BIT_NAND(_s, d, s) do { \ 137250395Sattilio __size_t __i; \ 138250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 139250395Sattilio (d)->__bits[__i] &= ~(s)->__bits[__i]; \ 140250395Sattilio} while (0) 141250395Sattilio 142319652Skib#define BIT_NAND2(_s, d, s1, s2) do { \ 143319652Skib __size_t __i; \ 144319652Skib for (__i = 0; __i < __bitset_words((_s)); __i++) \ 145319652Skib (d)->__bits[__i] = (s1)->__bits[__i] & ~(s2)->__bits[__i];\ 146319652Skib} while (0) 147319652Skib 148319652Skib#define BIT_XOR(_s, d, s) do { \ 149319652Skib __size_t __i; \ 150319652Skib for (__i = 0; __i < __bitset_words((_s)); __i++) \ 151319652Skib (d)->__bits[__i] ^= (s)->__bits[__i]; \ 152319652Skib} while (0) 153319652Skib 154319652Skib#define BIT_XOR2(_s, d, s1, s2) do { \ 155319652Skib __size_t __i; \ 156319652Skib for (__i = 0; __i < __bitset_words((_s)); __i++) \ 157319652Skib (d)->__bits[__i] = (s1)->__bits[__i] ^ (s2)->__bits[__i];\ 158319652Skib} while (0) 159319652Skib 160250395Sattilio#define BIT_CLR_ATOMIC(_s, n, p) \ 161250395Sattilio atomic_clear_long(&(p)->__bits[__bitset_word(_s, n)], \ 162250395Sattilio __bitset_mask((_s), n)) 163250395Sattilio 164250395Sattilio#define BIT_SET_ATOMIC(_s, n, p) \ 165250395Sattilio atomic_set_long(&(p)->__bits[__bitset_word(_s, n)], \ 166250395Sattilio __bitset_mask((_s), n)) 167250395Sattilio 168276386Sneel#define BIT_SET_ATOMIC_ACQ(_s, n, p) \ 169276386Sneel atomic_set_acq_long(&(p)->__bits[__bitset_word(_s, n)], \ 170276386Sneel __bitset_mask((_s), n)) 171276386Sneel 172255059Skib/* Convenience functions catering special cases. */ 173255059Skib#define BIT_AND_ATOMIC(_s, d, s) do { \ 174255059Skib __size_t __i; \ 175255059Skib for (__i = 0; __i < __bitset_words((_s)); __i++) \ 176255059Skib atomic_clear_long(&(d)->__bits[__i], \ 177255059Skib ~(s)->__bits[__i]); \ 178255059Skib} while (0) 179255059Skib 180250395Sattilio#define BIT_OR_ATOMIC(_s, d, s) do { \ 181250395Sattilio __size_t __i; \ 182250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 183250395Sattilio atomic_set_long(&(d)->__bits[__i], \ 184250395Sattilio (s)->__bits[__i]); \ 185250395Sattilio} while (0) 186250395Sattilio 187250395Sattilio#define BIT_COPY_STORE_REL(_s, f, t) do { \ 188250395Sattilio __size_t __i; \ 189250395Sattilio for (__i = 0; __i < __bitset_words((_s)); __i++) \ 190250395Sattilio atomic_store_rel_long(&(t)->__bits[__i], \ 191250395Sattilio (f)->__bits[__i]); \ 192250395Sattilio} while (0) 193250395Sattilio 194251703Sjeff#define BIT_FFS(_s, p) __extension__ ({ \ 195251703Sjeff __size_t __i; \ 196251703Sjeff int __bit; \ 197251703Sjeff \ 198251703Sjeff __bit = 0; \ 199251703Sjeff for (__i = 0; __i < __bitset_words((_s)); __i++) { \ 200251703Sjeff if ((p)->__bits[__i] != 0) { \ 201251703Sjeff __bit = ffsl((p)->__bits[__i]); \ 202251703Sjeff __bit += __i * _BITSET_BITS; \ 203251703Sjeff break; \ 204251703Sjeff } \ 205251703Sjeff } \ 206251703Sjeff __bit; \ 207251703Sjeff}) 208251703Sjeff 209320940Skib#define BIT_FLS(_s, p) __extension__ ({ \ 210320940Skib __size_t __i; \ 211320940Skib int __bit; \ 212320940Skib \ 213320940Skib __bit = 0; \ 214320940Skib for (__i = __bitset_words((_s)); __i > 0; __i--) { \ 215320940Skib if ((p)->__bits[__i - 1] != 0) { \ 216320940Skib __bit = flsl((p)->__bits[__i - 1]); \ 217320940Skib __bit += (__i - 1) * _BITSET_BITS; \ 218320940Skib break; \ 219320940Skib } \ 220320940Skib } \ 221320940Skib __bit; \ 222320940Skib}) 223320940Skib 224281538Sjhb#define BIT_COUNT(_s, p) __extension__ ({ \ 225281538Sjhb __size_t __i; \ 226281538Sjhb int __count; \ 227281538Sjhb \ 228281538Sjhb __count = 0; \ 229281538Sjhb for (__i = 0; __i < __bitset_words((_s)); __i++) \ 230281538Sjhb __count += __bitcountl((p)->__bits[__i]); \ 231281538Sjhb __count; \ 232281538Sjhb}) 233281538Sjhb 234250395Sattilio#endif /* !_SYS_BITSET_H_ */ 235