Rev 1100 | Rev 1121 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1100 | Rev 1104 | ||
|---|---|---|---|
| Line 30... | Line 30... | ||
| 30 | #define __amd64_ATOMIC_H__ |
30 | #define __amd64_ATOMIC_H__ |
| 31 | 31 | ||
| 32 | #include <arch/types.h> |
32 | #include <arch/types.h> |
| 33 | #include <arch/barrier.h> |
33 | #include <arch/barrier.h> |
| 34 | #include <preemption.h> |
34 | #include <preemption.h> |
| 35 | - | ||
| 36 | typedef struct { volatile __u64 count; } atomic_t; |
- | |
| 37 | - | ||
| 38 | static inline void atomic_set(atomic_t *val, __u64 i) |
- | |
| 39 | { |
- | |
| 40 | val->count = i; |
- | |
| 41 | } |
- | |
| 42 | - | ||
| 43 | static inline __u64 atomic_get(atomic_t *val) |
- | |
| 44 | { |
- | |
| 45 | return val->count; |
35 | #include <typedefs.h> |
| 46 | } |
- | |
| 47 | 36 | ||
| 48 | static inline void atomic_inc(atomic_t *val) { |
37 | static inline void atomic_inc(atomic_t *val) { |
| 49 | #ifdef CONFIG_SMP |
38 | #ifdef CONFIG_SMP |
| 50 | __asm__ volatile ("lock incq %0\n" : "=m" (val->count)); |
39 | __asm__ volatile ("lock incq %0\n" : "=m" (val->count)); |
| 51 | #else |
40 | #else |
| Line 59... | Line 48... | ||
| 59 | #else |
48 | #else |
| 60 | __asm__ volatile ("decq %0\n" : "=m" (val->count)); |
49 | __asm__ volatile ("decq %0\n" : "=m" (val->count)); |
| 61 | #endif /* CONFIG_SMP */ |
50 | #endif /* CONFIG_SMP */ |
| 62 | } |
51 | } |
| 63 | 52 | ||
| 64 | static inline count_t atomic_postinc(atomic_t *val) |
53 | static inline long atomic_postinc(atomic_t *val) |
| 65 | { |
54 | { |
| 66 | count_t r; |
55 | long r; |
| 67 | 56 | ||
| 68 | __asm__ volatile ( |
57 | __asm__ volatile ( |
| 69 | "movq $1, %0\n" |
58 | "movq $1, %0\n" |
| 70 | "lock xaddq %0, %1\n" |
59 | "lock xaddq %0, %1\n" |
| 71 | : "=r" (r), "=m" (val->count) |
60 | : "=r" (r), "=m" (val->count) |
| 72 | ); |
61 | ); |
| 73 | 62 | ||
| 74 | return r; |
63 | return r; |
| 75 | } |
64 | } |
| 76 | 65 | ||
| 77 | static inline count_t atomic_postdec(atomic_t *val) |
66 | static inline long atomic_postdec(atomic_t *val) |
| 78 | { |
67 | { |
| 79 | count_t r; |
68 | long r; |
| 80 | 69 | ||
| 81 | __asm__ volatile ( |
70 | __asm__ volatile ( |
| 82 | "movq $-1, %0\n" |
71 | "movq $-1, %0\n" |
| 83 | "lock xaddq %0, %1\n" |
72 | "lock xaddq %0, %1\n" |
| 84 | : "=r" (r), "=m" (val->count) |
73 | : "=r" (r), "=m" (val->count) |
| Line 101... | Line 90... | ||
| 101 | 90 | ||
| 102 | return v; |
91 | return v; |
| 103 | } |
92 | } |
| 104 | 93 | ||
| 105 | 94 | ||
| 106 | /** AMD64 specific fast spinlock */ |
95 | /** amd64 specific fast spinlock */ |
| 107 | static inline void atomic_lock_arch(atomic_t *val) |
96 | static inline void atomic_lock_arch(atomic_t *val) |
| 108 | { |
97 | { |
| 109 | __u64 tmp; |
98 | __u64 tmp; |
| 110 | 99 | ||
| 111 | preemption_disable(); |
100 | preemption_disable(); |
| Line 114... | Line 103... | ||
| 114 | #ifdef CONFIG_HT |
103 | #ifdef CONFIG_HT |
| 115 | "pause;" /* Pentium 4's HT love this instruction */ |
104 | "pause;" /* Pentium 4's HT love this instruction */ |
| 116 | #endif |
105 | #endif |
| 117 | "mov %0, %1;" |
106 | "mov %0, %1;" |
| 118 | "testq %1, %1;" |
107 | "testq %1, %1;" |
| 119 | "jnz 0b;" /* Leightweight looping on locked spinlock */ |
108 | "jnz 0b;" /* Lightweight looping on locked spinlock */ |
| 120 | 109 | ||
| 121 | "incq %1;" /* now use the atomic operation */ |
110 | "incq %1;" /* now use the atomic operation */ |
| 122 | "xchgq %0, %1;" |
111 | "xchgq %0, %1;" |
| 123 | "testq %1, %1;" |
112 | "testq %1, %1;" |
| 124 | "jnz 0b;" |
113 | "jnz 0b;" |