~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/include/asm/sync_bitops.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 */
119 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php