162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/******************************************************************************
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci *   Copyright © International Business Machines  Corp., 2009
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * DESCRIPTION
762306a36Sopenharmony_ci *      GCC atomic builtin wrappers
862306a36Sopenharmony_ci *      http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * AUTHOR
1162306a36Sopenharmony_ci *      Darren Hart <dvhart@linux.intel.com>
1262306a36Sopenharmony_ci *
1362306a36Sopenharmony_ci * HISTORY
1462306a36Sopenharmony_ci *      2009-Nov-17: Initial version by Darren Hart <dvhart@linux.intel.com>
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci *****************************************************************************/
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#ifndef _ATOMIC_H
1962306a36Sopenharmony_ci#define _ATOMIC_H
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_citypedef struct {
2262306a36Sopenharmony_ci	volatile int val;
2362306a36Sopenharmony_ci} atomic_t;
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#define ATOMIC_INITIALIZER { 0 }
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/**
2862306a36Sopenharmony_ci * atomic_cmpxchg() - Atomic compare and exchange
2962306a36Sopenharmony_ci * @uaddr:	The address of the futex to be modified
3062306a36Sopenharmony_ci * @oldval:	The expected value of the futex
3162306a36Sopenharmony_ci * @newval:	The new value to try and assign the futex
3262306a36Sopenharmony_ci *
3362306a36Sopenharmony_ci * Return the old value of addr->val.
3462306a36Sopenharmony_ci */
3562306a36Sopenharmony_cistatic inline int
3662306a36Sopenharmony_ciatomic_cmpxchg(atomic_t *addr, int oldval, int newval)
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci	return __sync_val_compare_and_swap(&addr->val, oldval, newval);
3962306a36Sopenharmony_ci}
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/**
4262306a36Sopenharmony_ci * atomic_inc() - Atomic incrememnt
4362306a36Sopenharmony_ci * @addr:	Address of the variable to increment
4462306a36Sopenharmony_ci *
4562306a36Sopenharmony_ci * Return the new value of addr->val.
4662306a36Sopenharmony_ci */
4762306a36Sopenharmony_cistatic inline int
4862306a36Sopenharmony_ciatomic_inc(atomic_t *addr)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	return __sync_add_and_fetch(&addr->val, 1);
5162306a36Sopenharmony_ci}
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/**
5462306a36Sopenharmony_ci * atomic_dec() - Atomic decrement
5562306a36Sopenharmony_ci * @addr:	Address of the variable to decrement
5662306a36Sopenharmony_ci *
5762306a36Sopenharmony_ci * Return the new value of addr-val.
5862306a36Sopenharmony_ci */
5962306a36Sopenharmony_cistatic inline int
6062306a36Sopenharmony_ciatomic_dec(atomic_t *addr)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	return __sync_sub_and_fetch(&addr->val, 1);
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci/**
6662306a36Sopenharmony_ci * atomic_set() - Atomic set
6762306a36Sopenharmony_ci * @addr:	Address of the variable to set
6862306a36Sopenharmony_ci * @newval:	New value for the atomic_t
6962306a36Sopenharmony_ci *
7062306a36Sopenharmony_ci * Return the new value of addr->val.
7162306a36Sopenharmony_ci */
7262306a36Sopenharmony_cistatic inline int
7362306a36Sopenharmony_ciatomic_set(atomic_t *addr, int newval)
7462306a36Sopenharmony_ci{
7562306a36Sopenharmony_ci	addr->val = newval;
7662306a36Sopenharmony_ci	return newval;
7762306a36Sopenharmony_ci}
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci#endif
80