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