What is the return value of test_bit() in <asm/bitops.h> on x86_64?

Le Tan tamlokveer at gmail.com
Wed Dec 9 21:20:32 EST 2015


Hi,
I was shocked when I found that `test_bit()` will return -1 or 0 to denote
whether a bit is set or not in a bitmap.
Looking at its implementation here:
```
static __always_inline int constant_test_bit(long nr, const volatile
unsigned long *addr)
{
        return ((1UL << (nr & (BITS_PER_LONG-1))) &
                (addr[nr >> _BITOPS_LONG_SHIFT])) != 0;
}

static inline int variable_test_bit(long nr, volatile const unsigned long
*addr)
{
        int oldbit;

        asm volatile("bt %2,%1\n\t"
                     "sbb %0,%0"
                     : "=r" (oldbit)
                     : "m" (*(unsigned long *)addr), "Ir" (nr));

        return oldbit;
}
```
The sbb instruction will let `det = dst - (src + CF)`. So it seems that
test_bit() will return -1 if a bit is set? And it seems to work that way in
my project.

However, when I wrote another toy function to test it, I saw that it will
return 1 for those bits set.
```
#define TEST_MAX_BITS 512

static void rr_unit_test(struct kvm_vcpu *vcpu)
{
static u64 counter = 0;
int ret;
DECLARE_BITMAP(test_map, TEST_MAX_BITS);
u64 nr;

if (vcpu->vcpu_id != 0)
return;
if (counter == 0) {
++counter;
bitmap_zero(test_map, TEST_MAX_BITS);
ret = test_bit(5, test_map);
printk(KERN_INFO "vcpu=%d ret=%d\n", vcpu->vcpu_id, ret);
set_bit(5, test_map);
ret = test_bit(5, test_map);
printk(KERN_INFO "vcpu=%d ret=%d\n", vcpu->vcpu_id, ret);
ret = test_bit(6, test_map);
printk(KERN_INFO "vcpu=%d ret=%d\n", vcpu->vcpu_id, ret);
ret = test_bit(512, test_map);
printk(KERN_INFO "vcpu=%d ret=%d\n", vcpu->vcpu_id, ret);
set_bit(512, test_map);
ret = test_bit(512, test_map);
printk(KERN_INFO "vcpu=%d ret=%d\n", vcpu->vcpu_id, ret);
nr = 448;
ret = test_bit(nr, test_map);
printk(KERN_INFO "vcpu=%d ret=%d\n", vcpu->vcpu_id, ret);
set_bit(nr, test_map);
ret = test_bit(nr, test_map);
printk(KERN_INFO "vcpu=%d ret=%d\n", vcpu->vcpu_id, ret);
}
}
```
So why will test_bit() behave differently?
Thanks very much!

Regards,
Le Tan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20151210/e240b51f/attachment.html 


More information about the Kernelnewbies mailing list