Path: blob/master/tools/include/asm-generic/bitops/non-atomic.h
26295 views
/* SPDX-License-Identifier: GPL-2.0 */1#ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_2#define _ASM_GENERIC_BITOPS_NON_ATOMIC_H_34#include <linux/bits.h>56/**7* ___set_bit - Set a bit in memory8* @nr: the bit to set9* @addr: the address to start counting from10*11* Unlike set_bit(), this function is non-atomic and may be reordered.12* If it's called on the same region of memory simultaneously, the effect13* may be that only one operation succeeds.14*/15static __always_inline void16___set_bit(unsigned long nr, volatile unsigned long *addr)17{18unsigned long mask = BIT_MASK(nr);19unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);2021*p |= mask;22}2324static __always_inline void25___clear_bit(unsigned long nr, volatile unsigned long *addr)26{27unsigned long mask = BIT_MASK(nr);28unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);2930*p &= ~mask;31}3233/**34* ___change_bit - Toggle a bit in memory35* @nr: the bit to change36* @addr: the address to start counting from37*38* Unlike change_bit(), this function is non-atomic and may be reordered.39* If it's called on the same region of memory simultaneously, the effect40* may be that only one operation succeeds.41*/42static __always_inline void43___change_bit(unsigned long nr, volatile unsigned long *addr)44{45unsigned long mask = BIT_MASK(nr);46unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);4748*p ^= mask;49}5051/**52* ___test_and_set_bit - Set a bit and return its old value53* @nr: Bit to set54* @addr: Address to count from55*56* This operation is non-atomic and can be reordered.57* If two examples of this operation race, one can appear to succeed58* but actually fail. You must protect multiple accesses with a lock.59*/60static __always_inline bool61___test_and_set_bit(unsigned long nr, volatile unsigned long *addr)62{63unsigned long mask = BIT_MASK(nr);64unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);65unsigned long old = *p;6667*p = old | mask;68return (old & mask) != 0;69}7071/**72* ___test_and_clear_bit - Clear a bit and return its old value73* @nr: Bit to clear74* @addr: Address to count from75*76* This operation is non-atomic and can be reordered.77* If two examples of this operation race, one can appear to succeed78* but actually fail. You must protect multiple accesses with a lock.79*/80static __always_inline bool81___test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)82{83unsigned long mask = BIT_MASK(nr);84unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);85unsigned long old = *p;8687*p = old & ~mask;88return (old & mask) != 0;89}9091/* WARNING: non atomic and it can be reordered! */92static __always_inline bool93___test_and_change_bit(unsigned long nr, volatile unsigned long *addr)94{95unsigned long mask = BIT_MASK(nr);96unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);97unsigned long old = *p;9899*p = old ^ mask;100return (old & mask) != 0;101}102103/**104* _test_bit - Determine whether a bit is set105* @nr: bit number to test106* @addr: Address to start counting from107*/108static __always_inline bool109_test_bit(unsigned long nr, const volatile unsigned long *addr)110{111return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));112}113114#endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */115116117