1
0
mirror of https://github.com/ioacademy-jikim/device_driver synced 2025-06-07 07:56:08 +00:00
ioacademy-jikim e92d98c6d0 first sample
2015-08-19 19:26:23 +09:00

78 lines
1.5 KiB
C

#include <stdio.h>
#define BITS_PER_LONG 64
#define ffz(x) __ffs(~(x))
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
static __always_inline unsigned long __ffs(unsigned long word)
{
int num = 0;
#if BITS_PER_LONG == 64
if ((word & 0xffffffff) == 0) {
num += 32;
word >>= 32;
}
#endif
if ((word & 0xffff) == 0) {
num += 16;
word >>= 16;
}
if ((word & 0xff) == 0) {
num += 8;
word >>= 8;
}
if ((word & 0xf) == 0) {
num += 4;
word >>= 4;
}
if ((word & 0x3) == 0) {
num += 2;
word >>= 2;
}
if ((word & 0x1) == 0)
num += 1;
return num;
}
static inline void set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long flags;
*p |= mask;
}
unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
{
const unsigned long *p = addr;
unsigned long result = 0;
unsigned long tmp;
while (size & ~(BITS_PER_LONG-1)) {
if (~(tmp = *(p++)))
goto found;
result += BITS_PER_LONG;
size -= BITS_PER_LONG;
}
if (!size)
return result;
tmp = (*p) | (~0UL << size);
if (tmp == ~0UL) /* Are any bits zero? */
return result + size; /* Nope. */
found:
return result + ffz(tmp);
}
int main()
{
unsigned long a[1] = {0x0UL};
unsigned long index;
index = find_first_zero_bit(a, 64);
printf("%lu\n", 64-index-1 );
set_bit( 0, a );
index = find_first_zero_bit(a, 64);
printf("%lu\n", 64-index-1 );
return 0;
}