|
|
1.1 ! root 1: #ifndef __ASM_SPINLOCK_H ! 2: #define __ASM_SPINLOCK_H ! 3: ! 4: #ifndef __SMP__ ! 5: ! 6: #define DEBUG_SPINLOCKS 0 /* 0 == no debugging, 1 == maintain lock state, 2 == full debug */ ! 7: ! 8: #if (DEBUG_SPINLOCKS < 1) ! 9: ! 10: /* ! 11: * Your basic spinlocks, allowing only a single CPU anywhere ! 12: * ! 13: * Gcc-2.7.x has a nasty bug with empty initializers. ! 14: */ ! 15: #if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8) ! 16: typedef struct { } spinlock_t; ! 17: #define SPIN_LOCK_UNLOCKED (spinlock_t) { } ! 18: #else ! 19: typedef struct { int gcc_is_buggy; } spinlock_t; ! 20: #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } ! 21: #endif ! 22: ! 23: #define spin_lock_init(lock) do { } while(0) ! 24: #define spin_lock(lock) (void)(lock) /* Not "unused variable". */ ! 25: #define spin_trylock(lock) (1) ! 26: #define spin_unlock_wait(lock) do { } while(0) ! 27: #define spin_unlock(lock) do { } while(0) ! 28: #define spin_lock_irq(lock) cli() ! 29: #define spin_unlock_irq(lock) sti() ! 30: ! 31: #define spin_lock_irqsave(lock, flags) \ ! 32: do { save_flags(flags); cli(); } while (0) ! 33: #define spin_unlock_irqrestore(lock, flags) \ ! 34: restore_flags(flags) ! 35: ! 36: #elif (DEBUG_SPINLOCKS < 2) ! 37: ! 38: typedef struct { ! 39: volatile unsigned int lock; ! 40: } spinlock_t; ! 41: #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } ! 42: ! 43: #define spin_lock_init(x) do { (x)->lock = 0; } while (0) ! 44: #define spin_trylock(lock) (!test_and_set_bit(0,(lock))) ! 45: ! 46: #define spin_lock(x) do { (x)->lock = 1; } while (0) ! 47: #define spin_unlock_wait(x) do { } while (0) ! 48: #define spin_unlock(x) do { (x)->lock = 0; } while (0) ! 49: #define spin_lock_irq(x) do { cli(); spin_lock(x); } while (0) ! 50: #define spin_unlock_irq(x) do { spin_unlock(x); sti(); } while (0) ! 51: ! 52: #define spin_lock_irqsave(x, flags) \ ! 53: do { save_flags(flags); spin_lock_irq(x); } while (0) ! 54: #define spin_unlock_irqrestore(x, flags) \ ! 55: do { spin_unlock(x); restore_flags(flags); } while (0) ! 56: ! 57: #else /* (DEBUG_SPINLOCKS >= 2) */ ! 58: ! 59: typedef struct { ! 60: volatile unsigned int lock; ! 61: volatile unsigned int babble; ! 62: const char *module; ! 63: } spinlock_t; ! 64: #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0, 25, __BASE_FILE__ } ! 65: ! 66: #include <linux/kernel.h> ! 67: ! 68: #define spin_lock_init(x) do { (x)->lock = 0; } while (0) ! 69: #define spin_trylock(lock) (!test_and_set_bit(0,(lock))) ! 70: ! 71: #define spin_lock(x) do {unsigned long __spinflags; save_flags(__spinflags); cli(); if ((x)->lock&&(x)->babble) {printk("%s:%d: spin_lock(%s:%p) already locked\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} (x)->lock = 1; restore_flags(__spinflags);} while (0) ! 72: #define spin_unlock_wait(x) do {unsigned long __spinflags; save_flags(__spinflags); cli(); if ((x)->lock&&(x)->babble) {printk("%s:%d: spin_unlock_wait(%s:%p) deadlock\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} restore_flags(__spinflags);} while (0) ! 73: #define spin_unlock(x) do {unsigned long __spinflags; save_flags(__spinflags); cli(); if (!(x)->lock&&(x)->babble) {printk("%s:%d: spin_unlock(%s:%p) not locked\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} (x)->lock = 0; restore_flags(__spinflags);} while (0) ! 74: #define spin_lock_irq(x) do {cli(); if ((x)->lock&&(x)->babble) {printk("%s:%d: spin_lock_irq(%s:%p) already locked\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} (x)->lock = 1;} while (0) ! 75: #define spin_unlock_irq(x) do {cli(); if (!(x)->lock&&(x)->babble) {printk("%s:%d: spin_unlock_irq(%s:%p) not locked\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} (x)->lock = 0; sti();} while (0) ! 76: ! 77: #define spin_lock_irqsave(x,flags) do {save_flags(flags); cli(); if ((x)->lock&&(x)->babble) {printk("%s:%d: spin_lock_irqsave(%s:%p) already locked\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} (x)->lock = 1;} while (0) ! 78: #define spin_unlock_irqrestore(x,flags) do {cli(); if (!(x)->lock&&(x)->babble) {printk("%s:%d: spin_unlock_irqrestore(%s:%p) not locked\n", __BASE_FILE__,__LINE__, (x)->module, (x));(x)->babble--;} (x)->lock = 0; restore_flags(flags);} while (0) ! 79: ! 80: #endif /* DEBUG_SPINLOCKS */ ! 81: ! 82: /* ! 83: * Read-write spinlocks, allowing multiple readers ! 84: * but only one writer. ! 85: * ! 86: * NOTE! it is quite common to have readers in interrupts ! 87: * but no interrupt writers. For those circumstances we ! 88: * can "mix" irq-safe locks - any writer needs to get a ! 89: * irq-safe write-lock, but readers can get non-irqsafe ! 90: * read-locks. ! 91: * ! 92: * Gcc-2.7.x has a nasty bug with empty initializers. ! 93: */ ! 94: #if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8) ! 95: typedef struct { } rwlock_t; ! 96: #define RW_LOCK_UNLOCKED (rwlock_t) { } ! 97: #else ! 98: typedef struct { int gcc_is_buggy; } rwlock_t; ! 99: #define RW_LOCK_UNLOCKED (rwlock_t) { 0 } ! 100: #endif ! 101: ! 102: #define read_lock(lock) (void)(lock) /* Not "unused variable." */ ! 103: #define read_unlock(lock) do { } while(0) ! 104: #define write_lock(lock) (void)(lock) /* Not "unused variable." */ ! 105: #define write_unlock(lock) do { } while(0) ! 106: #define read_lock_irq(lock) cli() ! 107: #define read_unlock_irq(lock) sti() ! 108: #define write_lock_irq(lock) cli() ! 109: #define write_unlock_irq(lock) sti() ! 110: ! 111: #define read_lock_irqsave(lock, flags) \ ! 112: do { save_flags(flags); cli(); } while (0) ! 113: #define read_unlock_irqrestore(lock, flags) \ ! 114: restore_flags(flags) ! 115: #define write_lock_irqsave(lock, flags) \ ! 116: do { save_flags(flags); cli(); } while (0) ! 117: #define write_unlock_irqrestore(lock, flags) \ ! 118: restore_flags(flags) ! 119: ! 120: #else /* __SMP__ */ ! 121: ! 122: /* ! 123: * Your basic spinlocks, allowing only a single CPU anywhere ! 124: */ ! 125: ! 126: typedef struct { ! 127: volatile unsigned int lock; ! 128: } spinlock_t; ! 129: ! 130: #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } ! 131: ! 132: #define spin_lock_init(x) do { (x)->lock = 0; } while(0) ! 133: /* ! 134: * Simple spin lock operations. There are two variants, one clears IRQ's ! 135: * on the local processor, one does not. ! 136: * ! 137: * We make no fairness assumptions. They have a cost. ! 138: */ ! 139: ! 140: #define spin_unlock_wait(x) do { barrier(); } while(((volatile spinlock_t *)(x))->lock) ! 141: ! 142: typedef struct { unsigned long a[100]; } __dummy_lock_t; ! 143: #define __dummy_lock(lock) (*(__dummy_lock_t *)(lock)) ! 144: ! 145: /* ! 146: * Intel PIV would benefit from using 'rep nop' here but on older ! 147: * processors and non intel it is listed as 'undefined' so cannot be ! 148: * blindly used. On 2.4 we should add a PIV CPU type for this one. ! 149: */ ! 150: #define spin_lock_string \ ! 151: "\n1:\t" \ ! 152: "lock ; btsl $0,%0\n\t" \ ! 153: "jc 2f\n" \ ! 154: ".section .text.lock,\"ax\"\n" \ ! 155: "2:\t" \ ! 156: "rep; nop\n\t" \ ! 157: "testb $1,%0\n\t" \ ! 158: "jne 2b\n\t" \ ! 159: "jmp 1b\n" \ ! 160: ".previous" ! 161: ! 162: #define spin_unlock_string \ ! 163: "lock ; btrl $0,%0" ! 164: ! 165: #define spin_lock(lock) \ ! 166: __asm__ __volatile__( \ ! 167: spin_lock_string \ ! 168: :"=m" (__dummy_lock(lock))) ! 169: ! 170: #define spin_unlock(lock) \ ! 171: __asm__ __volatile__( \ ! 172: spin_unlock_string \ ! 173: :"=m" (__dummy_lock(lock))) ! 174: ! 175: #define spin_trylock(lock) (!test_and_set_bit(0,(lock))) ! 176: ! 177: #define spin_lock_irq(lock) \ ! 178: do { __cli(); spin_lock(lock); } while (0) ! 179: ! 180: #define spin_unlock_irq(lock) \ ! 181: do { spin_unlock(lock); __sti(); } while (0) ! 182: ! 183: #define spin_lock_irqsave(lock, flags) \ ! 184: do { __save_flags(flags); __cli(); spin_lock(lock); } while (0) ! 185: ! 186: #define spin_unlock_irqrestore(lock, flags) \ ! 187: do { spin_unlock(lock); __restore_flags(flags); } while (0) ! 188: ! 189: /* ! 190: * Read-write spinlocks, allowing multiple readers ! 191: * but only one writer. ! 192: * ! 193: * NOTE! it is quite common to have readers in interrupts ! 194: * but no interrupt writers. For those circumstances we ! 195: * can "mix" irq-safe locks - any writer needs to get a ! 196: * irq-safe write-lock, but readers can get non-irqsafe ! 197: * read-locks. ! 198: */ ! 199: typedef struct { ! 200: volatile unsigned int lock; ! 201: unsigned long previous; ! 202: } rwlock_t; ! 203: ! 204: #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 } ! 205: ! 206: /* ! 207: * On x86, we implement read-write locks as a 32-bit counter ! 208: * with the high bit (sign) being the "write" bit. ! 209: * ! 210: * The inline assembly is non-obvious. Think about it. ! 211: */ ! 212: #define read_lock(rw) \ ! 213: asm volatile("\n1:\t" \ ! 214: "lock ; incl %0\n\t" \ ! 215: "js 2f\n" \ ! 216: ".section .text.lock,\"ax\"\n" \ ! 217: "2:\tlock ; decl %0\n" \ ! 218: "3:\trep; nop\n\t" \ ! 219: "cmpl $0,%0\n\t" \ ! 220: "js 3b\n\t" \ ! 221: "jmp 1b\n" \ ! 222: ".previous" \ ! 223: :"=m" (__dummy_lock(&(rw)->lock))) ! 224: ! 225: #define read_unlock(rw) \ ! 226: asm volatile("lock ; decl %0" \ ! 227: :"=m" (__dummy_lock(&(rw)->lock))) ! 228: ! 229: #define write_lock(rw) \ ! 230: asm volatile("\n1:\t" \ ! 231: "lock ; btsl $31,%0\n\t" \ ! 232: "jc 4f\n" \ ! 233: "2:\ttestl $0x7fffffff,%0\n\t" \ ! 234: "jne 3f\n" \ ! 235: ".section .text.lock,\"ax\"\n" \ ! 236: "3:\tlock ; btrl $31,%0\n" \ ! 237: "4:\trep; nop\n\t" \ ! 238: "cmp $0,%0\n\t" \ ! 239: "jne 4b\n\t" \ ! 240: "jmp 1b\n" \ ! 241: ".previous" \ ! 242: :"=m" (__dummy_lock(&(rw)->lock))) ! 243: ! 244: #define write_unlock(rw) \ ! 245: asm volatile("lock ; btrl $31,%0":"=m" (__dummy_lock(&(rw)->lock))) ! 246: ! 247: #define read_lock_irq(lock) do { __cli(); read_lock(lock); } while (0) ! 248: #define read_unlock_irq(lock) do { read_unlock(lock); __sti(); } while (0) ! 249: #define write_lock_irq(lock) do { __cli(); write_lock(lock); } while (0) ! 250: #define write_unlock_irq(lock) do { write_unlock(lock); __sti(); } while (0) ! 251: ! 252: #define read_lock_irqsave(lock, flags) \ ! 253: do { __save_flags(flags); __cli(); read_lock(lock); } while (0) ! 254: #define read_unlock_irqrestore(lock, flags) \ ! 255: do { read_unlock(lock); __restore_flags(flags); } while (0) ! 256: #define write_lock_irqsave(lock, flags) \ ! 257: do { __save_flags(flags); __cli(); write_lock(lock); } while (0) ! 258: #define write_unlock_irqrestore(lock, flags) \ ! 259: do { write_unlock(lock); __restore_flags(flags); } while (0) ! 260: ! 261: #endif /* __SMP__ */ ! 262: #endif /* __ASM_SPINLOCK_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.