|
|
1.1 ! root 1: #ifndef __ARCH_I386_ATOMIC__ ! 2: #define __ARCH_I386_ATOMIC__ ! 3: ! 4: /* ! 5: * Atomic operations that C can't guarantee us. Useful for ! 6: * resource counting etc.. ! 7: */ ! 8: ! 9: #ifdef __SMP__ ! 10: #define LOCK "lock ; " ! 11: #else ! 12: #define LOCK "" ! 13: #endif ! 14: ! 15: /* ! 16: * Make sure gcc doesn't try to be clever and move things around ! 17: * on us. We need to use _exactly_ the address the user gave us, ! 18: * not some alias that contains the same information. ! 19: */ ! 20: #define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x) ! 21: ! 22: typedef int atomic_t; ! 23: ! 24: static __inline__ void atomic_add(atomic_t i, atomic_t *v) ! 25: { ! 26: __asm__ __volatile__( ! 27: LOCK "addl %1,%0" ! 28: :"=m" (__atomic_fool_gcc(v)) ! 29: :"ir" (i), "m" (__atomic_fool_gcc(v))); ! 30: } ! 31: ! 32: static __inline__ void atomic_sub(atomic_t i, atomic_t *v) ! 33: { ! 34: __asm__ __volatile__( ! 35: LOCK "subl %1,%0" ! 36: :"=m" (__atomic_fool_gcc(v)) ! 37: :"ir" (i), "m" (__atomic_fool_gcc(v))); ! 38: } ! 39: ! 40: static __inline__ void atomic_inc(atomic_t *v) ! 41: { ! 42: __asm__ __volatile__( ! 43: LOCK "incl %0" ! 44: :"=m" (__atomic_fool_gcc(v)) ! 45: :"m" (__atomic_fool_gcc(v))); ! 46: } ! 47: ! 48: static __inline__ void atomic_dec(atomic_t *v) ! 49: { ! 50: __asm__ __volatile__( ! 51: LOCK "decl %0" ! 52: :"=m" (__atomic_fool_gcc(v)) ! 53: :"m" (__atomic_fool_gcc(v))); ! 54: } ! 55: ! 56: static __inline__ int atomic_dec_and_test(atomic_t *v) ! 57: { ! 58: unsigned char c; ! 59: ! 60: __asm__ __volatile__( ! 61: LOCK "decl %0; sete %1" ! 62: :"=m" (__atomic_fool_gcc(v)), "=qm" (c) ! 63: :"m" (__atomic_fool_gcc(v))); ! 64: return c != 0; ! 65: } ! 66: ! 67: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.