1*2874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
22aa8470fSDarren Hart /******************************************************************************
32aa8470fSDarren Hart  *
42aa8470fSDarren Hart  *   Copyright © International Business Machines  Corp., 2009
52aa8470fSDarren Hart  *
62aa8470fSDarren Hart  * DESCRIPTION
72aa8470fSDarren Hart  *      GCC atomic builtin wrappers
82aa8470fSDarren Hart  *      http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
92aa8470fSDarren Hart  *
102aa8470fSDarren Hart  * AUTHOR
112aa8470fSDarren Hart  *      Darren Hart <dvhart@linux.intel.com>
122aa8470fSDarren Hart  *
132aa8470fSDarren Hart  * HISTORY
142aa8470fSDarren Hart  *      2009-Nov-17: Initial version by Darren Hart <dvhart@linux.intel.com>
152aa8470fSDarren Hart  *
162aa8470fSDarren Hart  *****************************************************************************/
172aa8470fSDarren Hart 
182aa8470fSDarren Hart #ifndef _ATOMIC_H
192aa8470fSDarren Hart #define _ATOMIC_H
202aa8470fSDarren Hart 
212aa8470fSDarren Hart typedef struct {
222aa8470fSDarren Hart 	volatile int val;
232aa8470fSDarren Hart } atomic_t;
242aa8470fSDarren Hart 
252aa8470fSDarren Hart #define ATOMIC_INITIALIZER { 0 }
262aa8470fSDarren Hart 
272aa8470fSDarren Hart /**
282aa8470fSDarren Hart  * atomic_cmpxchg() - Atomic compare and exchange
292aa8470fSDarren Hart  * @uaddr:	The address of the futex to be modified
302aa8470fSDarren Hart  * @oldval:	The expected value of the futex
312aa8470fSDarren Hart  * @newval:	The new value to try and assign the futex
322aa8470fSDarren Hart  *
332aa8470fSDarren Hart  * Return the old value of addr->val.
342aa8470fSDarren Hart  */
352aa8470fSDarren Hart static inline int
atomic_cmpxchg(atomic_t * addr,int oldval,int newval)362aa8470fSDarren Hart atomic_cmpxchg(atomic_t *addr, int oldval, int newval)
372aa8470fSDarren Hart {
382aa8470fSDarren Hart 	return __sync_val_compare_and_swap(&addr->val, oldval, newval);
392aa8470fSDarren Hart }
402aa8470fSDarren Hart 
412aa8470fSDarren Hart /**
422aa8470fSDarren Hart  * atomic_inc() - Atomic incrememnt
432aa8470fSDarren Hart  * @addr:	Address of the variable to increment
442aa8470fSDarren Hart  *
452aa8470fSDarren Hart  * Return the new value of addr->val.
462aa8470fSDarren Hart  */
472aa8470fSDarren Hart static inline int
atomic_inc(atomic_t * addr)482aa8470fSDarren Hart atomic_inc(atomic_t *addr)
492aa8470fSDarren Hart {
502aa8470fSDarren Hart 	return __sync_add_and_fetch(&addr->val, 1);
512aa8470fSDarren Hart }
522aa8470fSDarren Hart 
532aa8470fSDarren Hart /**
542aa8470fSDarren Hart  * atomic_dec() - Atomic decrement
552aa8470fSDarren Hart  * @addr:	Address of the variable to decrement
562aa8470fSDarren Hart  *
572aa8470fSDarren Hart  * Return the new value of addr-val.
582aa8470fSDarren Hart  */
592aa8470fSDarren Hart static inline int
atomic_dec(atomic_t * addr)602aa8470fSDarren Hart atomic_dec(atomic_t *addr)
612aa8470fSDarren Hart {
622aa8470fSDarren Hart 	return __sync_sub_and_fetch(&addr->val, 1);
632aa8470fSDarren Hart }
642aa8470fSDarren Hart 
652aa8470fSDarren Hart /**
662aa8470fSDarren Hart  * atomic_set() - Atomic set
672aa8470fSDarren Hart  * @addr:	Address of the variable to set
682aa8470fSDarren Hart  * @newval:	New value for the atomic_t
692aa8470fSDarren Hart  *
702aa8470fSDarren Hart  * Return the new value of addr->val.
712aa8470fSDarren Hart  */
722aa8470fSDarren Hart static inline int
atomic_set(atomic_t * addr,int newval)732aa8470fSDarren Hart atomic_set(atomic_t *addr, int newval)
742aa8470fSDarren Hart {
752aa8470fSDarren Hart 	addr->val = newval;
762aa8470fSDarren Hart 	return newval;
772aa8470fSDarren Hart }
782aa8470fSDarren Hart 
792aa8470fSDarren Hart #endif
80