at v2.6.13-rc6 212 lines 4.2 kB view raw
1#ifndef _ALPHA_SPINLOCK_H 2#define _ALPHA_SPINLOCK_H 3 4#include <linux/config.h> 5#include <asm/system.h> 6#include <linux/kernel.h> 7#include <asm/current.h> 8 9 10/* 11 * Simple spin lock operations. There are two variants, one clears IRQ's 12 * on the local processor, one does not. 13 * 14 * We make no fairness assumptions. They have a cost. 15 */ 16 17typedef struct { 18 volatile unsigned int lock; 19#ifdef CONFIG_DEBUG_SPINLOCK 20 int on_cpu; 21 int line_no; 22 void *previous; 23 struct task_struct * task; 24 const char *base_file; 25#endif 26} spinlock_t; 27 28#ifdef CONFIG_DEBUG_SPINLOCK 29#define SPIN_LOCK_UNLOCKED (spinlock_t){ 0, -1, 0, NULL, NULL, NULL } 30#else 31#define SPIN_LOCK_UNLOCKED (spinlock_t){ 0 } 32#endif 33 34#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0) 35#define spin_is_locked(x) ((x)->lock != 0) 36#define spin_unlock_wait(x) do { barrier(); } while ((x)->lock) 37 38#ifdef CONFIG_DEBUG_SPINLOCK 39extern void _raw_spin_unlock(spinlock_t * lock); 40extern void debug_spin_lock(spinlock_t * lock, const char *, int); 41extern int debug_spin_trylock(spinlock_t * lock, const char *, int); 42#define _raw_spin_lock(LOCK) \ 43 debug_spin_lock(LOCK, __BASE_FILE__, __LINE__) 44#define _raw_spin_trylock(LOCK) \ 45 debug_spin_trylock(LOCK, __BASE_FILE__, __LINE__) 46#else 47static inline void _raw_spin_unlock(spinlock_t * lock) 48{ 49 mb(); 50 lock->lock = 0; 51} 52 53static inline void _raw_spin_lock(spinlock_t * lock) 54{ 55 long tmp; 56 57 __asm__ __volatile__( 58 "1: ldl_l %0,%1\n" 59 " bne %0,2f\n" 60 " lda %0,1\n" 61 " stl_c %0,%1\n" 62 " beq %0,2f\n" 63 " mb\n" 64 ".subsection 2\n" 65 "2: ldl %0,%1\n" 66 " bne %0,2b\n" 67 " br 1b\n" 68 ".previous" 69 : "=&r" (tmp), "=m" (lock->lock) 70 : "m"(lock->lock) : "memory"); 71} 72 73static inline int _raw_spin_trylock(spinlock_t *lock) 74{ 75 return !test_and_set_bit(0, &lock->lock); 76} 77#endif /* CONFIG_DEBUG_SPINLOCK */ 78 79#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) 80 81/***********************************************************/ 82 83typedef struct { 84 volatile unsigned int lock; 85} rwlock_t; 86 87#define RW_LOCK_UNLOCKED (rwlock_t){ 0 } 88 89#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0) 90 91static inline int read_can_lock(rwlock_t *lock) 92{ 93 return (lock->lock & 1) == 0; 94} 95 96static inline int write_can_lock(rwlock_t *lock) 97{ 98 return lock->lock == 0; 99} 100 101#ifdef CONFIG_DEBUG_RWLOCK 102extern void _raw_write_lock(rwlock_t * lock); 103extern void _raw_read_lock(rwlock_t * lock); 104#else 105static inline void _raw_write_lock(rwlock_t * lock) 106{ 107 long regx; 108 109 __asm__ __volatile__( 110 "1: ldl_l %1,%0\n" 111 " bne %1,6f\n" 112 " lda %1,1\n" 113 " stl_c %1,%0\n" 114 " beq %1,6f\n" 115 " mb\n" 116 ".subsection 2\n" 117 "6: ldl %1,%0\n" 118 " bne %1,6b\n" 119 " br 1b\n" 120 ".previous" 121 : "=m" (*lock), "=&r" (regx) 122 : "m" (*lock) : "memory"); 123} 124 125static inline void _raw_read_lock(rwlock_t * lock) 126{ 127 long regx; 128 129 __asm__ __volatile__( 130 "1: ldl_l %1,%0\n" 131 " blbs %1,6f\n" 132 " subl %1,2,%1\n" 133 " stl_c %1,%0\n" 134 " beq %1,6f\n" 135 " mb\n" 136 ".subsection 2\n" 137 "6: ldl %1,%0\n" 138 " blbs %1,6b\n" 139 " br 1b\n" 140 ".previous" 141 : "=m" (*lock), "=&r" (regx) 142 : "m" (*lock) : "memory"); 143} 144#endif /* CONFIG_DEBUG_RWLOCK */ 145 146static inline int _raw_read_trylock(rwlock_t * lock) 147{ 148 long regx; 149 int success; 150 151 __asm__ __volatile__( 152 "1: ldl_l %1,%0\n" 153 " lda %2,0\n" 154 " blbs %1,2f\n" 155 " subl %1,2,%2\n" 156 " stl_c %2,%0\n" 157 " beq %2,6f\n" 158 "2: mb\n" 159 ".subsection 2\n" 160 "6: br 1b\n" 161 ".previous" 162 : "=m" (*lock), "=&r" (regx), "=&r" (success) 163 : "m" (*lock) : "memory"); 164 165 return success; 166} 167 168static inline int _raw_write_trylock(rwlock_t * lock) 169{ 170 long regx; 171 int success; 172 173 __asm__ __volatile__( 174 "1: ldl_l %1,%0\n" 175 " lda %2,0\n" 176 " bne %1,2f\n" 177 " lda %2,1\n" 178 " stl_c %2,%0\n" 179 " beq %2,6f\n" 180 "2: mb\n" 181 ".subsection 2\n" 182 "6: br 1b\n" 183 ".previous" 184 : "=m" (*lock), "=&r" (regx), "=&r" (success) 185 : "m" (*lock) : "memory"); 186 187 return success; 188} 189 190static inline void _raw_write_unlock(rwlock_t * lock) 191{ 192 mb(); 193 lock->lock = 0; 194} 195 196static inline void _raw_read_unlock(rwlock_t * lock) 197{ 198 long regx; 199 __asm__ __volatile__( 200 " mb\n" 201 "1: ldl_l %1,%0\n" 202 " addl %1,2,%1\n" 203 " stl_c %1,%0\n" 204 " beq %1,6f\n" 205 ".subsection 2\n" 206 "6: br 1b\n" 207 ".previous" 208 : "=m" (*lock), "=&r" (regx) 209 : "m" (*lock) : "memory"); 210} 211 212#endif /* _ALPHA_SPINLOCK_H */