linux/arch/arm64/include/asm/atomic.h
<<
>>
Prefs
   1/*
   2 * Based on arch/arm/include/asm/atomic.h
   3 *
   4 * Copyright (C) 1996 Russell King.
   5 * Copyright (C) 2002 Deep Blue Solutions Ltd.
   6 * Copyright (C) 2012 ARM Ltd.
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19 */
  20#ifndef __ASM_ATOMIC_H
  21#define __ASM_ATOMIC_H
  22
  23#include <linux/compiler.h>
  24#include <linux/types.h>
  25
  26#include <asm/barrier.h>
  27#include <asm/lse.h>
  28
  29#ifdef __KERNEL__
  30
  31#define __ARM64_IN_ATOMIC_IMPL
  32
  33#if defined(CONFIG_ARM64_LSE_ATOMICS) && defined(CONFIG_AS_LSE)
  34#include <asm/atomic_lse.h>
  35#else
  36#include <asm/atomic_ll_sc.h>
  37#endif
  38
  39#undef __ARM64_IN_ATOMIC_IMPL
  40
  41#include <asm/cmpxchg.h>
  42
  43#define ___atomic_add_unless(v, a, u, sfx)                              \
  44({                                                                      \
  45        typeof((v)->counter) c, old;                                    \
  46                                                                        \
  47        c = atomic##sfx##_read(v);                                      \
  48        while (c != (u) &&                                              \
  49              (old = atomic##sfx##_cmpxchg((v), c, c + (a))) != c)      \
  50                c = old;                                                \
  51        c;                                                              \
  52 })
  53
  54#define ATOMIC_INIT(i)  { (i) }
  55
  56#define atomic_read(v)                  READ_ONCE((v)->counter)
  57#define atomic_set(v, i)                WRITE_ONCE(((v)->counter), (i))
  58
  59#define atomic_add_return_relaxed       atomic_add_return_relaxed
  60#define atomic_add_return_acquire       atomic_add_return_acquire
  61#define atomic_add_return_release       atomic_add_return_release
  62#define atomic_add_return               atomic_add_return
  63
  64#define atomic_inc_return_relaxed(v)    atomic_add_return_relaxed(1, (v))
  65#define atomic_inc_return_acquire(v)    atomic_add_return_acquire(1, (v))
  66#define atomic_inc_return_release(v)    atomic_add_return_release(1, (v))
  67#define atomic_inc_return(v)            atomic_add_return(1, (v))
  68
  69#define atomic_sub_return_relaxed       atomic_sub_return_relaxed
  70#define atomic_sub_return_acquire       atomic_sub_return_acquire
  71#define atomic_sub_return_release       atomic_sub_return_release
  72#define atomic_sub_return               atomic_sub_return
  73
  74#define atomic_dec_return_relaxed(v)    atomic_sub_return_relaxed(1, (v))
  75#define atomic_dec_return_acquire(v)    atomic_sub_return_acquire(1, (v))
  76#define atomic_dec_return_release(v)    atomic_sub_return_release(1, (v))
  77#define atomic_dec_return(v)            atomic_sub_return(1, (v))
  78
  79#define atomic_fetch_add_relaxed        atomic_fetch_add_relaxed
  80#define atomic_fetch_add_acquire        atomic_fetch_add_acquire
  81#define atomic_fetch_add_release        atomic_fetch_add_release
  82#define atomic_fetch_add                atomic_fetch_add
  83
  84#define atomic_fetch_sub_relaxed        atomic_fetch_sub_relaxed
  85#define atomic_fetch_sub_acquire        atomic_fetch_sub_acquire
  86#define atomic_fetch_sub_release        atomic_fetch_sub_release
  87#define atomic_fetch_sub                atomic_fetch_sub
  88
  89#define atomic_fetch_and_relaxed        atomic_fetch_and_relaxed
  90#define atomic_fetch_and_acquire        atomic_fetch_and_acquire
  91#define atomic_fetch_and_release        atomic_fetch_and_release
  92#define atomic_fetch_and                atomic_fetch_and
  93
  94#define atomic_fetch_andnot_relaxed     atomic_fetch_andnot_relaxed
  95#define atomic_fetch_andnot_acquire     atomic_fetch_andnot_acquire
  96#define atomic_fetch_andnot_release     atomic_fetch_andnot_release
  97#define atomic_fetch_andnot             atomic_fetch_andnot
  98
  99#define atomic_fetch_or_relaxed         atomic_fetch_or_relaxed
 100#define atomic_fetch_or_acquire         atomic_fetch_or_acquire
 101#define atomic_fetch_or_release         atomic_fetch_or_release
 102#define atomic_fetch_or                 atomic_fetch_or
 103
 104#define atomic_fetch_xor_relaxed        atomic_fetch_xor_relaxed
 105#define atomic_fetch_xor_acquire        atomic_fetch_xor_acquire
 106#define atomic_fetch_xor_release        atomic_fetch_xor_release
 107#define atomic_fetch_xor                atomic_fetch_xor
 108
 109#define atomic_xchg_relaxed(v, new)     xchg_relaxed(&((v)->counter), (new))
 110#define atomic_xchg_acquire(v, new)     xchg_acquire(&((v)->counter), (new))
 111#define atomic_xchg_release(v, new)     xchg_release(&((v)->counter), (new))
 112#define atomic_xchg(v, new)             xchg(&((v)->counter), (new))
 113
 114#define atomic_cmpxchg_relaxed(v, old, new)                             \
 115        cmpxchg_relaxed(&((v)->counter), (old), (new))
 116#define atomic_cmpxchg_acquire(v, old, new)                             \
 117        cmpxchg_acquire(&((v)->counter), (old), (new))
 118#define atomic_cmpxchg_release(v, old, new)                             \
 119        cmpxchg_release(&((v)->counter), (old), (new))
 120#define atomic_cmpxchg(v, old, new)     cmpxchg(&((v)->counter), (old), (new))
 121
 122#define atomic_inc(v)                   atomic_add(1, (v))
 123#define atomic_dec(v)                   atomic_sub(1, (v))
 124#define atomic_inc_and_test(v)          (atomic_inc_return(v) == 0)
 125#define atomic_dec_and_test(v)          (atomic_dec_return(v) == 0)
 126#define atomic_sub_and_test(i, v)       (atomic_sub_return((i), (v)) == 0)
 127#define atomic_add_negative(i, v)       (atomic_add_return((i), (v)) < 0)
 128#define __atomic_add_unless(v, a, u)    ___atomic_add_unless(v, a, u,)
 129#define atomic_andnot                   atomic_andnot
 130
 131/*
 132 * 64-bit atomic operations.
 133 */
 134#define ATOMIC64_INIT                   ATOMIC_INIT
 135#define atomic64_read                   atomic_read
 136#define atomic64_set                    atomic_set
 137
 138#define atomic64_add_return_relaxed     atomic64_add_return_relaxed
 139#define atomic64_add_return_acquire     atomic64_add_return_acquire
 140#define atomic64_add_return_release     atomic64_add_return_release
 141#define atomic64_add_return             atomic64_add_return
 142
 143#define atomic64_inc_return_relaxed(v)  atomic64_add_return_relaxed(1, (v))
 144#define atomic64_inc_return_acquire(v)  atomic64_add_return_acquire(1, (v))
 145#define atomic64_inc_return_release(v)  atomic64_add_return_release(1, (v))
 146#define atomic64_inc_return(v)          atomic64_add_return(1, (v))
 147
 148#define atomic64_sub_return_relaxed     atomic64_sub_return_relaxed
 149#define atomic64_sub_return_acquire     atomic64_sub_return_acquire
 150#define atomic64_sub_return_release     atomic64_sub_return_release
 151#define atomic64_sub_return             atomic64_sub_return
 152
 153#define atomic64_dec_return_relaxed(v)  atomic64_sub_return_relaxed(1, (v))
 154#define atomic64_dec_return_acquire(v)  atomic64_sub_return_acquire(1, (v))
 155#define atomic64_dec_return_release(v)  atomic64_sub_return_release(1, (v))
 156#define atomic64_dec_return(v)          atomic64_sub_return(1, (v))
 157
 158#define atomic64_fetch_add_relaxed      atomic64_fetch_add_relaxed
 159#define atomic64_fetch_add_acquire      atomic64_fetch_add_acquire
 160#define atomic64_fetch_add_release      atomic64_fetch_add_release
 161#define atomic64_fetch_add              atomic64_fetch_add
 162
 163#define atomic64_fetch_sub_relaxed      atomic64_fetch_sub_relaxed
 164#define atomic64_fetch_sub_acquire      atomic64_fetch_sub_acquire
 165#define atomic64_fetch_sub_release      atomic64_fetch_sub_release
 166#define atomic64_fetch_sub              atomic64_fetch_sub
 167
 168#define atomic64_fetch_and_relaxed      atomic64_fetch_and_relaxed
 169#define atomic64_fetch_and_acquire      atomic64_fetch_and_acquire
 170#define atomic64_fetch_and_release      atomic64_fetch_and_release
 171#define atomic64_fetch_and              atomic64_fetch_and
 172
 173#define atomic64_fetch_andnot_relaxed   atomic64_fetch_andnot_relaxed
 174#define atomic64_fetch_andnot_acquire   atomic64_fetch_andnot_acquire
 175#define atomic64_fetch_andnot_release   atomic64_fetch_andnot_release
 176#define atomic64_fetch_andnot           atomic64_fetch_andnot
 177
 178#define atomic64_fetch_or_relaxed       atomic64_fetch_or_relaxed
 179#define atomic64_fetch_or_acquire       atomic64_fetch_or_acquire
 180#define atomic64_fetch_or_release       atomic64_fetch_or_release
 181#define atomic64_fetch_or               atomic64_fetch_or
 182
 183#define atomic64_fetch_xor_relaxed      atomic64_fetch_xor_relaxed
 184#define atomic64_fetch_xor_acquire      atomic64_fetch_xor_acquire
 185#define atomic64_fetch_xor_release      atomic64_fetch_xor_release
 186#define atomic64_fetch_xor              atomic64_fetch_xor
 187
 188#define atomic64_xchg_relaxed           atomic_xchg_relaxed
 189#define atomic64_xchg_acquire           atomic_xchg_acquire
 190#define atomic64_xchg_release           atomic_xchg_release
 191#define atomic64_xchg                   atomic_xchg
 192
 193#define atomic64_cmpxchg_relaxed        atomic_cmpxchg_relaxed
 194#define atomic64_cmpxchg_acquire        atomic_cmpxchg_acquire
 195#define atomic64_cmpxchg_release        atomic_cmpxchg_release
 196#define atomic64_cmpxchg                atomic_cmpxchg
 197
 198#define atomic64_inc(v)                 atomic64_add(1, (v))
 199#define atomic64_dec(v)                 atomic64_sub(1, (v))
 200#define atomic64_inc_and_test(v)        (atomic64_inc_return(v) == 0)
 201#define atomic64_dec_and_test(v)        (atomic64_dec_return(v) == 0)
 202#define atomic64_sub_and_test(i, v)     (atomic64_sub_return((i), (v)) == 0)
 203#define atomic64_add_negative(i, v)     (atomic64_add_return((i), (v)) < 0)
 204#define atomic64_add_unless(v, a, u)    (___atomic_add_unless(v, a, u, 64) != u)
 205#define atomic64_andnot                 atomic64_andnot
 206
 207#define atomic64_inc_not_zero(v)        atomic64_add_unless((v), 1, 0)
 208
 209#endif
 210#endif
 211