00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #if defined(USE_NPTL)
00028
00029 #include <pthread.h>
00030 #define spin_lock pthread_mutex_lock
00031 #define spin_unlock pthread_mutex_unlock
00032 #define spinlock_t pthread_mutex_t
00033 #define SPIN_LOCK_UNLOCKED PTHREAD_MUTEX_INITIALIZER
00034
00035 #else
00036
00037 #if defined(__hppa__)
00038
00039 typedef int spinlock_t[4];
00040
00041 #define SPIN_LOCK_UNLOCKED { 1, 1, 1, 1 }
00042
00043 static inline void resetlock (spinlock_t *p)
00044 {
00045 (*p)[0] = (*p)[1] = (*p)[2] = (*p)[3] = 1;
00046 }
00047
00048 #else
00049
00050 typedef int spinlock_t;
00051
00052 #define SPIN_LOCK_UNLOCKED 0
00053
00054 static inline void resetlock (spinlock_t *p)
00055 {
00056 *p = SPIN_LOCK_UNLOCKED;
00057 }
00058
00059 #endif
00060
00061 #if defined(_ARCH_PPC)
00062 static inline int testandset (int *p)
00063 {
00064 int ret;
00065 __asm__ __volatile__ (
00066 " lwarx %0,0,%1\n"
00067 " xor. %0,%3,%0\n"
00068 " bne $+12\n"
00069 " stwcx. %2,0,%1\n"
00070 " bne- $-16\n"
00071 : "=&r" (ret)
00072 : "r" (p), "r" (1), "r" (0)
00073 : "cr0", "memory");
00074 return ret;
00075 }
00076 #elif defined(__i386__)
00077 static inline int testandset (int *p)
00078 {
00079 long int readval = 0;
00080
00081 __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
00082 : "+m" (*p), "+a" (readval)
00083 : "r" (1)
00084 : "cc");
00085 return readval;
00086 }
00087 #elif defined(__x86_64__)
00088 static inline int testandset (int *p)
00089 {
00090 long int readval = 0;
00091
00092 __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
00093 : "+m" (*p), "+a" (readval)
00094 : "r" (1)
00095 : "cc");
00096 return readval;
00097 }
00098 #elif defined(__s390__)
00099 static inline int testandset (int *p)
00100 {
00101 int ret;
00102
00103 __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n"
00104 " jl 0b"
00105 : "=&d" (ret)
00106 : "r" (1), "a" (p), "0" (*p)
00107 : "cc", "memory" );
00108 return ret;
00109 }
00110 #elif defined(__alpha__)
00111 static inline int testandset (int *p)
00112 {
00113 int ret;
00114 unsigned long one;
00115
00116 __asm__ __volatile__ ("0: mov 1,%2\n"
00117 " ldl_l %0,%1\n"
00118 " stl_c %2,%1\n"
00119 " beq %2,1f\n"
00120 ".subsection 2\n"
00121 "1: br 0b\n"
00122 ".previous"
00123 : "=r" (ret), "=m" (*p), "=r" (one)
00124 : "m" (*p));
00125 return ret;
00126 }
00127 #elif defined(__sparc__)
00128 static inline int testandset (int *p)
00129 {
00130 int ret;
00131
00132 __asm__ __volatile__("ldstub [%1], %0"
00133 : "=r" (ret)
00134 : "r" (p)
00135 : "memory");
00136
00137 return (ret ? 1 : 0);
00138 }
00139 #elif defined(__arm__)
00140 static inline int testandset (int *spinlock)
00141 {
00142 register unsigned int ret;
00143 __asm__ __volatile__("swp %0, %1, [%2]"
00144 : "=r"(ret)
00145 : "0"(1), "r"(spinlock));
00146
00147 return ret;
00148 }
00149 #elif defined(__mc68000)
00150 static inline int testandset (int *p)
00151 {
00152 char ret;
00153 __asm__ __volatile__("tas %1; sne %0"
00154 : "=r" (ret)
00155 : "m" (p)
00156 : "cc","memory");
00157 return ret;
00158 }
00159 #elif defined(__hppa__)
00160
00161
00162
00163
00164
00165
00166
00167
00168 #define __PA_LDCW_ALIGNMENT 16
00169 static inline void *ldcw_align (void *p) {
00170 unsigned long a = (unsigned long)p;
00171 a = (a + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1);
00172 return (void *)a;
00173 }
00174
00175 static inline int testandset (spinlock_t *p)
00176 {
00177 unsigned int ret;
00178 p = ldcw_align(p);
00179 __asm__ __volatile__("ldcw 0(%1),%0"
00180 : "=r" (ret)
00181 : "r" (p)
00182 : "memory" );
00183 return !ret;
00184 }
00185
00186 #elif defined(__ia64)
00187
00188 #include <ia64intrin.h>
00189
00190 static inline int testandset (int *p)
00191 {
00192 return __sync_lock_test_and_set (p, 1);
00193 }
00194 #elif defined(__mips__)
00195 static inline int testandset (int *p)
00196 {
00197 int ret;
00198
00199 __asm__ __volatile__ (
00200 " .set push \n"
00201 " .set noat \n"
00202 " .set mips2 \n"
00203 "1: li $1, 1 \n"
00204 " ll %0, %1 \n"
00205 " sc $1, %1 \n"
00206 " beqz $1, 1b \n"
00207 " .set pop "
00208 : "=r" (ret), "+R" (*p)
00209 :
00210 : "memory");
00211
00212 return ret;
00213 }
00214 #else
00215 #error unimplemented CPU support
00216 #endif
00217
00218 #if defined(CONFIG_USER_ONLY)
00219 static inline void spin_lock(spinlock_t *lock)
00220 {
00221 while (testandset(lock));
00222 }
00223
00224 static inline void spin_unlock(spinlock_t *lock)
00225 {
00226 resetlock(lock);
00227 }
00228
00229 static inline int spin_trylock(spinlock_t *lock)
00230 {
00231 return !testandset(lock);
00232 }
00233 #else
00234 static inline void spin_lock(spinlock_t *lock)
00235 {
00236 }
00237
00238 static inline void spin_unlock(spinlock_t *lock)
00239 {
00240 }
00241
00242 static inline int spin_trylock(spinlock_t *lock)
00243 {
00244 return 1;
00245 }
00246 #endif
00247
00248 #endif