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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux