|
|
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.