linux-bk/include/asm-i386/bitops.h
<<
>>
Prefs
   1#ifndef _I386_BITOPS_H
   2#define _I386_BITOPS_H
   3
   4/*
   5 * Copyright 1992, Linus Torvalds.
   6 */
   7
   8#include <linux/config.h>
   9#include <linux/compiler.h>
  10
  11/*
  12 * These have to be done with inline assembly: that way the bit-setting
  13 * is guaranteed to be atomic. All bit operations return 0 if the bit
  14 * was cleared before the operation and != 0 if it was not.
  15 *
  16 * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  17 */
  18
  19#ifdef CONFIG_SMP
  20#define LOCK_PREFIX "lock ; "
  21#else
  22#define LOCK_PREFIX ""
  23#endif
  24
  25#define ADDR (*(volatile long *) addr)
  26
  27/**
  28 * set_bit - Atomically set a bit in memory
  29 * @nr: the bit to set
  30 * @addr: the address to start counting from
  31 *
  32 * This function is atomic and may not be reordered.  See __set_bit()
  33 * if you do not require the atomic guarantees.
  34 * Note that @nr may be almost arbitrarily large; this function is not
  35 * restricted to acting on a single-word quantity.
  36 */
  37static inline void set_bit(int nr, volatile unsigned long * addr)
  38{
  39        __asm__ __volatile__( LOCK_PREFIX
  40                "btsl %1,%0"
  41                :"=m" (ADDR)
  42                :"Ir" (nr));
  43}
  44
  45/**
  46 * __set_bit - Set a bit in memory
  47 * @nr: the bit to set
  48 * @addr: the address to start counting from
  49 *
  50 * Unlike set_bit(), this function is non-atomic and may be reordered.
  51 * If it's called on the same region of memory simultaneously, the effect
  52 * may be that only one operation succeeds.
  53 */
  54static inline void __set_bit(int nr, volatile unsigned long * addr)
  55{
  56        __asm__(
  57                "btsl %1,%0"
  58                :"=m" (ADDR)
  59                :"Ir" (nr));
  60}
  61
  62/**
  63 * clear_bit - Clears a bit in memory
  64 * @nr: Bit to clear
  65 * @addr: Address to start counting from
  66 *
  67 * clear_bit() is atomic and may not be reordered.  However, it does
  68 * not contain a memory barrier, so if it is used for locking purposes,
  69 * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
  70 * in order to ensure changes are visible on other processors.
  71 */
  72static inline void clear_bit(int nr, volatile unsigned long * addr)
  73{
  74        __asm__ __volatile__( LOCK_PREFIX
  75                "btrl %1,%0"
  76                :"=m" (ADDR)
  77                :"Ir" (nr));
  78}
  79
  80static inline void __clear_bit(int nr, volatile unsigned long * addr)
  81{
  82        __asm__ __volatile__(
  83                "btrl %1,%0"
  84                :"=m" (ADDR)
  85                :"Ir" (nr));
  86}
  87#define smp_mb__before_clear_bit()      barrier()
  88#define smp_mb__after_clear_bit()       barrier()
  89
  90/**
  91 * __change_bit - Toggle a bit in memory
  92 * @nr: the bit to change
  93 * @addr: the address to start counting from
  94 *
  95 * Unlike change_bit(), this function is non-atomic and may be reordered.
  96 * If it's called on the same region of memory simultaneously, the effect
  97 * may be that only one operation succeeds.
  98 */
  99static inline void __change_bit(int nr, volatile unsigned long * addr)
 100{
 101        __asm__ __volatile__(
 102                "btcl %1,%0"
 103                :"=m" (ADDR)
 104                :"Ir" (nr));
 105}
 106
 107/**
 108 * change_bit - Toggle a bit in memory
 109 * @nr: Bit to change
 110 * @addr: Address to start counting from
 111 *
 112 * change_bit() is atomic and may not be reordered.
 113 * Note that @nr may be almost arbitrarily large; this function is not
 114 * restricted to acting on a single-word quantity.
 115 */
 116static inline void change_bit(int nr, volatile unsigned long * addr)
 117{
 118        __asm__ __volatile__( LOCK_PREFIX
 119                "btcl %1,%0"
 120                :"=m" (ADDR)
 121                :"Ir" (nr));
 122}
 123
 124/**
 125 * test_and_set_bit - Set a bit and return its old value
 126 * @nr: Bit to set
 127 * @addr: Address to count from
 128 *
 129 * This operation is atomic and cannot be reordered.  
 130 * It also implies a memory barrier.
 131 */
 132static inline int test_and_set_bit(int nr, volatile unsigned long * addr)
 133{
 134        int oldbit;
 135
 136        __asm__ __volatile__( LOCK_PREFIX
 137                "btsl %2,%1\n\tsbbl %0,%0"
 138                :"=r" (oldbit),"=m" (ADDR)
 139                :"Ir" (nr) : "memory");
 140        return oldbit;
 141}
 142
 143/**
 144 * __test_and_set_bit - Set a bit and return its old value
 145 * @nr: Bit to set
 146 * @addr: Address to count from
 147 *
 148 * This operation is non-atomic and can be reordered.  
 149 * If two examples of this operation race, one can appear to succeed
 150 * but actually fail.  You must protect multiple accesses with a lock.
 151 */
 152static inline int __test_and_set_bit(int nr, volatile unsigned long * addr)
 153{
 154        int oldbit;
 155
 156        __asm__(
 157                "btsl %2,%1\n\tsbbl %0,%0"
 158                :"=r" (oldbit),"=m" (ADDR)
 159                :"Ir" (nr));
 160        return oldbit;
 161}
 162
 163/**
 164 * test_and_clear_bit - Clear a bit and return its old value
 165 * @nr: Bit to clear
 166 * @addr: Address to count from
 167 *
 168 * This operation is atomic and cannot be reordered.  
 169 * It also implies a memory barrier.
 170 */
 171static inline int test_and_clear_bit(int nr, volatile unsigned long * addr)
 172{
 173        int oldbit;
 174
 175        __asm__ __volatile__( LOCK_PREFIX
 176                "btrl %2,%1\n\tsbbl %0,%0"
 177                :"=r" (oldbit),"=m" (ADDR)
 178                :"Ir" (nr) : "memory");
 179        return oldbit;
 180}
 181
 182/**
 183 * __test_and_clear_bit - Clear a bit and return its old value
 184 * @nr: Bit to clear
 185 * @addr: Address to count from
 186 *
 187 * This operation is non-atomic and can be reordered.  
 188 * If two examples of this operation race, one can appear to succeed
 189 * but actually fail.  You must protect multiple accesses with a lock.
 190 */
 191static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
 192{
 193        int oldbit;
 194
 195        __asm__(
 196                "btrl %2,%1\n\tsbbl %0,%0"
 197                :"=r" (oldbit),"=m" (ADDR)
 198                :"Ir" (nr));
 199        return oldbit;
 200}
 201
 202/* WARNING: non atomic and it can be reordered! */
 203static inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
 204{
 205        int oldbit;
 206
 207        __asm__ __volatile__(
 208                "btcl %2,%1\n\tsbbl %0,%0"
 209                :"=r" (oldbit),"=m" (ADDR)
 210                :"Ir" (nr) : "memory");
 211        return oldbit;
 212}
 213
 214/**
 215 * test_and_change_bit - Change a bit and return its old value
 216 * @nr: Bit to change
 217 * @addr: Address to count from
 218 *
 219 * This operation is atomic and cannot be reordered.  
 220 * It also implies a memory barrier.
 221 */
 222static inline int test_and_change_bit(int nr, volatile unsigned long* addr)
 223{
 224        int oldbit;
 225
 226        __asm__ __volatile__( LOCK_PREFIX
 227                "btcl %2,%1\n\tsbbl %0,%0"
 228                :"=r" (oldbit),"=m" (ADDR)
 229                :"Ir" (nr) : "memory");
 230        return oldbit;
 231}
 232
 233#if 0 /* Fool kernel-doc since it doesn't do macros yet */
 234/**
 235 * test_bit - Determine whether a bit is set
 236 * @nr: bit number to test
 237 * @addr: Address to start counting from
 238 */
 239static int test_bit(int nr, const volatile void * addr);
 240#endif
 241
 242static inline int constant_test_bit(int nr, const volatile unsigned long *addr)
 243{
 244        return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0;
 245}
 246
 247static inline int variable_test_bit(int nr, const volatile unsigned long * addr)
 248{
 249        int oldbit;
 250
 251        __asm__ __volatile__(
 252                "btl %2,%1\n\tsbbl %0,%0"
 253                :"=r" (oldbit)
 254                :"m" (ADDR),"Ir" (nr));
 255        return oldbit;
 256}
 257
 258#define test_bit(nr,addr) \
 259(__builtin_constant_p(nr) ? \
 260 constant_test_bit((nr),(addr)) : \
 261 variable_test_bit((nr),(addr)))
 262
 263#undef ADDR
 264
 265/**
 266 * find_first_zero_bit - find the first zero bit in a memory region
 267 * @addr: The address to start the search at
 268 * @size: The maximum size to search
 269 *
 270 * Returns the bit-number of the first zero bit, not the number of the byte
 271 * containing a bit.
 272 */
 273static inline int find_first_zero_bit(const unsigned long *addr, unsigned size)
 274{
 275        int d0, d1, d2;
 276        int res;
 277
 278        if (!size)
 279                return 0;
 280        /* This looks at memory. Mark it volatile to tell gcc not to move it around */
 281        __asm__ __volatile__(
 282                "movl $-1,%%eax\n\t"
 283                "xorl %%edx,%%edx\n\t"
 284                "repe; scasl\n\t"
 285                "je 1f\n\t"
 286                "xorl -4(%%edi),%%eax\n\t"
 287                "subl $4,%%edi\n\t"
 288                "bsfl %%eax,%%edx\n"
 289                "1:\tsubl %%ebx,%%edi\n\t"
 290                "shll $3,%%edi\n\t"
 291                "addl %%edi,%%edx"
 292                :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
 293                :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory");
 294        return res;
 295}
 296
 297/**
 298 * find_next_zero_bit - find the first zero bit in a memory region
 299 * @addr: The address to base the search on
 300 * @offset: The bitnumber to start searching at
 301 * @size: The maximum size to search
 302 */
 303int find_next_zero_bit(const unsigned long *addr, int size, int offset);
 304
 305/**
 306 * find_first_bit - find the first set bit in a memory region
 307 * @addr: The address to start the search at
 308 * @size: The maximum size to search
 309 *
 310 * Returns the bit-number of the first set bit, not the number of the byte
 311 * containing a bit.
 312 */
 313static inline int find_first_bit(const unsigned long *addr, unsigned size)
 314{
 315        int d0, d1;
 316        int res;
 317
 318        /* This looks at memory. Mark it volatile to tell gcc not to move it around */
 319        __asm__ __volatile__(
 320                "xorl %%eax,%%eax\n\t"
 321                "repe; scasl\n\t"
 322                "jz 1f\n\t"
 323                "leal -4(%%edi),%%edi\n\t"
 324                "bsfl (%%edi),%%eax\n"
 325                "1:\tsubl %%ebx,%%edi\n\t"
 326                "shll $3,%%edi\n\t"
 327                "addl %%edi,%%eax"
 328                :"=a" (res), "=&c" (d0), "=&D" (d1)
 329                :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory");
 330        return res;
 331}
 332
 333/**
 334 * find_next_bit - find the first set bit in a memory region
 335 * @addr: The address to base the search on
 336 * @offset: The bitnumber to start searching at
 337 * @size: The maximum size to search
 338 */
 339int find_next_bit(const unsigned long *addr, int size, int offset);
 340
 341/**
 342 * ffz - find first zero in word.
 343 * @word: The word to search
 344 *
 345 * Undefined if no zero exists, so code should check against ~0UL first.
 346 */
 347static inline unsigned long ffz(unsigned long word)
 348{
 349        __asm__("bsfl %1,%0"
 350                :"=r" (word)
 351                :"r" (~word));
 352        return word;
 353}
 354
 355/**
 356 * __ffs - find first bit in word.
 357 * @word: The word to search
 358 *
 359 * Undefined if no bit exists, so code should check against 0 first.
 360 */
 361static inline unsigned long __ffs(unsigned long word)
 362{
 363        __asm__("bsfl %1,%0"
 364                :"=r" (word)
 365                :"rm" (word));
 366        return word;
 367}
 368
 369/*
 370 * fls: find last bit set.
 371 */
 372
 373#define fls(x) generic_fls(x)
 374
 375#ifdef __KERNEL__
 376
 377/*
 378 * Every architecture must define this function. It's the fastest
 379 * way of searching a 140-bit bitmap where the first 100 bits are
 380 * unlikely to be set. It's guaranteed that at least one of the 140
 381 * bits is cleared.
 382 */
 383static inline int sched_find_first_bit(const unsigned long *b)
 384{
 385        if (unlikely(b[0]))
 386                return __ffs(b[0]);
 387        if (unlikely(b[1]))
 388                return __ffs(b[1]) + 32;
 389        if (unlikely(b[2]))
 390                return __ffs(b[2]) + 64;
 391        if (b[3])
 392                return __ffs(b[3]) + 96;
 393        return __ffs(b[4]) + 128;
 394}
 395
 396/**
 397 * ffs - find first bit set
 398 * @x: the word to search
 399 *
 400 * This is defined the same way as
 401 * the libc and compiler builtin ffs routines, therefore
 402 * differs in spirit from the above ffz (man ffs).
 403 */
 404static inline int ffs(int x)
 405{
 406        int r;
 407
 408        __asm__("bsfl %1,%0\n\t"
 409                "jnz 1f\n\t"
 410                "movl $-1,%0\n"
 411                "1:" : "=r" (r) : "rm" (x));
 412        return r+1;
 413}
 414
 415/**
 416 * hweightN - returns the hamming weight of a N-bit word
 417 * @x: the word to weigh
 418 *
 419 * The Hamming Weight of a number is the total number of bits set in it.
 420 */
 421
 422#define hweight32(x) generic_hweight32(x)
 423#define hweight16(x) generic_hweight16(x)
 424#define hweight8(x) generic_hweight8(x)
 425
 426#endif /* __KERNEL__ */
 427
 428#ifdef __KERNEL__
 429
 430#define ext2_set_bit(nr,addr) \
 431        __test_and_set_bit((nr),(unsigned long*)addr)
 432#define ext2_set_bit_atomic(lock,nr,addr) \
 433        test_and_set_bit((nr),(unsigned long*)addr)
 434#define ext2_clear_bit(nr, addr) \
 435        __test_and_clear_bit((nr),(unsigned long*)addr)
 436#define ext2_clear_bit_atomic(lock,nr, addr) \
 437                test_and_clear_bit((nr),(unsigned long*)addr)
 438#define ext2_test_bit(nr, addr)      test_bit((nr),(unsigned long*)addr)
 439#define ext2_find_first_zero_bit(addr, size) \
 440        find_first_zero_bit((unsigned long*)addr, size)
 441#define ext2_find_next_zero_bit(addr, size, off) \
 442        find_next_zero_bit((unsigned long*)addr, size, off)
 443
 444/* Bitmap functions for the minix filesystem.  */
 445#define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,(void*)addr)
 446#define minix_set_bit(nr,addr) __set_bit(nr,(void*)addr)
 447#define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,(void*)addr)
 448#define minix_test_bit(nr,addr) test_bit(nr,(void*)addr)
 449#define minix_find_first_zero_bit(addr,size) \
 450        find_first_zero_bit((void*)addr,size)
 451
 452#endif /* __KERNEL__ */
 453
 454#endif /* _I386_BITOPS_H */
 455
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.