linux-bk/include/asm-parisc/spinlock.h
<<
>>
Prefs
   1#ifndef __ASM_SPINLOCK_H
   2#define __ASM_SPINLOCK_H
   3
   4#include <asm/system.h>
   5
   6/* we seem to be the only architecture that uses 0 to mean locked - but we
   7 * have to.  prumpf */
   8
   9#undef SPIN_LOCK_UNLOCKED
  10#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 }
  11
  12#define spin_lock_init(x)       do { (x)->lock = 1; } while(0)
  13
  14#define spin_unlock_wait(x)     do { barrier(); } while(((volatile spinlock_t *)(x))->lock == 1)
  15
  16#define spin_lock(x) \
  17        do { while(__ldcw(&(x)->lock) == 0); } while(0)
  18        
  19#define spin_unlock(x) \
  20        do { (x)->lock = 1; } while(0)
  21
  22#define spin_trylock(x) (__ldcw(&(x)->lock) == 1)
  23
  24/*
  25 * Read-write spinlocks, allowing multiple readers
  26 * but only one writer.
  27 */
  28typedef struct {
  29        spinlock_t lock;
  30        volatile int counter;
  31} rwlock_t;
  32
  33#define RW_LOCK_UNLOCKED (rwlock_t) { SPIN_LOCK_UNLOCKED, 0 }
  34
  35/* read_lock, read_unlock are pretty straightforward.  Of course it somehow
  36 * sucks we end up saving/restoring flags twice for read_lock_irqsave aso. */
  37
  38static inline void read_lock(rwlock_t *rw)
  39{
  40        unsigned long flags;
  41        spin_lock_irqsave(&rw->lock, flags);
  42
  43        rw->counter++;
  44
  45        spin_unlock_irqrestore(&rw->lock, flags);
  46}
  47
  48static inline void read_unlock(rwlock_t *rw)
  49{
  50        unsigned long flags;
  51        spin_lock_irqsave(&rw->lock, flags);
  52
  53        rw->counter--;
  54
  55        spin_unlock_irqrestore(&rw->lock, flags);
  56}
  57
  58/* write_lock is less trivial.  We optimistically grab the lock and check
  59 * if we surprised any readers.  If so we release the lock and wait till
  60 * they're all gone before trying again
  61 *
  62 * Also note that we don't use the _irqsave / _irqrestore suffixes here.
  63 * If we're called with interrupts enabled and we've got readers (or other
  64 * writers) in interrupt handlers someone fucked up and we'd dead-lock
  65 * sooner or later anyway.   prumpf */
  66
  67static inline void write_lock(rwlock_t *rw)
  68{
  69retry:
  70        spin_lock(&rw->lock);
  71
  72        if(rw->counter != 0) {
  73                /* this basically never happens */
  74                spin_unlock(&rw->lock);
  75
  76                while(rw->counter != 0);
  77
  78                goto retry;
  79        }
  80
  81        /* got it.  now leave without unlocking */
  82}
  83
  84/* write_unlock is absolutely trivial - we don't have to wait for anything */
  85
  86static inline void write_unlock(rwlock_t *rw)
  87{
  88        spin_unlock(&rw->lock);
  89}
  90
  91#endif /* __ASM_SPINLOCK_H */
  92
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.