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

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

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

  1 #ifndef _ALPHA_SPINLOCK_H
  2 #define _ALPHA_SPINLOCK_H
  3 
  4 #include <asm/system.h>
  5 #include <linux/kernel.h>
  6 #include <asm/current.h>
  7 
  8 #define DEBUG_SPINLOCK 0
  9 #define DEBUG_RWLOCK 0
 10 
 11 /*
 12  * Simple spin lock operations.  There are two variants, one clears IRQ's
 13  * on the local processor, one does not.
 14  *
 15  * We make no fairness assumptions. They have a cost.
 16  */
 17 
 18 typedef struct {
 19         volatile unsigned int lock /*__attribute__((aligned(32))) */;
 20 #if DEBUG_SPINLOCK
 21         int on_cpu;
 22         int line_no;
 23         void *previous;
 24         struct task_struct * task;
 25         const char *base_file;
 26 #endif
 27 } spinlock_t;
 28 
 29 #if DEBUG_SPINLOCK
 30 #define SPIN_LOCK_UNLOCKED (spinlock_t) {0, -1, 0, 0, 0, 0}
 31 #define spin_lock_init(x)                                               \
 32         ((x)->lock = 0, (x)->on_cpu = -1, (x)->previous = 0, (x)->task = 0)
 33 #else
 34 #define SPIN_LOCK_UNLOCKED      (spinlock_t) { 0 }
 35 #define spin_lock_init(x)       ((x)->lock = 0)
 36 #endif
 37 
 38 #define spin_is_locked(x)       ((x)->lock != 0)
 39 #define spin_unlock_wait(x)     ({ do { barrier(); } while ((x)->lock); })
 40 
 41 #if DEBUG_SPINLOCK
 42 extern void spin_unlock(spinlock_t * lock);
 43 extern void debug_spin_lock(spinlock_t * lock, const char *, int);
 44 extern int debug_spin_trylock(spinlock_t * lock, const char *, int);
 45 
 46 #define spin_lock(LOCK) debug_spin_lock(LOCK, __BASE_FILE__, __LINE__)
 47 #define spin_trylock(LOCK) debug_spin_trylock(LOCK, __BASE_FILE__, __LINE__)
 48 
 49 #define spin_lock_own(LOCK, LOCATION)                                   \
 50 do {                                                                    \
 51         if (!((LOCK)->lock && (LOCK)->on_cpu == smp_processor_id()))    \
 52                 printk("%s: called on %d from %p but lock %s on %d\n",  \
 53                        LOCATION, smp_processor_id(),                    \
 54                        __builtin_return_address(0),                     \
 55                        (LOCK)->lock ? "taken" : "freed", (LOCK)->on_cpu); \
 56 } while (0)
 57 #else
 58 static inline void spin_unlock(spinlock_t * lock)
 59 {
 60         mb();
 61         lock->lock = 0;
 62 }
 63 
 64 static inline void spin_lock(spinlock_t * lock)
 65 {
 66         long tmp;
 67 
 68         /* Use sub-sections to put the actual loop at the end
 69            of this object file's text section so as to perfect
 70            branch prediction.  */
 71         __asm__ __volatile__(
 72         "1:     ldl_l   %0,%1\n"
 73         "       blbs    %0,2f\n"
 74         "       or      %0,1,%0\n"
 75         "       stl_c   %0,%1\n"
 76         "       beq     %0,2f\n"
 77         "       mb\n"
 78         ".subsection 2\n"
 79         "2:     ldl     %0,%1\n"
 80         "       blbs    %0,2b\n"
 81         "       br      1b\n"
 82         ".previous"
 83         : "=&r" (tmp), "=m" (lock->lock)
 84         : "m"(lock->lock) : "memory");
 85 }
 86 
 87 #define spin_trylock(lock) (!test_and_set_bit(0,(lock)))
 88 #define spin_lock_own(LOCK, LOCATION)   ((void)0)
 89 #endif /* DEBUG_SPINLOCK */
 90 
 91 /***********************************************************/
 92 
 93 typedef struct {
 94         volatile int write_lock:1, read_counter:31;
 95 } /*__attribute__((aligned(32)))*/ rwlock_t;
 96 
 97 #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
 98 
 99 #if DEBUG_RWLOCK
100 extern void write_lock(rwlock_t * lock);
101 extern void read_lock(rwlock_t * lock);
102 #else
103 static inline void write_lock(rwlock_t * lock)
104 {
105         long regx;
106 
107         __asm__ __volatile__(
108         "1:     ldl_l   %1,%0\n"
109         "       bne     %1,6f\n"
110         "       or      $31,1,%1\n"
111         "       stl_c   %1,%0\n"
112         "       beq     %1,6f\n"
113         "       mb\n"
114         ".subsection 2\n"
115         "6:     ldl     %1,%0\n"
116         "       bne     %1,6b\n"
117         "       br      1b\n"
118         ".previous"
119         : "=m" (*(volatile int *)lock), "=&r" (regx)
120         : "" (*(volatile int *)lock) : "memory");
121 }
122 
123 static inline void read_lock(rwlock_t * lock)
124 {
125         long regx;
126 
127         __asm__ __volatile__(
128         "1:     ldl_l   %1,%0\n"
129         "       blbs    %1,6f\n"
130         "       subl    %1,2,%1\n"
131         "       stl_c   %1,%0\n"
132         "       beq     %1,6f\n"
133         "4:     mb\n"
134         ".subsection 2\n"
135         "6:     ldl     %1,%0\n"
136         "       blbs    %1,6b\n"
137         "       br      1b\n"
138         ".previous"
139         : "=m" (*(volatile int *)lock), "=&r" (regx)
140         : "m" (*(volatile int *)lock) : "memory");
141 }
142 #endif /* DEBUG_RWLOCK */
143 
144 static inline void write_unlock(rwlock_t * lock)
145 {
146         mb();
147         *(volatile int *)lock = 0;
148 }
149 
150 static inline void read_unlock(rwlock_t * lock)
151 {
152         long regx;
153         __asm__ __volatile__(
154         "       mb\n"
155         "1:     ldl_l   %1,%0\n"
156         "       addl    %1,2,%1\n"
157         "       stl_c   %1,%0\n"
158         "       beq     %1,6f\n"
159         ".subsection 2\n"
160         "6:     br      1b\n"
161         ".previous"
162         : "=m" (*(volatile int *)lock), "=&r" (regx)
163         : "m" (*(volatile int *)lock) : "memory");
164 }
165 
166 #endif /* _ALPHA_SPINLOCK_H */
167 

~ [ 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.