~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/asm-parisc/spinlock.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.