Linux Audio

Check our new training course

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