00001
00002
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef __L4UTIL__INCLUDE__BITOPS_H__
00029 #define __L4UTIL__INCLUDE__BITOPS_H__
00030
00031
00032 #include <l4/sys/l4int.h>
00033 #include <l4/sys/compiler.h>
00034
00036 #define l4util_test_and_clear_bit(b, dest) l4util_btr(b, dest)
00037 #define l4util_test_and_set_bit(b, dest) l4util_bts(b, dest)
00038 #define l4util_test_and_change_bit(b, dest) l4util_btc(b, dest)
00039 #define l4util_log2(word) l4util_bsr(word)
00040
00041
00042
00043
00044
00045 EXTERN_C_BEGIN
00046
00056 L4_INLINE void
00057 l4util_set_bit(int b, volatile l4_umword_t * dest);
00058
00059 L4_INLINE void
00060 l4util_set_bit32(int b, volatile l4_uint32_t * dest);
00061
00062 #if L4_MWORD_BITS >= 64
00063 L4_INLINE void
00064 l4util_set_bit64(int b, volatile l4_uint64_t * dest);
00065 #endif
00066
00074 L4_INLINE void
00075 l4util_clear_bit(int b, volatile l4_umword_t * dest);
00076
00077 L4_INLINE void
00078 l4util_clear_bit32(int b, volatile l4_uint32_t * dest);
00079
00080 #if L4_MWORD_BITS >= 64
00081 L4_INLINE void
00082 l4util_clear_bit64(int b, volatile l4_uint64_t * dest);
00083 #endif
00084
00092 L4_INLINE void
00093 l4util_complement_bit(int b, volatile l4_umword_t * dest);
00094
00104 L4_INLINE int
00105 l4util_test_bit(int b, const volatile l4_umword_t * dest);
00106
00107 L4_INLINE int
00108 l4util_test_bit32(int b, const volatile l4_uint32_t * dest);
00109
00110 #if L4_MWORD_BITS >= 64
00111 L4_INLINE int
00112 l4util_test_bit64(int b, const volatile l4_uint64_t * dest);
00113 #endif
00114
00126 L4_INLINE int
00127 l4util_bts(int b, volatile l4_umword_t * dest);
00128
00140 L4_INLINE int
00141 l4util_btr(int b, volatile l4_umword_t * dest);
00142
00154 L4_INLINE int
00155 l4util_btc(int b, volatile l4_umword_t * dest);
00156
00168 L4_INLINE int
00169 l4util_bsr(l4_umword_t word);
00170
00182 L4_INLINE int
00183 l4util_bsf(l4_umword_t word);
00184
00195 L4_INLINE int
00196 l4util_find_first_set_bit(const void * dest, l4_size_t size);
00197
00208 L4_INLINE int
00209 l4util_find_first_zero_bit(const void * dest, l4_size_t size);
00210
00211
00212 EXTERN_C_END
00213
00214
00215
00216
00217
00218 #include <l4/util/bitops_arch.h>
00219
00220
00221
00222
00223
00224 #ifndef __L4UTIL_BITOPS_HAVE_ARCH_SET_BIT
00225 #include <l4/util/atomic.h>
00226 L4_INLINE void
00227 l4util_set_bit(int b, volatile l4_umword_t * dest)
00228 {
00229 l4_umword_t oldval, newval;
00230
00231 dest += b / (sizeof(*dest) * 8);
00232 b &= sizeof(*dest) * 8 - 1;
00233
00234 do
00235 {
00236 oldval = *dest;
00237 newval = oldval | (1 << b);
00238 }
00239 while (!l4util_cmpxchg(dest, oldval, newval));
00240 }
00241 #endif
00242
00243 #ifndef __L4UTIL_BITOPS_HAVE_ARCH_CLEAR_BIT
00244 #include <l4/util/atomic.h>
00245 L4_INLINE void
00246 l4util_clear_bit(int b, volatile l4_umword_t * dest)
00247 {
00248 l4_umword_t oldval, newval;
00249
00250 dest += b / (sizeof(*dest) * 8);
00251 b &= sizeof(*dest) * 8 - 1;
00252
00253 do
00254 {
00255 oldval = *dest;
00256 newval = oldval & ~(1 << b);
00257 }
00258 while (!l4util_cmpxchg(dest, oldval, newval));
00259 }
00260 #endif
00261
00262 #ifndef __L4UTIL_BITOPS_HAVE_ARCH_TEST_BIT
00263 L4_INLINE int
00264 l4util_test_bit(int b, const volatile l4_umword_t * dest)
00265 {
00266 dest += b / (sizeof(*dest) * 8);
00267 b &= sizeof(*dest) * 8 - 1;
00268
00269 return (*dest >> b) & 1;
00270 }
00271 #endif
00272
00273 #ifndef __L4UTIL_BITOPS_HAVE_ARCH_TEST_BIT32
00274 L4_INLINE int
00275 l4util_test_bit32(int b, const volatile l4_uint32_t * dest)
00276 {
00277 dest += b / (sizeof(*dest) * 8);
00278 b &= sizeof(*dest) * 8 - 1;
00279
00280 return (*dest >> b) & 1;
00281 }
00282 #endif
00283
00284 #ifndef __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_SET
00285 #include <l4/util/atomic.h>
00286 L4_INLINE int
00287 l4util_bts(int b, volatile l4_umword_t * dest)
00288 {
00289 l4_umword_t oldval, newval;
00290
00291 dest += b / (sizeof(*dest) * 8);
00292 b &= sizeof(*dest) * 8 - 1;
00293
00294 do
00295 {
00296 oldval = *dest;
00297 newval = oldval | (1 << b);
00298 }
00299 while (!l4util_cmpxchg(dest, oldval, newval));
00300
00301
00302 return (oldval >> b) & 1;
00303 }
00304 #endif
00305
00306 #ifndef __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_RESET
00307 #include <l4/util/atomic.h>
00308 L4_INLINE int
00309 l4util_btr(int b, volatile l4_umword_t * dest)
00310 {
00311 l4_umword_t oldval, newval;
00312
00313 dest += b / (sizeof(*dest) * 8);
00314 b &= sizeof(*dest) * 8 - 1;
00315
00316 do
00317 {
00318 oldval = *dest;
00319 newval = oldval & ~(1 << b);
00320 }
00321 while (!l4util_cmpxchg(dest, oldval, newval));
00322
00323
00324 return (oldval >> b) & 1;
00325 }
00326 #endif
00327
00328 #ifndef __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_REVERSE
00329 L4_INLINE int
00330 l4util_bsr(l4_umword_t word)
00331 {
00332 int i;
00333
00334 if (!word)
00335 return -1;
00336
00337 for (i = 8 * sizeof(word) - 1; i >= 0; i--)
00338 if ((1 << i) & word)
00339 return i;
00340
00341 return -1;
00342 }
00343 #endif
00344
00345 #ifndef __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_FORWARD
00346 L4_INLINE int
00347 l4util_bsf(l4_umword_t word)
00348 {
00349 unsigned int i;
00350
00351 if (!word)
00352 return -1;
00353
00354 for (i = 0; i < sizeof(word) * 8; i++)
00355 if ((1 << i) & word)
00356 return i;
00357
00358 return -1;
00359 }
00360 #endif
00361
00362 #ifndef __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_ZERO_BIT
00363 L4_INLINE int
00364 l4util_find_first_zero_bit(const void * dest, l4_size_t size)
00365 {
00366 l4_size_t i, j;
00367 unsigned long *v = (unsigned long*)dest;
00368
00369 if (!size)
00370 return 0;
00371
00372 size = (size + 31) & ~0x1f;
00373
00374 for (i = j = 0; i < size; i++, j++)
00375 {
00376 if (j >= sizeof(*v) * 8)
00377 {
00378 j = 0;
00379 v++;
00380 }
00381 if (!((1 << j) & *v))
00382 return i;
00383 }
00384 return size + 1;
00385 }
00386 #endif
00387
00388 #ifndef __L4UTIL_BITOPS_HAVE_ARCH_COMPLEMENT_BIT
00389 L4_INLINE void
00390 l4util_complement_bit(int b, volatile l4_umword_t * dest)
00391 {
00392 dest += b / (sizeof(*dest) * 8);
00393 b &= sizeof(*dest) * 8 - 1;
00394
00395 *dest ^= 1UL << b;
00396 }
00397 #endif
00398
00399 #endif