1/* 2 * Copyright 2010 Tilera Corporation. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, version 2. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 11 * NON INFRINGEMENT. See the GNU General Public License for 12 * more details. 13 * 14 * Atomic primitives. 15 */ 16 17#ifndef _ASM_TILE_ATOMIC_H 18#define _ASM_TILE_ATOMIC_H 19 20#ifndef __ASSEMBLY__ 21 22#include <linux/compiler.h> 23#include <asm/system.h> 24 25#define ATOMIC_INIT(i) { (i) } 26 27/** 28 * atomic_read - read atomic variable 29 * @v: pointer of type atomic_t 30 * 31 * Atomically reads the value of @v. 32 */ 33static inline int atomic_read(const atomic_t *v) 34{ 35 return v->counter; 36} 37 38/** 39 * atomic_sub_return - subtract integer and return 40 * @v: pointer of type atomic_t 41 * @i: integer value to subtract 42 * 43 * Atomically subtracts @i from @v and returns @v - @i 44 */ 45#define atomic_sub_return(i, v) atomic_add_return((int)(-(i)), (v)) 46 47/** 48 * atomic_sub - subtract integer from atomic variable 49 * @i: integer value to subtract 50 * @v: pointer of type atomic_t 51 * 52 * Atomically subtracts @i from @v. 53 */ 54#define atomic_sub(i, v) atomic_add((int)(-(i)), (v)) 55 56/** 57 * atomic_sub_and_test - subtract value from variable and test result 58 * @i: integer value to subtract 59 * @v: pointer of type atomic_t 60 * 61 * Atomically subtracts @i from @v and returns true if the result is 62 * zero, or false for all other cases. 63 */ 64#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0) 65 66/** 67 * atomic_inc_return - increment memory and return 68 * @v: pointer of type atomic_t 69 * 70 * Atomically increments @v by 1 and returns the new value. 71 */ 72#define atomic_inc_return(v) atomic_add_return(1, (v)) 73 74/** 75 * atomic_dec_return - decrement memory and return 76 * @v: pointer of type atomic_t 77 * 78 * Atomically decrements @v by 1 and returns the new value. 79 */ 80#define atomic_dec_return(v) atomic_sub_return(1, (v)) 81 82/** 83 * atomic_inc - increment atomic variable 84 * @v: pointer of type atomic_t 85 * 86 * Atomically increments @v by 1. 87 */ 88#define atomic_inc(v) atomic_add(1, (v)) 89 90/** 91 * atomic_dec - decrement atomic variable 92 * @v: pointer of type atomic_t 93 * 94 * Atomically decrements @v by 1. 95 */ 96#define atomic_dec(v) atomic_sub(1, (v)) 97 98/** 99 * atomic_dec_and_test - decrement and test 100 * @v: pointer of type atomic_t 101 * 102 * Atomically decrements @v by 1 and returns true if the result is 0. 103 */ 104#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0) 105 106/** 107 * atomic_inc_and_test - increment and test 108 * @v: pointer of type atomic_t 109 * 110 * Atomically increments @v by 1 and returns true if the result is 0. 111 */ 112#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) 113 114/** 115 * atomic_add_negative - add and test if negative 116 * @v: pointer of type atomic_t 117 * @i: integer value to add 118 * 119 * Atomically adds @i to @v and returns true if the result is 120 * negative, or false when result is greater than or equal to zero. 121 */ 122#define atomic_add_negative(i, v) (atomic_add_return((i), (v)) < 0) 123 124/** 125 * atomic_inc_not_zero - increment unless the number is zero 126 * @v: pointer of type atomic_t 127 * 128 * Atomically increments @v by 1, so long as @v is non-zero. 129 * Returns non-zero if @v was non-zero, and zero otherwise. 130 */ 131#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) 132 133 134/* 135 * We define xchg() and cmpxchg() in the included headers. 136 * Note that we do not define __HAVE_ARCH_CMPXCHG, since that would imply 137 * that cmpxchg() is an efficient operation, which is not particularly true. 138 */ 139 140/* Nonexistent functions intended to cause link errors. */ 141extern unsigned long __xchg_called_with_bad_pointer(void); 142extern unsigned long __cmpxchg_called_with_bad_pointer(void); 143 144#define tas(ptr) (xchg((ptr), 1)) 145 146#endif /* __ASSEMBLY__ */ 147 148#ifndef __tilegx__ 149#include <asm/atomic_32.h> 150#else 151#include <asm/atomic_64.h> 152#endif 153 154/* Provide the appropriate atomic_long_t definitions. */ 155#ifndef __ASSEMBLY__ 156#include <asm-generic/atomic-long.h> 157#endif 158 159#endif /* _ASM_TILE_ATOMIC_H */ 160