18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __TOOLS_ASM_GENERIC_ATOMIC_H 38c2ecf20Sopenharmony_ci#define __TOOLS_ASM_GENERIC_ATOMIC_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/compiler.h> 68c2ecf20Sopenharmony_ci#include <linux/types.h> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci/* 98c2ecf20Sopenharmony_ci * Atomic operations that C can't guarantee us. Useful for 108c2ecf20Sopenharmony_ci * resource counting etc.. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * Excerpts obtained from the Linux kernel sources. 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#define ATOMIC_INIT(i) { (i) } 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/** 188c2ecf20Sopenharmony_ci * atomic_read - read atomic variable 198c2ecf20Sopenharmony_ci * @v: pointer of type atomic_t 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * Atomically reads the value of @v. 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_cistatic inline int atomic_read(const atomic_t *v) 248c2ecf20Sopenharmony_ci{ 258c2ecf20Sopenharmony_ci return READ_ONCE((v)->counter); 268c2ecf20Sopenharmony_ci} 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci/** 298c2ecf20Sopenharmony_ci * atomic_set - set atomic variable 308c2ecf20Sopenharmony_ci * @v: pointer of type atomic_t 318c2ecf20Sopenharmony_ci * @i: required value 328c2ecf20Sopenharmony_ci * 338c2ecf20Sopenharmony_ci * Atomically sets the value of @v to @i. 348c2ecf20Sopenharmony_ci */ 358c2ecf20Sopenharmony_cistatic inline void atomic_set(atomic_t *v, int i) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci v->counter = i; 388c2ecf20Sopenharmony_ci} 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/** 418c2ecf20Sopenharmony_ci * atomic_inc - increment atomic variable 428c2ecf20Sopenharmony_ci * @v: pointer of type atomic_t 438c2ecf20Sopenharmony_ci * 448c2ecf20Sopenharmony_ci * Atomically increments @v by 1. 458c2ecf20Sopenharmony_ci */ 468c2ecf20Sopenharmony_cistatic inline void atomic_inc(atomic_t *v) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci __sync_add_and_fetch(&v->counter, 1); 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci/** 528c2ecf20Sopenharmony_ci * atomic_dec_and_test - decrement and test 538c2ecf20Sopenharmony_ci * @v: pointer of type atomic_t 548c2ecf20Sopenharmony_ci * 558c2ecf20Sopenharmony_ci * Atomically decrements @v by 1 and 568c2ecf20Sopenharmony_ci * returns true if the result is 0, or false for all other 578c2ecf20Sopenharmony_ci * cases. 588c2ecf20Sopenharmony_ci */ 598c2ecf20Sopenharmony_cistatic inline int atomic_dec_and_test(atomic_t *v) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci return __sync_sub_and_fetch(&v->counter, 1) == 0; 628c2ecf20Sopenharmony_ci} 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci#define cmpxchg(ptr, oldval, newval) \ 658c2ecf20Sopenharmony_ci __sync_val_compare_and_swap(ptr, oldval, newval) 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cistatic inline int atomic_cmpxchg(atomic_t *v, int oldval, int newval) 688c2ecf20Sopenharmony_ci{ 698c2ecf20Sopenharmony_ci return cmpxchg(&(v)->counter, oldval, newval); 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci#endif /* __TOOLS_ASM_GENERIC_ATOMIC_H */ 73