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

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

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

  1 #ifndef _ASM_IA64_SPINLOCK_H
  2 #define _ASM_IA64_SPINLOCK_H
  3 
  4 /*
  5  * Copyright (C) 1998-2000 Hewlett-Packard Co
  6  * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
  7  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
  8  *
  9  * This file is used for SMP configurations only.
 10  */
 11 
 12 #include <linux/kernel.h>
 13 
 14 #include <asm/system.h>
 15 #include <asm/bitops.h>
 16 #include <asm/atomic.h>
 17 
 18 #undef NEW_LOCK
 19 
 20 #ifdef NEW_LOCK
 21 
 22 typedef struct { 
 23         volatile unsigned int lock;
 24 } spinlock_t;
 25 
 26 #define SPIN_LOCK_UNLOCKED                      (spinlock_t) { 0 }
 27 #define spin_lock_init(x)                       ((x)->lock = 0) 
 28 
 29 /*
 30  * Streamlined test_and_set_bit(0, (x)).  We use test-and-test-and-set
 31  * rather than a simple xchg to avoid writing the cache-line when
 32  * there is contention.
 33  */
 34 #define spin_lock(x)                                                                    \
 35 {                                                                                       \
 36         register char *addr __asm__ ("r31") = (char *) &(x)->lock;                      \
 37                                                                                         \
 38         __asm__ __volatile__ (                                                          \
 39                 "mov r30=1\n"                                                           \
 40                 "mov ar.ccv=r0\n"                                                       \
 41                 ";;\n"                                                                  \
 42                 IA64_SEMFIX"cmpxchg4.acq r30=[%0],r30,ar.ccv\n"                         \
 43                 ";;\n"                                                                  \
 44                 "cmp.ne p15,p0=r30,r0\n"                                                \
 45                 "(p15) br.call.spnt.few b7=ia64_spinlock_contention\n"                  \
 46                 ";;\n"                                                                  \
 47                 "1:\n"                          /* force a new bundle */                \
 48                 :: "r"(addr)                                                            \
 49                 : "ar.ccv", "ar.pfs", "b7", "p15", "r28", "r29", "r30", "memory");      \
 50 }
 51 
 52 #define spin_trylock(x)                                                                 \
 53 ({                                                                                      \
 54         register long result;                                                           \
 55                                                                                         \
 56         __asm__ __volatile__ (                                                          \
 57                 "mov ar.ccv=r0\n"                                                       \
 58                 ";;\n"                                                                  \
 59                 IA64_SEMFIX"cmpxchg4.acq %0=[%2],%1,ar.ccv\n"                           \
 60                 : "=r"(result) : "r"(1), "r"(&(x)->lock) : "ar.ccv", "memory");         \
 61         (result == 0);                                                                  \
 62 })
 63 
 64 #define spin_is_locked(x)       ((x)->lock != 0)
 65 #define spin_unlock(x)          do {((spinlock_t *) x)->lock = 0;} while (0)
 66 #define spin_unlock_wait(x)     do {} while ((x)->lock)
 67 
 68 #else /* !NEW_LOCK */
 69 
 70 typedef struct { 
 71         volatile unsigned int lock;
 72 } spinlock_t;
 73 
 74 #define SPIN_LOCK_UNLOCKED                      (spinlock_t) { 0 }
 75 #define spin_lock_init(x)                       ((x)->lock = 0)
 76 
 77 /*
 78  * Streamlined test_and_set_bit(0, (x)).  We use test-and-test-and-set
 79  * rather than a simple xchg to avoid writing the cache-line when
 80  * there is contention.
 81  */
 82 #define spin_lock(x) __asm__ __volatile__ (                     \
 83         "mov ar.ccv = r0\n"                                     \
 84         "mov r29 = 1\n"                                         \
 85         ";;\n"                                                  \
 86         "1:\n"                                                  \
 87         "ld4 r2 = [%0]\n"                                       \
 88         ";;\n"                                                  \
 89         "cmp4.eq p0,p7 = r0,r2\n"                               \
 90         "(p7) br.cond.spnt.few 1b \n"                           \
 91         IA64_SEMFIX"cmpxchg4.acq r2 = [%0], r29, ar.ccv\n"      \
 92         ";;\n"                                                  \
 93         "cmp4.eq p0,p7 = r0, r2\n"                              \
 94         "(p7) br.cond.spnt.few 1b\n"                            \
 95         ";;\n"                                                  \
 96         :: "r"(&(x)->lock) : "r2", "r29", "memory")
 97 
 98 #define spin_is_locked(x)       ((x)->lock != 0)
 99 #define spin_unlock(x)          do {((spinlock_t *) x)->lock = 0; barrier(); } while (0)
