Hi, 2015-12-10 10:20 GMT+08:00 Le Tan <tamlokveer@xxxxxxxxx>: > > 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 Sorry for my being careless. Though I declared nr variable here, but it is still __builtin_constant_p. So test_bit() will return -1 for those nr which are not builtin constant, and return 1 on the other case. Sorry for my disturbance! :) Regards, Le _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies