linux/include/asm-generic/bitops/instrumented-non-atomic.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2
   3/*
   4 * This file provides wrappers with sanitizer instrumentation for non-atomic
   5 * bit operations.
   6 *
   7 * To use this functionality, an arch's bitops.h file needs to define each of
   8 * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
   9 * arch___set_bit(), etc.).
  10 */
  11#ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
  12#define _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
  13
  14#include <linux/instrumented.h>
  15
  16/**
  17 * __set_bit - Set a bit in memory
  18 * @nr: the bit to set
  19 * @addr: the address to start counting from
  20 *
  21 * Unlike set_bit(), this function is non-atomic. If it is called on the same
  22 * region of memory concurrently, the effect may be that only one operation
  23 * succeeds.
  24 */
  25static inline void __set_bit(long nr, volatile unsigned long *addr)
  26{
  27        instrument_write(addr + BIT_WORD(nr), sizeof(long));
  28        arch___set_bit(nr, addr);
  29}
  30
  31/**
  32 * __clear_bit - Clears a bit in memory
  33 * @nr: the bit to clear
  34 * @addr: the address to start counting from
  35 *
  36 * Unlike clear_bit(), this function is non-atomic. If it is called on the same
  37 * region of memory concurrently, the effect may be that only one operation
  38 * succeeds.
  39 */
  40static inline void __clear_bit(long nr, volatile unsigned long *addr)
  41{
  42        instrument_write(addr + BIT_WORD(nr), sizeof(long));
  43        arch___clear_bit(nr, addr);
  44}
  45
  46/**
  47 * __change_bit - Toggle a bit in memory
  48 * @nr: the bit to change
  49 * @addr: the address to start counting from
  50 *
  51 * Unlike change_bit(), this function is non-atomic. If it is called on the same
  52 * region of memory concurrently, the effect may be that only one operation
  53 * succeeds.
  54 */
  55static inline void __change_bit(long nr, volatile unsigned long *addr)
  56{
  57        instrument_write(addr + BIT_WORD(nr), sizeof(long));
  58        arch___change_bit(nr, addr);
  59}
  60
  61/**
  62 * __test_and_set_bit - Set a bit and return its old value
  63 * @nr: Bit to set
  64 * @addr: Address to count from
  65 *
  66 * This operation is non-atomic. If two instances of this operation race, one
  67 * can appear to succeed but actually fail.
  68 */
  69static inline bool __test_and_set_bit(long nr, volatile unsigned long *addr)
  70{
  71        instrument_write(addr + BIT_WORD(nr), sizeof(long));
  72        return arch___test_and_set_bit(nr, addr);
  73}
  74
  75/**
  76 * __test_and_clear_bit - Clear a bit and return its old value
  77 * @nr: Bit to clear
  78 * @addr: Address to count from
  79 *
  80 * This operation is non-atomic. If two instances of this operation race, one
  81 * can appear to succeed but actually fail.
  82 */
  83static inline bool __test_and_clear_bit(long nr, volatile unsigned long *addr)
  84{
  85        instrument_write(addr + BIT_WORD(nr), sizeof(long));
  86        return arch___test_and_clear_bit(nr, addr);
  87}
  88
  89/**
  90 * __test_and_change_bit - Change a bit and return its old value
  91 * @nr: Bit to change
  92 * @addr: Address to count from
  93 *
  94 * This operation is non-atomic. If two instances of this operation race, one
  95 * can appear to succeed but actually fail.
  96 */
  97static inline bool __test_and_change_bit(long nr, volatile unsigned long *addr)
  98{
  99        instrument_write(addr + BIT_WORD(nr), sizeof(long));
 100        return arch___test_and_change_bit(nr, addr);
 101}
 102
 103/**
 104 * test_bit - Determine whether a bit is set
 105 * @nr: bit number to test
 106 * @addr: Address to start counting from
 107 */
 108static inline bool test_bit(long nr, const volatile unsigned long *addr)
 109{
 110        instrument_atomic_read(addr + BIT_WORD(nr), sizeof(long));
 111        return arch_test_bit(nr, addr);
 112}
 113
 114#endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H */
 115