115 lines · 3.1 KB · C
RawDownload
/* SPDX-License-Identifier: GPL-2.0 */#ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_#define _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ #include <linux/bits.h> /** * ___set_bit - Set a bit in memory * @nr: the bit to set * @addr: the address to start counting from * * Unlike set_bit(), this function is non-atomic and may be reordered. * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */static __always_inline void___set_bit(unsigned long nr, volatile unsigned long *addr){	unsigned long mask = BIT_MASK(nr);	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); 	*p  |= mask;} static __always_inline void___clear_bit(unsigned long nr, volatile unsigned long *addr){	unsigned long mask = BIT_MASK(nr);	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); 	*p &= ~mask;} /** * ___change_bit - Toggle a bit in memory * @nr: the bit to change * @addr: the address to start counting from * * Unlike change_bit(), this function is non-atomic and may be reordered. * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */static __always_inline void___change_bit(unsigned long nr, volatile unsigned long *addr){	unsigned long mask = BIT_MASK(nr);	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); 	*p ^= mask;} /** * ___test_and_set_bit - Set a bit and return its old value * @nr: Bit to set * @addr: Address to count from * * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail.  You must protect multiple accesses with a lock. */static __always_inline bool___test_and_set_bit(unsigned long nr, volatile unsigned long *addr){	unsigned long mask = BIT_MASK(nr);	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);	unsigned long old = *p; 	*p = old | mask;	return (old & mask) != 0;} /** * ___test_and_clear_bit - Clear a bit and return its old value * @nr: Bit to clear * @addr: Address to count from * * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail.  You must protect multiple accesses with a lock. */static __always_inline bool___test_and_clear_bit(unsigned long nr, volatile unsigned long *addr){	unsigned long mask = BIT_MASK(nr);	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);	unsigned long old = *p; 	*p = old & ~mask;	return (old & mask) != 0;} /* WARNING: non atomic and it can be reordered! */static __always_inline bool___test_and_change_bit(unsigned long nr, volatile unsigned long *addr){	unsigned long mask = BIT_MASK(nr);	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);	unsigned long old = *p; 	*p = old ^ mask;	return (old & mask) != 0;} /** * _test_bit - Determine whether a bit is set * @nr: bit number to test * @addr: Address to start counting from */static __always_inline bool_test_bit(unsigned long nr, const volatile unsigned long *addr){	return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));} #endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */