1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /******************************************************************************
3  *
4  *   Copyright © International Business Machines  Corp., 2009
5  *
6  * DESCRIPTION
7  *      GCC atomic builtin wrappers
8  *      http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
9  *
10  * AUTHOR
11  *      Darren Hart <dvhart@linux.intel.com>
12  *
13  * HISTORY
14  *      2009-Nov-17: Initial version by Darren Hart <dvhart@linux.intel.com>
15  *
16  *****************************************************************************/
17 
18 #ifndef _ATOMIC_H
19 #define _ATOMIC_H
20 
21 typedef struct {
22 	volatile int val;
23 } atomic_t;
24 
25 #define ATOMIC_INITIALIZER { 0 }
26 
27 /**
28  * atomic_cmpxchg() - Atomic compare and exchange
29  * @uaddr:	The address of the futex to be modified
30  * @oldval:	The expected value of the futex
31  * @newval:	The new value to try and assign the futex
32  *
33  * Return the old value of addr->val.
34  */
35 static inline int
atomic_cmpxchg(atomic_t * addr,int oldval,int newval)36 atomic_cmpxchg(atomic_t *addr, int oldval, int newval)
37 {
38 	return __sync_val_compare_and_swap(&addr->val, oldval, newval);
39 }
40 
41 /**
42  * atomic_inc() - Atomic incrememnt
43  * @addr:	Address of the variable to increment
44  *
45  * Return the new value of addr->val.
46  */
47 static inline int
atomic_inc(atomic_t * addr)48 atomic_inc(atomic_t *addr)
49 {
50 	return __sync_add_and_fetch(&addr->val, 1);
51 }
52 
53 /**
54  * atomic_dec() - Atomic decrement
55  * @addr:	Address of the variable to decrement
56  *
57  * Return the new value of addr-val.
58  */
59 static inline int
atomic_dec(atomic_t * addr)60 atomic_dec(atomic_t *addr)
61 {
62 	return __sync_sub_and_fetch(&addr->val, 1);
63 }
64 
65 /**
66  * atomic_set() - Atomic set
67  * @addr:	Address of the variable to set
68  * @newval:	New value for the atomic_t
69  *
70  * Return the new value of addr->val.
71  */
72 static inline int
atomic_set(atomic_t * addr,int newval)73 atomic_set(atomic_t *addr, int newval)
74 {
75 	addr->val = newval;
76 	return newval;
77 }
78 
79 #endif
80