123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- #ifndef __ATOMIC_H
- #define __ATOMIC_H
- #include "asm-generic/atomic.h"
- typedef struct {
- volatile int counter;
- } atomic_t;
- #ifdef __i386__
- /**
- * atomic_read - read atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically reads the value of @v.
- */
- static inline int atomic_read(const atomic_t *v)
- {
- return v->counter;
- }
- /**
- * atomic_set - set atomic variable
- * @v: pointer of type atomic_t
- * @i: required value
- *
- * Atomically sets the value of @v to @i.
- */
- static inline void atomic_set(atomic_t *v, int i)
- {
- v->counter = i;
- }
- /**
- * atomic_inc - increment atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1.
- */
- static inline void atomic_inc(atomic_t *v)
- {
- asm volatile("lock incl %0"
- : "+m" (v->counter));
- }
- /**
- * atomic_dec - decrement atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically decrements @v by 1.
- */
- static inline void atomic_dec(atomic_t *v)
- {
- asm volatile("lock decl %0"
- : "+m" (v->counter));
- }
- typedef struct {
- u64 __attribute__((aligned(8))) counter;
- } atomic64_t;
- #define ATOMIC64_INIT(val) { (val) }
- /**
- * atomic64_read - read atomic64 variable
- * @ptr: pointer to type atomic64_t
- *
- * Atomically reads the value of @ptr and returns it.
- */
- static inline u64 atomic64_read(atomic64_t *ptr)
- {
- u64 res;
- /*
- * Note, we inline this atomic64_t primitive because
- * it only clobbers EAX/EDX and leaves the others
- * untouched. We also (somewhat subtly) rely on the
- * fact that cmpxchg8b returns the current 64-bit value
- * of the memory location we are touching:
- */
- asm volatile("mov %%ebx, %%eax\n\t"
- "mov %%ecx, %%edx\n\t"
- "lock cmpxchg8b %1\n"
- : "=&A" (res)
- : "m" (*ptr)
- );
- return res;
- }
- u64 atomic64_cmpxchg(atomic64_t *v, u64 old, u64 new);
- #elif defined(__x86_64__)
- /**
- * atomic_read - read atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically reads the value of @v.
- */
- static inline int atomic_read(const atomic_t *v)
- {
- return v->counter;
- }
- /**
- * atomic_set - set atomic variable
- * @v: pointer of type atomic_t
- * @i: required value
- *
- * Atomically sets the value of @v to @i.
- */
- static inline void atomic_set(atomic_t *v, int i)
- {
- v->counter = i;
- }
- /**
- * atomic_inc - increment atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1.
- */
- static inline void atomic_inc(atomic_t *v)
- {
- asm volatile("lock incl %0"
- : "=m" (v->counter)
- : "m" (v->counter));
- }
- /**
- * atomic_dec - decrement atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically decrements @v by 1.
- */
- static inline void atomic_dec(atomic_t *v)
- {
- asm volatile("lock decl %0"
- : "=m" (v->counter)
- : "m" (v->counter));
- }
- typedef struct {
- long long counter;
- } atomic64_t;
- #define ATOMIC64_INIT(i) { (i) }
- /**
- * atomic64_read - read atomic64 variable
- * @v: pointer of type atomic64_t
- *
- * Atomically reads the value of @v.
- * Doesn't imply a read memory barrier.
- */
- static inline long atomic64_read(const atomic64_t *v)
- {
- return v->counter;
- }
- u64 atomic64_cmpxchg(atomic64_t *v, u64 old, u64 new);
- #endif
- #endif
|