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