100 #define spin_trylock(x)         (cmpxchg_acq(&(x)->lock, 0, 1) == 0)
101 #define spin_unlock_wait(x)     do { barrier(); } while ((x)->lock)
102 
103 #endif /* !NEW_LOCK */
104 
105 typedef struct {
106         volatile int read_counter:31;
107         volatile int write_lock:1;
108 } rwlock_t;
109 #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
110 
111 #define read_lock(rw)                                                           \
112 do {                                                                            \
113         int tmp = 0;                                                            \
114         __asm__ __volatile__ ("1:\t"IA64_SEMFIX"fetchadd4.acq %0 = [%1], 1\n"   \
115                               ";;\n"                                            \
116                               "tbit.nz p6,p0 = %0, 31\n"                        \
117                               "(p6) br.cond.sptk.few 2f\n"                      \
118                               ".section .text.lock,\"ax\"\n"                    \
119                               "2:\t"IA64_SEMFIX"fetchadd4.rel %0 = [%1], -1\n"  \
120                               ";;\n"                                            \
121                               "3:\tld4.acq %0 = [%1]\n"                         \
122                               ";;\n"                                            \
123                               "tbit.nz p6,p0 = %0, 31\n"                        \
124                               "(p6) br.cond.sptk.few 3b\n"                      \
125                               "br.cond.sptk.few 1b\n"                           \
126                               ";;\n"                                            \
127                               ".previous\n"                                     \
128                               : "=&r" (tmp)                                     \
129                               : "r" (rw): "memory");                            \
130 } while(0)
131 
132 #define read_unlock(rw)                                                         \
133 do {                                                                            \
134         int tmp = 0;                                                            \
135         __asm__ __volatile__ (IA64_SEMFIX"fetchadd4.rel %0 = [%1], -1\n"        \
136                               : "=r" (tmp)                                      \
137                               : "r" (rw)                                        \
138                               : "memory");                                      \
139 } while(0)
140 
141 #define write_lock(rw)                                                          \
142 do {                                                                            \
143         __asm__ __volatile__ (                                                  \
144                 "mov ar.ccv = r0\n"                                             \
145                 "movl r29 = 0x80000000\n"                                       \
146                 ";;\n"                                                          \
147                 "1:\n"                                                          \
148                 "ld4 r2 = [%0]\n"                                               \
149                 ";;\n"                                                          \
150                 "cmp4.eq p0,p7 = r0,r2\n"                                       \
151                 "(p7) br.cond.spnt.few 1b \n"                                   \
152                 IA64_SEMFIX"cmpxchg4.acq r2 = [%0], r29, ar.ccv\n"              \
153                 ";;\n"                                                          \
154                 "cmp4.eq p0,p7 = r0, r2\n"                                      \
155                 "(p7) br.cond.spnt.few 1b\n"                                    \
156                 ";;\n"                                                          \
157                 :: "r"(rw) : "r2", "r29", "memory");                            \
158 } while(0)
159 
160 /*
161  * clear_bit() has "acq" semantics; we're really need "rel" semantics,
162  * but for simplicity, we simply do a fence for now...
163  */
164 #define write_unlock(x)                         ({clear_bit(31, (x)); mb();})
165 
166 #endif /*  _ASM_IA64_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.