aboutsummaryrefslogtreecommitdiff
path: root/linuxthreads/sysdeps/mips/pspinlock.c
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads/sysdeps/mips/pspinlock.c')
-rw-r--r--linuxthreads/sysdeps/mips/pspinlock.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/linuxthreads/sysdeps/mips/pspinlock.c b/linuxthreads/sysdeps/mips/pspinlock.c
index 906fb4ae60..7df3040bda 100644
--- a/linuxthreads/sysdeps/mips/pspinlock.c
+++ b/linuxthreads/sysdeps/mips/pspinlock.c
@@ -19,8 +19,12 @@
#include <errno.h>
#include <pthread.h>
+#include <sgidefs.h>
+#include <sys/tas.h>
+#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
+
/* This implementation is similar to the one used in the Linux kernel. */
int
__pthread_spin_lock (pthread_spinlock_t *lock)
@@ -28,22 +32,34 @@ __pthread_spin_lock (pthread_spinlock_t *lock)
unsigned int tmp;
asm volatile
- (".set\tnoreorder\t\t\t# spin_lock\n"
- ".set\tpush\n"
- ".set\tmips2\n"
- "1:\tll\t%1, %2\n\t"
- "bnez\t%1, 1b\n\t"
- " li\t%1, 1\n\t"
- "sc\t%1, %0\n\t"
- "beqz\t%1, 1b\n\t"
- ".set\tpop\n"
- ".set\treorder"
- : "=o" (*lock), "=&r" (tmp)
- : "o" (*lock)
+ ("\t\t\t# spin_lock\n\t"
+ "1:\n\t"
+ "ll %1,%2\n\t"
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ "bnez %1,1b\n\t"
+ " li %1,1\n\t"
+ ".set pop\n\t"
+ "sc %1,%0\n\t"
+ "beqz %1,1b"
+ : "=m" (*lock), "=&r" (tmp)
+ : "m" (*lock)
: "memory");
return 0;
}
+
+#else /* !(_MIPS_ISA >= _MIPS_ISA_MIPS2) */
+
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+ while (_test_and_set (lock, 1));
+ return 0;
+}
+
+#endif /* !(_MIPS_ISA >= _MIPS_ISA_MIPS2) */
+
weak_alias (__pthread_spin_lock, pthread_spin_lock)
@@ -60,11 +76,10 @@ int
__pthread_spin_unlock (pthread_spinlock_t *lock)
{
asm volatile
- (".set\tnoreorder\t\t\t# spin_unlock\n\t"
- "sw\t$0, %0\n\t"
- ".set\treorder"
- : "=o" (*lock)
- : "o" (*lock)
+ ("\t\t\t# spin_unlock\n\t"
+ "sw $0,%0"
+ : "=m" (*lock)
+ :
: "memory");
return 0;
}