~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/loongarch/include/asm/local.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /*
  3  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  4  */
  5 #ifndef _ARCH_LOONGARCH_LOCAL_H
  6 #define _ARCH_LOONGARCH_LOCAL_H
  7 
  8 #include <linux/percpu.h>
  9 #include <linux/bitops.h>
 10 #include <linux/atomic.h>
 11 #include <asm/cmpxchg.h>
 12 
 13 typedef struct {
 14         atomic_long_t a;
 15 } local_t;
 16 
 17 #define LOCAL_INIT(i)   { ATOMIC_LONG_INIT(i) }
 18 
 19 #define local_read(l)   atomic_long_read(&(l)->a)
 20 #define local_set(l, i) atomic_long_set(&(l)->a, (i))
 21 
 22 #define local_add(i, l) atomic_long_add((i), (&(l)->a))
 23 #define local_sub(i, l) atomic_long_sub((i), (&(l)->a))
 24 #define local_inc(l)    atomic_long_inc(&(l)->a)
 25 #define local_dec(l)    atomic_long_dec(&(l)->a)
 26 
 27 /*
 28  * Same as above, but return the result value
 29  */
 30 static inline long local_add_return(long i, local_t *l)
 31 {
 32         unsigned long result;
 33 
 34         __asm__ __volatile__(
 35         "   " __AMADD " %1, %2, %0      \n"
 36         : "+ZB" (l->a.counter), "=&r" (result)
 37         : "r" (i)
 38         : "memory");
 39         result = result + i;
 40 
 41         return result;
 42 }
 43 
 44 static inline long local_sub_return(long i, local_t *l)
 45 {
 46         unsigned long result;
 47 
 48         __asm__ __volatile__(
 49         "   " __AMADD "%1, %2, %0       \n"
 50         : "+ZB" (l->a.counter), "=&r" (result)
 51         : "r" (-i)
 52         : "memory");
 53 
 54         result = result - i;
 55 
 56         return result;
 57 }
 58 
 59 static inline long local_cmpxchg(local_t *l, long old, long new)
 60 {
 61         return cmpxchg_local(&l->a.counter, old, new);
 62 }
 63 
 64 static inline bool local_try_cmpxchg(local_t *l, long *old, long new)
 65 {
 66         return try_cmpxchg_local(&l->a.counter,
 67                                  (typeof(l->a.counter) *) old, new);
 68 }
 69 
 70 #define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
 71 
 72 /**
 73  * local_add_unless - add unless the number is already a given value
 74  * @l: pointer of type local_t
 75  * @a: the amount to add to l...
 76  * @u: ...unless l is equal to u.
 77  *
 78  * Atomically adds @a to @l, if @v was not already @u.
 79  * Returns true if the addition was done.
 80  */
 81 static inline bool
 82 local_add_unless(local_t *l, long a, long u)
 83 {
 84         long c = local_read(l);
 85 
 86         do {
 87                 if (unlikely(c == u))
 88                         return false;
 89         } while (!local_try_cmpxchg(l, &c, c + a));
 90 
 91         return true;
 92 }
 93 
 94 #define local_inc_not_zero(l) local_add_unless((l), 1, 0)
 95 
 96 #define local_dec_return(l) local_sub_return(1, (l))
 97 #define local_inc_return(l) local_add_return(1, (l))
 98 
 99 /*
100  * local_sub_and_test - subtract value from variable and test result
101  * @i: integer value to subtract
102  * @l: pointer of type local_t
103  *
104  * Atomically subtracts @i from @l and returns
105  * true if the result is zero, or false for all
106  * other cases.
107  */
108 #define local_sub_and_test(i, l) (local_sub_return((i), (l)) == 0)
109 
110 /*
111  * local_inc_and_test - increment and test
112  * @l: pointer of type local_t
113  *
114  * Atomically increments @l by 1
115  * and returns true if the result is zero, or false for all
116  * other cases.
117  */
118 #define local_inc_and_test(l) (local_inc_return(l) == 0)
119 
120 /*
121  * local_dec_and_test - decrement by 1 and test
122  * @l: pointer of type local_t
123  *
124  * Atomically decrements @l by 1 and
125  * returns true if the result is 0, or false for all other
126  * cases.
127  */
128 #define local_dec_and_test(l) (local_sub_return(1, (l)) == 0)
129 
130 /*
131  * local_add_negative - add and test if negative
132  * @l: pointer of type local_t
133  * @i: integer value to add
134  *
135  * Atomically adds @i to @l and returns true
136  * if the result is negative, or false when
137  * result is greater than or equal to zero.
138  */
139 #define local_add_negative(i, l) (local_add_return(i, (l)) < 0)
140 
141 /* Use these for per-cpu local_t variables: on some archs they are
142  * much more efficient than these naive implementations.  Note they take
143  * a variable, not an address.
144  */
145 
146 #define __local_inc(l)          ((l)->a.counter++)
147 #define __local_dec(l)          ((l)->a.counter++)
148 #define __local_add(i, l)       ((l)->a.counter += (i))
149 #define __local_sub(i, l)       ((l)->a.counter -= (i))
150 
151 #endif /* _ARCH_LOONGARCH_LOCAL_H */
152 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php