Main Page   File List  

bitops.h

Go to the documentation of this file.
00001 /* $Id: bitops.h 27933 2007-03-08 10:15:20Z adam $ */
00002 /*****************************************************************************/
00011 /*
00012  * Copyright (C) 2000-2002
00013  * Dresden University of Technology, Operating Systems Research Group
00014  *
00015  * This file contains free software, you can redistribute it and/or modify
00016  * it under the terms of the GNU General Public License, Version 2 as
00017  * published by the Free Software Foundation (see the file COPYING).
00018  *
00019  * This program is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  * GNU General Public License for more details.
00023  *
00024  * For different licensing schemes please contact
00025  * <contact@os.inf.tu-dresden.de>.
00026  */
00027 /*****************************************************************************/
00028 #ifndef __L4UTIL__INCLUDE__BITOPS_H__
00029 #define __L4UTIL__INCLUDE__BITOPS_H__
00030 
00031 /* L4 includes */
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  *** Prototypes
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  *** Implementation of specific version
00216  *****************************************************************************/
00217 
00218 #include <l4/util/bitops_arch.h>
00219 
00220 /*****************************************************************************
00221  *** Generic implementations
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); /* advance dest to the proper element */
00232   b    &= sizeof(*dest) * 8 - 1;   /* modulo; cut off all upper bits */
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   /* Return old bit */
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   /* Return old bit */
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; /* Grmbl: adapt to x86 implementation... */
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 /* ! __L4UTIL__INCLUDE__BITOPS_H__ */

L4 Utilities, part of DROPS  © 2000-2003