root/arch/x86/include/asm/sync_bitops.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. sync_set_bit
  2. sync_clear_bit
  3. sync_change_bit
  4. sync_test_and_set_bit
  5. sync_test_and_clear_bit
  6. sync_test_and_change_bit

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 #ifndef _ASM_X86_SYNC_BITOPS_H
   3 #define _ASM_X86_SYNC_BITOPS_H
   4 
   5 /*
   6  * Copyright 1992, Linus Torvalds.
   7  */
   8 
   9 /*
  10  * These have to be done with inline assembly: that way the bit-setting
  11  * is guaranteed to be atomic. All bit operations return 0 if the bit
  12  * was cleared before the operation and != 0 if it was not.
  13  *
  14  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  15  */
  16 
  17 #include <asm/rmwcc.h>
  18 
  19 #define ADDR (*(volatile long *)addr)
  20 
  21 /**
  22  * sync_set_bit - Atomically set a bit in memory
  23  * @nr: the bit to set
  24  * @addr: the address to start counting from
  25  *
  26  * This function is atomic and may not be reordered.  See __set_bit()
  27  * if you do not require the atomic guarantees.
  28  *
  29  * Note that @nr may be almost arbitrarily large; this function is not
  30  * restricted to acting on a single-word quantity.
  31  */
  32 static inline void sync_set_bit(long nr, volatile unsigned long *addr)
  33 {
  34         asm volatile("lock; " __ASM_SIZE(bts) " %1,%0"
  35                      : "+m" (ADDR)
  36                      : "Ir" (nr)
  37                      : "memory");
  38 }
  39 
  40 /**
  41  * sync_clear_bit - Clears a bit in memory
  42  * @nr: Bit to clear
  43  * @addr: Address to start counting from
  44  *
  45  * sync_clear_bit() is atomic and may not be reordered.  However, it does
  46  * not contain a memory barrier, so if it is used for locking purposes,
  47  * you should call smp_mb__before_atomic() and/or smp_mb__after_atomic()
  48  * in order to ensure changes are visible on other processors.
  49  */
  50 static inline void sync_clear_bit(long nr, volatile unsigned long *addr)
  51 {
  52         asm volatile("lock; " __ASM_SIZE(btr) " %1,%0"
  53                      : "+m" (ADDR)
  54                      : "Ir" (nr)
  55                      : "memory");
  56 }
  57 
  58 /**
  59  * sync_change_bit - Toggle a bit in memory
  60  * @nr: Bit to change
  61  * @addr: Address to start counting from
  62  *
  63  * sync_change_bit() is atomic and may not be reordered.
  64  * Note that @nr may be almost arbitrarily large; this function is not
  65  * restricted to acting on a single-word quantity.
  66  */
  67 static inline void sync_change_bit(long nr, volatile unsigned long *addr)
  68 {
  69         asm volatile("lock; " __ASM_SIZE(btc) " %1,%0"
  70                      : "+m" (ADDR)
  71                      : "Ir" (nr)
  72                      : "memory");
  73 }
  74 
  75 /**
  76  * sync_test_and_set_bit - Set a bit and return its old value
  77  * @nr: Bit to set
  78  * @addr: Address to count from
  79  *
  80  * This operation is atomic and cannot be reordered.
  81  * It also implies a memory barrier.
  82  */
  83 static inline bool sync_test_and_set_bit(long nr, volatile unsigned long *addr)
  84 {
  85         return GEN_BINARY_RMWcc("lock; " __ASM_SIZE(bts), *addr, c, "Ir", nr);
  86 }
  87 
  88 /**
  89  * sync_test_and_clear_bit - Clear a bit and return its old value
  90  * @nr: Bit to clear
  91  * @addr: Address to count from
  92  *
  93  * This operation is atomic and cannot be reordered.
  94  * It also implies a memory barrier.
  95  */
  96 static inline int sync_test_and_clear_bit(long nr, volatile unsigned long *addr)
  97 {
  98         return GEN_BINARY_RMWcc("lock; " __ASM_SIZE(btr), *addr, c, "Ir", nr);
  99 }
 100 
 101 /**
 102  * sync_test_and_change_bit - Change a bit and return its old value
 103  * @nr: Bit to change
 104  * @addr: Address to count from
 105  *
 106  * This operation is atomic and cannot be reordered.
 107  * It also implies a memory barrier.
 108  */
 109 static inline int sync_test_and_change_bit(long nr, volatile unsigned long *addr)
 110 {
 111         return GEN_BINARY_RMWcc("lock; " __ASM_SIZE(btc), *addr, c, "Ir", nr);
 112 }
 113 
 114 #define sync_test_bit(nr, addr) test_bit(nr, addr)
 115 
 116 #undef ADDR
 117 
 118 #endif /* _ASM_X86_SYNC_BITOPS_H */

/* [<][>][^][v][top][bottom][index][help] */