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