15abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst#ifndef _ASM_X86_ATOMIC_H 25abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst#define _ASM_X86_ATOMIC_H 35abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 45abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst#include <linux/compiler.h> 55abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst#include <linux/types.h> 65abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst#include <asm/processor.h> 75abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst#include <asm/alternative.h> 85abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst#include <asm/cmpxchg.h> 90c44c2d0f459cd7e275242b72f500137c4fa834dPeter Zijlstra#include <asm/rmwcc.h> 10d00a569284b1340c16fe2c148099e077ea09ebc9Peter Zijlstra#include <asm/barrier.h> 115abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 125abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/* 135abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomic operations that C can't guarantee us. Useful for 145abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * resource counting etc.. 155abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 165abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 175abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst#define ATOMIC_INIT(i) { (i) } 185abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 195abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/** 205abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * atomic_read - read atomic variable 215abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @v: pointer of type atomic_t 225abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * 235abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomically reads the value of @v. 245abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 255abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline int atomic_read(const atomic_t *v) 265abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 272291059c852706c6f5ffb400366042b7625066cdPranith Kumar return ACCESS_ONCE((v)->counter); 285abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 295abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 305abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/** 315abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * atomic_set - set atomic variable 325abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @v: pointer of type atomic_t 335abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @i: required value 345abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * 355abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomically sets the value of @v to @i. 365abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 375abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline void atomic_set(atomic_t *v, int i) 385abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 395abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst v->counter = i; 405abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 415abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 425abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/** 435abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * atomic_add - add integer to atomic variable 445abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @i: integer value to add 455abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @v: pointer of type atomic_t 465abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * 475abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomically adds @i to @v. 485abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 495abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline void atomic_add(int i, atomic_t *v) 505abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 515abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst asm volatile(LOCK_PREFIX "addl %1,%0" 525abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst : "+m" (v->counter) 535abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst : "ir" (i)); 545abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 555abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 565abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/** 575abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * atomic_sub - subtract integer from atomic variable 585abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @i: integer value to subtract 595abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @v: pointer of type atomic_t 605abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * 615abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomically subtracts @i from @v. 625abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 635abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline void atomic_sub(int i, atomic_t *v) 645abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 655abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst asm volatile(LOCK_PREFIX "subl %1,%0" 665abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst : "+m" (v->counter) 675abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst : "ir" (i)); 685abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 695abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 705abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/** 715abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * atomic_sub_and_test - subtract value from variable and test result 725abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @i: integer value to subtract 735abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @v: pointer of type atomic_t 745abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * 755abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomically subtracts @i from @v and returns 765abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * true if the result is zero, or false for all 775abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * other cases. 785abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 795abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline int atomic_sub_and_test(int i, atomic_t *v) 805abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 81e0f6dec35f9286e78879fe1ac92803fd69fc4fdcH. Peter Anvin GEN_BINARY_RMWcc(LOCK_PREFIX "subl", v->counter, "er", i, "%0", "e"); 825abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 835abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 845abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/** 855abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * atomic_inc - increment atomic variable 865abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @v: pointer of type atomic_t 875abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * 885abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomically increments @v by 1. 895abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 905abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline void atomic_inc(atomic_t *v) 915abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 925abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst asm volatile(LOCK_PREFIX "incl %0" 935abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst : "+m" (v->counter)); 945abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 955abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 965abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/** 975abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * atomic_dec - decrement atomic variable 985abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @v: pointer of type atomic_t 995abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * 1005abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomically decrements @v by 1. 1015abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 1025abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline void atomic_dec(atomic_t *v) 1035abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 1045abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst asm volatile(LOCK_PREFIX "decl %0" 1055abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst : "+m" (v->counter)); 1065abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 1075abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 1085abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/** 1095abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * atomic_dec_and_test - decrement and test 1105abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @v: pointer of type atomic_t 1115abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * 1125abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomically decrements @v by 1 and 1135abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * returns true if the result is 0, or false for all other 1145abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * cases. 1155abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 1165abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline int atomic_dec_and_test(atomic_t *v) 1175abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 1180c44c2d0f459cd7e275242b72f500137c4fa834dPeter Zijlstra GEN_UNARY_RMWcc(LOCK_PREFIX "decl", v->counter, "%0", "e"); 1195abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 1205abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 1215abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/** 1225abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * atomic_inc_and_test - increment and test 1235abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @v: pointer of type atomic_t 1245abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * 1255abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomically increments @v by 1 1265abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * and returns true if the result is zero, or false for all 1275abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * other cases. 1285abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 1295abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline int atomic_inc_and_test(atomic_t *v) 1305abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 1310c44c2d0f459cd7e275242b72f500137c4fa834dPeter Zijlstra GEN_UNARY_RMWcc(LOCK_PREFIX "incl", v->counter, "%0", "e"); 1325abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 1335abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 1345abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/** 1355abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * atomic_add_negative - add and test if negative 1365abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @i: integer value to add 1375abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @v: pointer of type atomic_t 1385abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * 1395abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomically adds @i to @v and returns true 1405abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * if the result is negative, or false when 1415abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * result is greater than or equal to zero. 1425abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 1435abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline int atomic_add_negative(int i, atomic_t *v) 1445abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 145e0f6dec35f9286e78879fe1ac92803fd69fc4fdcH. Peter Anvin GEN_BINARY_RMWcc(LOCK_PREFIX "addl", v->counter, "er", i, "%0", "s"); 1465abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 1475abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 1485abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/** 1495abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * atomic_add_return - add integer and return 1505abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @i: integer value to add 1515abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @v: pointer of type atomic_t 1525abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * 1535abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomically adds @i to @v and returns @i + @v 1545abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 1555abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline int atomic_add_return(int i, atomic_t *v) 1565abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 1578b8bc2f7311c3223213dbe346d9cc2e299fdb5ebJeremy Fitzhardinge return i + xadd(&v->counter, i); 1585abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 1595abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 1605abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/** 1615abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * atomic_sub_return - subtract integer and return 1625abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @v: pointer of type atomic_t 1635abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @i: integer value to subtract 1645abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * 1655abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomically subtracts @i from @v and returns @v - @i 1665abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 1675abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline int atomic_sub_return(int i, atomic_t *v) 1685abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 1695abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst return atomic_add_return(-i, v); 1705abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 1715abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 1725abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst#define atomic_inc_return(v) (atomic_add_return(1, v)) 1735abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst#define atomic_dec_return(v) (atomic_sub_return(1, v)) 1745abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 1755abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline int atomic_cmpxchg(atomic_t *v, int old, int new) 1765abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 1775abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst return cmpxchg(&v->counter, old, new); 1785abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 1795abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 1805abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline int atomic_xchg(atomic_t *v, int new) 1815abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 1825abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst return xchg(&v->counter, new); 1835abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 1845abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 1855abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/** 186f24219b4e90cf70ec4a211b17fbabc725a0ddf3cArun Sharma * __atomic_add_unless - add unless the number is already a given value 1875abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @v: pointer of type atomic_t 1885abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @a: the amount to add to v... 1895abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @u: ...unless v is equal to u. 1905abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * 1915abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomically adds @a to @v, so long as @v was not already @u. 192f24219b4e90cf70ec4a211b17fbabc725a0ddf3cArun Sharma * Returns the old value of @v. 1935abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 194f24219b4e90cf70ec4a211b17fbabc725a0ddf3cArun Sharmastatic inline int __atomic_add_unless(atomic_t *v, int a, int u) 1955abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 1965abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst int c, old; 1975abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst c = atomic_read(v); 1985abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst for (;;) { 1995abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst if (unlikely(c == (u))) 2005abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst break; 2015abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst old = atomic_cmpxchg((v), c, c + (a)); 2025abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst if (likely(old == c)) 2035abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst break; 2045abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst c = old; 2055abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst } 206f24219b4e90cf70ec4a211b17fbabc725a0ddf3cArun Sharma return c; 2075abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 2085abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 2095abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/** 2105abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * atomic_inc_short - increment of a short integer 2115abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * @v: pointer to type int 2125abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * 2135abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Atomically adds 1 to @v 2145abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst * Returns the new value of @u 2155abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst */ 2165abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerststatic inline short int atomic_inc_short(short int *v) 2175abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst{ 2185abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst asm(LOCK_PREFIX "addw $1, %0" : "+m" (*v)); 2195abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst return *v; 2205abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst} 2215abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 2225abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst/* These are x86-specific, used by some header files */ 2235abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst#define atomic_clear_mask(mask, addr) \ 2245abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst asm volatile(LOCK_PREFIX "andl %0,%1" \ 2255abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst : : "r" (~(mask)), "m" (*(addr)) : "memory") 2265abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 2275abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst#define atomic_set_mask(mask, addr) \ 2285abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst asm volatile(LOCK_PREFIX "orl %0,%1" \ 2295abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst : : "r" ((unsigned)(mask)), "m" (*(addr)) \ 2305abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst : "memory") 2315abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 23296a388de5dc53a8b234b3fd41f3ae2cedc9ffd42Thomas Gleixner#ifdef CONFIG_X86_32 233a1ce39288e6fbefdd8d607021d02384eb4a20b99David Howells# include <asm/atomic64_32.h> 23496a388de5dc53a8b234b3fd41f3ae2cedc9ffd42Thomas Gleixner#else 235a1ce39288e6fbefdd8d607021d02384eb4a20b99David Howells# include <asm/atomic64_64.h> 23696a388de5dc53a8b234b3fd41f3ae2cedc9ffd42Thomas Gleixner#endif 2375abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst 2385abbbbf0b0cd4abf5898136d0c345dc99b859c8cBrian Gerst#endif /* _ASM_X86_ATOMIC_H */ 239