5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2007 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
22 #define SILC_BIT_POS(bit) (bit / SILC_BIT_SIZE)
23 #define SILC_BIT_MASK(bit) (1UL << (bit % SILC_BIT_SIZE))
27 SilcBool silc_bit_set(volatile unsigned long *bitmap, SilcUInt32 bitmap_size,
30 SilcUInt32 pos = SILC_BIT_POS(bit);
31 unsigned long mask = SILC_BIT_MASK(bit);
34 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
37 if (pos >= bitmap_size) {
38 silc_set_errno(SILC_ERR_OVERFLOW);
48 SilcBool silc_bit_clear(volatile unsigned long *bitmap, SilcUInt32 bitmap_size,
51 SilcUInt32 pos = SILC_BIT_POS(bit);
52 unsigned long mask = SILC_BIT_MASK(bit);
55 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
58 if (pos >= bitmap_size) {
59 silc_set_errno(SILC_ERR_OVERFLOW);
69 SilcBool silc_bit_toggle(volatile unsigned long *bitmap,
70 SilcUInt32 bitmap_size, SilcUInt32 bit)
72 SilcUInt32 pos = SILC_BIT_POS(bit);
73 unsigned long mask = SILC_BIT_MASK(bit);
76 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
79 if (pos >= bitmap_size) {
80 silc_set_errno(SILC_ERR_OVERFLOW);
88 /* Set bit and return old value */
90 int silc_bit_test_and_set(volatile unsigned long *bitmap,
91 SilcUInt32 bitmap_size, SilcUInt32 bit)
93 SilcUInt32 pos = SILC_BIT_POS(bit);
94 unsigned long mask = SILC_BIT_MASK(bit), ret;
97 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
100 if (pos >= bitmap_size) {
101 silc_set_errno(SILC_ERR_OVERFLOW);
108 return (ret & mask) != 0;
111 /* Clear bit and return old value */
113 int silc_bit_test_and_clear(volatile unsigned long *bitmap,
114 SilcUInt32 bitmap_size, SilcUInt32 bit)
116 SilcUInt32 pos = SILC_BIT_POS(bit);
117 unsigned long mask = SILC_BIT_MASK(bit), ret;
120 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
123 if (pos >= bitmap_size) {
124 silc_set_errno(SILC_ERR_OVERFLOW);
129 bitmap[pos] &= ~mask;
131 return (ret & mask) != 0;
134 /* Toggle bit and return old value */
136 int silc_bit_test_and_toggle(volatile unsigned long *bitmap,
137 SilcUInt32 bitmap_size, SilcUInt32 bit)
139 SilcUInt32 pos = SILC_BIT_POS(bit);
140 unsigned long mask = SILC_BIT_MASK(bit), ret;
143 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
146 if (pos >= bitmap_size) {
147 silc_set_errno(SILC_ERR_OVERFLOW);
154 return (ret & mask) != 0;
157 /* Return bit value */
159 int silc_bit_get(volatile unsigned long *bitmap, SilcUInt32 bitmap_size,
162 SilcUInt32 pos = SILC_BIT_POS(bit);
163 unsigned long mask = SILC_BIT_MASK(bit);
166 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
169 if (pos >= bitmap_size) {
170 silc_set_errno(SILC_ERR_OVERFLOW);
174 return (bitmap[pos] & mask) != 0;
177 /* Return first set bit number */
179 int silc_bit_ffs(volatile unsigned long *bitmap, SilcUInt32 bitmap_size)
181 return silc_bit_fns(bitmap, bitmap_size, 0);
184 /* Return first zero bit number */
186 int silc_bit_ffz(volatile unsigned long *bitmap, SilcUInt32 bitmap_size)
188 return silc_bit_fnz(bitmap, bitmap_size, 0);
191 /* Return next set bit number */
193 int silc_bit_fns(volatile unsigned long *bitmap, SilcUInt32 bitmap_size,
196 register SilcUInt32 i;
199 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
202 if (offset >= bitmap_size * SILC_BIT_SIZE) {
203 silc_set_errno(SILC_ERR_OVERFLOW);
207 for (i = offset; i < bitmap_size * SILC_BIT_SIZE; i++)
208 if (bitmap[SILC_BIT_POS(i)] & SILC_BIT_MASK(i))
211 silc_set_errno(SILC_ERR_NOT_FOUND);
215 /* Return next zero bit number */
217 int silc_bit_fnz(volatile unsigned long *bitmap, SilcUInt32 bitmap_size,
220 register SilcUInt32 i;
223 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
226 if (offset >= bitmap_size * SILC_BIT_SIZE) {
227 silc_set_errno(SILC_ERR_OVERFLOW);
231 for (i = offset; i < bitmap_size * SILC_BIT_SIZE; i++)
232 if ((bitmap[SILC_BIT_POS(i)] & SILC_BIT_MASK(i)) == 0)
235 silc_set_errno(SILC_ERR_NOT_FOUND);
241 void silc_bit_clear_bitmap(volatile unsigned long *bitmap,
242 SilcUInt32 bitmap_size)
246 memset((void *)bitmap, 0, bitmap_size * 8);