* sysdeps/mips/pspinlock.c (__pthread_spin_lock): Implement for
authorAndreas Jaeger <aj@suse.de>
Fri, 28 Jul 2000 13:36:23 +0000 (13:36 +0000)
committerAndreas Jaeger <aj@suse.de>
Fri, 28 Jul 2000 13:36:23 +0000 (13:36 +0000)
R3K.
* sysdeps/mips/pt-machine.h (testandset): Likewise.
2000-07-12  Maciej W. Rozycki  <macro@ds2.pg.gda.pl>

* sysdeps/mips/pspinlock.c (__pthread_spin_lock): Implement for
R3K.
* sysdeps/mips/pt-machine.h (testandset): Likewise.

linuxthreads/ChangeLog
linuxthreads/sysdeps/mips/pspinlock.c
linuxthreads/sysdeps/mips/pt-machine.h

index 88549fd..3366f8c 100644 (file)
@@ -1,3 +1,9 @@
+2000-07-12  Maciej W. Rozycki  <macro@ds2.pg.gda.pl>
+
+       * sysdeps/mips/pspinlock.c (__pthread_spin_lock): Implement for
+       R3K.
+       * sysdeps/mips/pt-machine.h (testandset): Likewise.
+
 2000-07-26  Andreas Jaeger  <aj@suse.de>
 
        * pthread.c: Initialize p_sem_avail.
index 906fb4a..7df3040 100644 (file)
 
 #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;
 }
index 50765b1..16e2640 100644 (file)
    You should have received a copy of the GNU Library General Public
    License along with the GNU C Library; see the file COPYING.LIB.  If
    not, write to the Free Software Foundation, Inc.,
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-   TODO: This version makes use of MIPS ISA 2 features.  It won't
-   work on ISA 1.  These machines will have to take the overhead of
-   a sysmips(MIPS_ATOMIC_SET, ...) syscall which isn't implemented
-   yet correctly.  There is however a better solution for R3000
-   uniprocessor machines possible.  */
+#include <sgidefs.h>
+#include <sys/tas.h>
 
 #ifndef PT_EI
 # define PT_EI extern inline
 
 
 /* Spinlock implementation; required.  */
+
+#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
+
 PT_EI long int
 testandset (int *spinlock)
 {
   long int ret, temp;
 
-  __asm__ __volatile__(
-       "# Inline spinlock test & set\n\t"
-       ".set\tmips2\n"
-       "1:\tll\t%0,%3\n\t"
-       "bnez\t%0,2f\n\t"
-       ".set\tnoreorder\n\t"
-       "li\t%1,1\n\t"
-       ".set\treorder\n\t"
-       "sc\t%1,%2\n\t"
-       "beqz\t%1,1b\n"
-       "2:\t.set\tmips0\n\t"
-       "/* End spinlock test & set */"
-       : "=&r"(ret), "=&r" (temp), "=m"(*spinlock)
-       : "m"(*spinlock)
-       : "memory");
+  __asm__ __volatile__
+    ("/* Inline spinlock test & set */\n\t"
+     "1:\n\t"
+     "ll       %0,%3\n\t"
+     ".set     push\n\t"
+     ".set     noreorder\n\t"
+     "bnez     %0,2f\n\t"
+     " li      %1,1\n\t"
+     ".set     pop\n\t"
+     "sc       %1,%2\n\t"
+     "beqz     %1,1b\n"
+     "2:\n\t"
+     "/* End spinlock test & set */"
+     : "=&r" (ret), "=&r" (temp), "=m" (*spinlock)
+     : "m" (*spinlock)
+     : "memory");
 
   return ret;
 }
 
+#else /* !(_MIPS_ISA >= _MIPS_ISA_MIPS2) */
+
+PT_EI long int
+testandset (int *spinlock)
+{
+  return _test_and_set (spinlock, 1);
+}
+#endif /* !(_MIPS_ISA >= _MIPS_ISA_MIPS2) */
+
 
 /* Get some notion of the current stack.  Need not be exactly the top
    of the stack, just something somewhere in the current frame.  */
@@ -68,27 +78,32 @@ register char * stack_pointer __asm__ ("$29");
 
 /* Compare-and-swap for semaphores. */
 
+#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
+
 #define HAS_COMPARE_AND_SWAP
 PT_EI int
 __compare_and_swap (long int *p, long int oldval, long int newval)
 {
-  long ret;
-
-  __asm__ __volatile__ (
-       "/* Inline compare & swap */\n\t"
-       ".set\tmips2\n"
-       "1:\tll\t%0,%4\n\t"
-       ".set\tnoreorder\n\t"
-       "bne\t%0,%2,2f\n\t"
-       "move\t%0,%3\n\t"
-       ".set\treorder\n\t"
-       "sc\t%0,%1\n\t"
-       "beqz\t%0,1b\n"
-       "2:\t.set\tmips0\n\t"
-       "/* End compare & swap */"
-       : "=&r"(ret), "=m"(*p)
-       : "r"(oldval), "r"(newval), "m"(*p)
-       : "memory");
+  long int ret;
+
+  __asm__ __volatile__
+    ("/* Inline compare & swap */\n\t"
+     "1:\n\t"
+     "ll       %0,%4\n\t"
+     ".set     push\n"
+     ".set     noreorder\n\t"
+     "bne      %0,%2,2f\n\t"
+     " move    %0,%3\n\t"
+     ".set     pop\n\t"
+     "sc       %0,%1\n\t"
+     "beqz     %0,1b\n"
+     "2:\n\t"
+     "/* End compare & swap */"
+     : "=&r" (ret), "=m" (*p)
+     : "r" (oldval), "r" (newval), "m" (*p)
+     : "memory");
 
   return ret;
 }
+
+#endif /* (_MIPS_ISA >= _MIPS_ISA_MIPS2) */