Loading...
Searching...
No Matches
bitops.h
Go to the documentation of this file.
/*****************************************************************************/
/*
* (c) 2000-2009 Author(s)
* economic rights: Technische Universität Dresden (Germany)
* License: see LICENSE.spdx (in this directory or the directories above)
*/
/*****************************************************************************/
#ifndef __L4UTIL__INCLUDE__BITOPS_H__
#define __L4UTIL__INCLUDE__BITOPS_H__
/* L4 includes */
#include <l4/sys/l4int.h>
#include <l4/sys/compiler.h>
#define l4util_test_and_clear_bit(b, dest) l4util_btr(b, dest)
#define l4util_test_and_set_bit(b, dest) l4util_bts(b, dest)
#define l4util_test_and_change_bit(b, dest) l4util_btc(b, dest)
#define l4util_log2(word) l4util_bsr(word)
/*****************************************************************************
*** Prototypes
*****************************************************************************/
L4_BEGIN_DECLS
L4_INLINE void
l4util_set_bit(int b, volatile l4_umword_t * dest);
L4_INLINE void
l4util_clear_bit(int b, volatile l4_umword_t * dest);
L4_INLINE void
l4util_complement_bit(int b, volatile l4_umword_t * dest);
L4_INLINE int
l4util_test_bit(int b, const volatile l4_umword_t * dest);
L4_INLINE int
l4util_bts(int b, volatile l4_umword_t * dest);
L4_INLINE int
l4util_btr(int b, volatile l4_umword_t * dest);
L4_INLINE int
l4util_btc(int b, volatile l4_umword_t * dest);
L4_INLINE int
l4util_bsr(l4_umword_t word);
L4_INLINE int
l4util_bsf(l4_umword_t word);
L4_INLINE int
l4util_find_first_set_bit(const void * dest, l4_size_t size);
L4_INLINE int
l4util_find_first_zero_bit(const void * dest, l4_size_t size);
L4_INLINE int
l4util_next_power2(unsigned long val);
L4_END_DECLS
/*****************************************************************************
*** Implementation of specific version
*****************************************************************************/
#include <l4/util/bitops_arch.h>
/*****************************************************************************
*** Generic implementations
*****************************************************************************/
#ifndef __L4UTIL_BITOPS_HAVE_ARCH_SET_BIT
#include <l4/util/atomic.h>
L4_INLINE void
l4util_set_bit(int b, volatile l4_umword_t * dest)
{
l4_umword_t oldval, newval;
dest += b / (sizeof(*dest) * 8); /* advance dest to the proper element */
b &= sizeof(*dest) * 8 - 1; /* modulo; cut off all upper bits */
do
{
oldval = *dest;
newval = oldval | (1UL << b);
}
while (!l4util_cmpxchg(dest, oldval, newval));
}
#endif
#ifndef __L4UTIL_BITOPS_HAVE_ARCH_CLEAR_BIT
#include <l4/util/atomic.h>
L4_INLINE void
l4util_clear_bit(int b, volatile l4_umword_t * dest)
{
l4_umword_t oldval, newval;
dest += b / (sizeof(*dest) * 8);
b &= sizeof(*dest) * 8 - 1;
do
{
oldval = *dest;
newval = oldval & ~(1UL << b);
}
while (!l4util_cmpxchg(dest, oldval, newval));
}
#endif
#ifndef __L4UTIL_BITOPS_HAVE_ARCH_TEST_BIT
L4_INLINE int
l4util_test_bit(int b, const volatile l4_umword_t * dest)
{
dest += b / (sizeof(*dest) * 8);
b &= sizeof(*dest) * 8 - 1;
return (*dest >> b) & 1;
}
#endif
#ifndef __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_SET
#include <l4/util/atomic.h>
L4_INLINE int
l4util_bts(int b, volatile l4_umword_t * dest)
{
l4_umword_t oldval, newval;
dest += b / (sizeof(*dest) * 8);
b &= sizeof(*dest) * 8 - 1;
do
{
oldval = *dest;
newval = oldval | (1UL << b);
}
while (!l4util_cmpxchg(dest, oldval, newval));
/* Return old bit */
return (oldval >> b) & 1;
}
#endif
#ifndef __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_RESET
#include <l4/util/atomic.h>
L4_INLINE int
l4util_btr(int b, volatile l4_umword_t * dest)
{
l4_umword_t oldval, newval;
dest += b / (sizeof(*dest) * 8);
b &= sizeof(*dest) * 8 - 1;
do
{
oldval = *dest;
newval = oldval & ~(1UL << b);
}
while (!l4util_cmpxchg(dest, oldval, newval));
/* Return old bit */
return (oldval >> b) & 1;
}
#endif
#ifndef __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_REVERSE
L4_INLINE int
l4util_bsr(l4_umword_t word)
{
int i;
if (!word)
return -1;
for (i = 8 * sizeof(word) - 1; i >= 0; i--)
if ((1UL << i) & word)
return i;
__builtin_unreachable();
}
#endif
#ifndef __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_FORWARD
L4_INLINE int
l4util_bsf(l4_umword_t word)
{
unsigned int i;
if (!word)
return -1;
for (i = 0; i < sizeof(word) * 8; i++)
if ((1UL << i) & word)
return i;
__builtin_unreachable();
}
#endif
#ifndef __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_ZERO_BIT
L4_INLINE int
l4util_find_first_zero_bit(const void * dest, l4_size_t size)
{
l4_size_t i, j;
unsigned long *v = (unsigned long*)dest;
if (!size)
return 0;
size = (size + 31) & ~0x1f; /* Grmbl: adapt to x86 implementation... */
for (i = j = 0; i < size; i++, j++)
{
if (j >= sizeof(*v) * 8)
{
j = 0;
v++;
}
if (!((1UL << j) & *v))
return i;
}
return size + 1;
}
#endif
#ifndef __L4UTIL_BITOPS_HAVE_ARCH_COMPLEMENT_BIT
L4_INLINE void
l4util_complement_bit(int b, volatile l4_umword_t * dest)
{
dest += b / (sizeof(*dest) * 8);
b &= sizeof(*dest) * 8 - 1;
*dest ^= 1UL << b;
}
#endif
/*
* Adapted from:
* http://en.wikipedia.org/wiki/Power_of_two#Algorithm_to_find_the_next-highest_power_of_two
*/
L4_INLINE int
l4util_next_power2(unsigned long val)
{
unsigned i;
if (val == 0)
return 1;
val--;
for (i=1; i < sizeof(unsigned long)*8; i<<=1)
val = val | val >> i;
return val+1;
}
/* Non-implemented version, catch with a linker warning */
extern int __this_l4util_bitops_function_is_not_implemented_for_this_arch__sorry(void);
#ifndef __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_COMPLEMENT
L4_INLINE int
l4util_btc(int b, volatile l4_umword_t * dest)
{ (void)b; (void)dest; __this_l4util_bitops_function_is_not_implemented_for_this_arch__sorry(); return 0; }
#endif
#ifndef __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_SET_BIT
L4_INLINE int
l4util_find_first_set_bit(const void * dest, l4_size_t size)
{ (void)dest; (void)size; __this_l4util_bitops_function_is_not_implemented_for_this_arch__sorry(); return 0; }
#endif
#endif /* ! __L4UTIL__INCLUDE__BITOPS_H__ */
compiler.h
L4 compiler related defines.
l4_size_t
unsigned int l4_size_t
Unsigned size type.
Definition l4int.h:24
l4_umword_t
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
L4_INLINE
#define L4_INLINE
L4 Inline function attribute.
Definition compiler.h:51
L4_BEGIN_DECLS
#define L4_BEGIN_DECLS
Start section with C types and functions.
Definition compiler.h:165
L4_END_DECLS
#define L4_END_DECLS
End section with C types and functions.
Definition compiler.h:166
l4util_cmpxchg
int l4util_cmpxchg(volatile l4_umword_t *dest, l4_umword_t cmp_val, l4_umword_t new_val)
Atomic compare and exchange (machine wide fields).
Definition atomic.h:379
l4util_set_bit
void l4util_set_bit(int b, volatile l4_umword_t *dest)
Set bit in memory.
Definition bitops.h:207
l4util_next_power2
int l4util_next_power2(unsigned long val)
Find the next power of 2 for a given number.
Definition bitops.h:373
l4util_bsf
int l4util_bsf(l4_umword_t word)
Bit scan forward.
Definition bitops.h:316
l4util_btc
int l4util_btc(int b, volatile l4_umword_t *dest)
Bit test and complement.
Definition bitops.h:394
l4util_bsr
int l4util_bsr(l4_umword_t word)
Bit scan reverse.
Definition bitops.h:299
l4util_btr
int l4util_btr(int b, volatile l4_umword_t *dest)
Bit test and reset.
Definition bitops.h:278
l4util_find_first_set_bit
int l4util_find_first_set_bit(const void *dest, l4_size_t size)
Find the first set bit in a memory region.
Definition bitops.h:400
l4util_bts
int l4util_bts(int b, volatile l4_umword_t *dest)
Bit test and set.
Definition bitops.h:256
l4util_find_first_zero_bit
int l4util_find_first_zero_bit(const void *dest, l4_size_t size)
Find the first zero bit in a memory region.
Definition bitops.h:333
l4util_clear_bit
void l4util_clear_bit(int b, volatile l4_umword_t *dest)
Clear bit in memory.
Definition bitops.h:226
l4util_test_bit
int l4util_test_bit(int b, const volatile l4_umword_t *dest)
Test bit (return value of bit).
Definition bitops.h:244
l4util_complement_bit
void l4util_complement_bit(int b, volatile l4_umword_t *dest)
Complement bit in memory.
Definition bitops.h:359
l4int.h
Fixed sized integer types, generic version.
atomic.h
atomic operations header and generic implementations