1 #ifndef __ASM_SPINLOCK_H
2 #define __ASM_SPINLOCK_H
4 #include <asm/spinlock_t.h> /* get spinlock primitives */
5 #include <asm/psw.h> /* local_* primitives need PSW_I */
6 #include <asm/system_irqsave.h> /* get local_* primitives */
9 * Read-write spinlocks, allowing multiple readers
10 * but only one writer.
17 #define RW_LOCK_UNLOCKED (rwlock_t) { SPIN_LOCK_UNLOCKED, 0 }
19 #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while (0)
21 /* read_lock, read_unlock are pretty straightforward. Of course it somehow
22 * sucks we end up saving/restoring flags twice for read_lock_irqsave aso. */
24 static inline void read_lock(rwlock_t *rw)
27 spin_lock_irqsave(&rw->lock, flags);
31 spin_unlock_irqrestore(&rw->lock, flags);
34 static inline void read_unlock(rwlock_t *rw)
37 spin_lock_irqsave(&rw->lock, flags);
41 spin_unlock_irqrestore(&rw->lock, flags);
44 /* write_lock is less trivial. We optimistically grab the lock and check
45 * if we surprised any readers. If so we release the lock and wait till
46 * they're all gone before trying again
48 * Also note that we don't use the _irqsave / _irqrestore suffixes here.
49 * If we're called with interrupts enabled and we've got readers (or other
50 * writers) in interrupt handlers someone fucked up and we'd dead-lock
51 * sooner or later anyway. prumpf */
53 static inline void write_lock(rwlock_t *rw)
58 if(rw->counter != 0) {
59 /* this basically never happens */
60 spin_unlock(&rw->lock);
62 while(rw->counter != 0);
67 /* got it. now leave without unlocking */
70 /* write_unlock is absolutely trivial - we don't have to wait for anything */
72 static inline void write_unlock(rwlock_t *rw)
74 spin_unlock(&rw->lock);
77 #endif /* __ASM_SPINLOCK_H */