83 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef _ASM_GENERIC_BITOPS_LOCK_H_3#define _ASM_GENERIC_BITOPS_LOCK_H_4 5#include <linux/atomic.h>6#include <linux/compiler.h>7#include <asm/barrier.h>8 9/**10 * arch_test_and_set_bit_lock - Set a bit and return its old value, for lock11 * @nr: Bit to set12 * @addr: Address to count from13 *14 * This operation is atomic and provides acquire barrier semantics if15 * the returned value is 0.16 * It can be used to implement bit locks.17 */18static __always_inline int19arch_test_and_set_bit_lock(unsigned int nr, volatile unsigned long *p)20{21 long old;22 unsigned long mask = BIT_MASK(nr);23 24 p += BIT_WORD(nr);25 if (READ_ONCE(*p) & mask)26 return 1;27 28 old = raw_atomic_long_fetch_or_acquire(mask, (atomic_long_t *)p);29 return !!(old & mask);30}31 32 33/**34 * arch_clear_bit_unlock - Clear a bit in memory, for unlock35 * @nr: the bit to set36 * @addr: the address to start counting from37 *38 * This operation is atomic and provides release barrier semantics.39 */40static __always_inline void41arch_clear_bit_unlock(unsigned int nr, volatile unsigned long *p)42{43 p += BIT_WORD(nr);44 raw_atomic_long_fetch_andnot_release(BIT_MASK(nr), (atomic_long_t *)p);45}46 47/**48 * arch___clear_bit_unlock - Clear a bit in memory, for unlock49 * @nr: the bit to set50 * @addr: the address to start counting from51 *52 * A weaker form of clear_bit_unlock() as used by __bit_lock_unlock(). If all53 * the bits in the word are protected by this lock some archs can use weaker54 * ops to safely unlock.55 *56 * See for example x86's implementation.57 */58static inline void59arch___clear_bit_unlock(unsigned int nr, volatile unsigned long *p)60{61 unsigned long old;62 63 p += BIT_WORD(nr);64 old = READ_ONCE(*p);65 old &= ~BIT_MASK(nr);66 raw_atomic_long_set_release((atomic_long_t *)p, old);67}68 69#ifndef arch_xor_unlock_is_negative_byte70static inline bool arch_xor_unlock_is_negative_byte(unsigned long mask,71 volatile unsigned long *p)72{73 long old;74 75 old = raw_atomic_long_fetch_xor_release(mask, (atomic_long_t *)p);76 return !!(old & BIT(7));77}78#endif79 80#include <asm-generic/bitops/instrumented-lock.h>81 82#endif /* _ASM_GENERIC_BITOPS_LOCK_H_ */83