1 #ifndef __ASM_SPINLOCK_H
2 #define __ASM_SPINLOCK_H
4 #include <asm/system.h>
6 /* Note that PA-RISC has to use `1' to mean unlocked and `0' to mean locked
7 * since it only has load-and-zero. Moreover, at least on some PA processors,
8 * the semaphore address has to be 16-byte aligned.
11 #undef SPIN_LOCK_UNLOCKED
12 #define SPIN_LOCK_UNLOCKED (spinlock_t) { { 1, 1, 1, 1 } }
14 #define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
16 static inline int spin_is_locked(spinlock_t *x)
18 volatile unsigned int *a = __ldcw_align(x);
22 #define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
23 #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
25 static inline void _raw_spin_lock(spinlock_t *x)
27 volatile unsigned int *a = __ldcw_align(x);
28 while (__ldcw(a) == 0)
32 static inline void _raw_spin_unlock(spinlock_t *x)
34 volatile unsigned int *a = __ldcw_align(x);
38 static inline int _raw_spin_trylock(spinlock_t *x)
40 volatile unsigned int *a = __ldcw_align(x);
41 return __ldcw(a) != 0;
45 * Read-write spinlocks, allowing multiple readers
46 * but only one writer.
53 #define RW_LOCK_UNLOCKED (rwlock_t) { { { 1, 1, 1, 1 } }, 0 }
55 #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while (0)
57 #define rwlock_is_locked(lp) ((lp)->counter != 0)
59 /* read_lock, read_unlock are pretty straightforward. Of course it somehow
60 * sucks we end up saving/restoring flags twice for read_lock_irqsave aso. */
62 static __inline__ void _raw_read_lock(rwlock_t *rw)
65 local_irq_save(flags);
66 _raw_spin_lock(&rw->lock);
70 _raw_spin_unlock(&rw->lock);
71 local_irq_restore(flags);
74 static __inline__ void _raw_read_unlock(rwlock_t *rw)
77 local_irq_save(flags);
78 _raw_spin_lock(&rw->lock);
82 _raw_spin_unlock(&rw->lock);
83 local_irq_restore(flags);
86 /* write_lock is less trivial. We optimistically grab the lock and check
87 * if we surprised any readers. If so we release the lock and wait till
88 * they're all gone before trying again
90 * Also note that we don't use the _irqsave / _irqrestore suffixes here.
91 * If we're called with interrupts enabled and we've got readers (or other
92 * writers) in interrupt handlers someone fucked up and we'd dead-lock
93 * sooner or later anyway. prumpf */
95 static __inline__ void _raw_write_lock(rwlock_t *rw)
98 _raw_spin_lock(&rw->lock);
100 if(rw->counter != 0) {
101 /* this basically never happens */
102 _raw_spin_unlock(&rw->lock);
104 while(rw->counter != 0);
109 /* got it. now leave without unlocking */
110 rw->counter = -1; /* remember we are locked */
113 /* write_unlock is absolutely trivial - we don't have to wait for anything */
115 static __inline__ void _raw_write_unlock(rwlock_t *rw)
118 _raw_spin_unlock(&rw->lock);
121 static __inline__ int is_read_locked(rwlock_t *rw)
123 return rw->counter > 0;
126 static __inline__ int is_write_locked(rwlock_t *rw)
128 return rw->counter < 0;
131 #endif /* __ASM_SPINLOCK_H */