]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fixed pthread_spin_lock on sparc32/64 (bug 16882) release/2.17/master
authorGuo Yixuan <culu.gyx@gmail.com>
Tue, 3 Jun 2014 23:19:11 +0000 (16:19 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 3 Jun 2014 23:43:08 +0000 (16:43 -0700)
[BZ #16882]
* nptl/sysdeps/sparc/sparc32/pthread_spin_lock.S
(pthread_spin_lock): Branch out of spin loop to proper location.
* nptl/sysdeps/sparc/sparc64/pthread_spin_lock.S
(pthread_spin_lock): Likewise.

* nptl/tst-spin4.c: New test.
* nptl/Makefile (tests): Add tst-spin4.

ChangeLog
NEWS
nptl/Makefile
nptl/sysdeps/sparc/sparc32/pthread_spin_lock.S
nptl/sysdeps/sparc/sparc64/pthread_spin_lock.S
nptl/tst-spin4.c [new file with mode: 0644]

index ef667cc9b9a4c29c50224e69ac477e5f0aeeb413..97227c97b6675b5af7b40d306c4f616d8e955d42 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2014-06-03  Guo Yixuan  <culu.gyx@gmail.com>
+
+       [BZ #16882]
+       * nptl/sysdeps/sparc/sparc32/pthread_spin_lock.S
+       (pthread_spin_lock): Branch out of spin loop to proper location.
+       * nptl/sysdeps/sparc/sparc64/pthread_spin_lock.S
+       (pthread_spin_lock): Likewise.
+
+       * nptl/tst-spin4.c: New test.
+       * nptl/Makefile (tests): Add tst-spin4.
+
 2014-05-17  Jose E. Marchesi  <jose.marchesi@oracle.com>
 
        [BZ #16958]
diff --git a/NEWS b/NEWS
index 9ab955a3015fe2fca0b005e2b3116451284e2f73..7df114b79af98333f28e6b63622655755bf579e8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -29,7 +29,7 @@ Version 2.17
   14767, 14783, 14784, 14785, 14793, 14796, 14797, 14801, 14803, 14805,
   14807, 14811, 14815, 14821, 14822, 14824, 14828, 14831, 14833, 14835,
   14838, 14856, 14863, 14865, 14866, 14868, 14869, 14871, 14872, 14879,
-  14889, 14893, 14898, 14914.
+  14889, 14893, 14898, 14914, 16882.
 
 * Optimization of memcpy for MIPS.
 
index e33432ee8a6bdd7ac4aec1942b6897122a8f7c75..5d820b29cde77d77bf4fae64abe9dc7f98084bce 100644 (file)
@@ -207,7 +207,7 @@ tests = tst-typesizes \
        tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
        tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a tst-mutexpi8 \
        tst-mutexpi9 \
-       tst-spin1 tst-spin2 tst-spin3 \
+       tst-spin1 tst-spin2 tst-spin3 tst-spin4 \
        tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
        tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
        tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
index 3155121700bd8d2682ce49b71b210729cf2062f0..703dbca69dd375a3076a74da33a4a3ac86da8ea0 100644 (file)
 
        .text
 ENTRY(pthread_spin_lock)
-       ldstub          [%o0], %g1
+1:     ldstub          [%o0], %g1
        orcc            %g1, 0x0, %g0
        bne,a           2f
         ldub           [%o0], %g1
-1:     retl
+       retl
         mov            0, %o0
 2:     orcc            %g1, 0x0, %g0
        bne,a           2b
index cd3b01fcb069c9425c4ead8fd0a6b2910980540f..d52c4a6b41a977bb28be482b73c46e29702f4e33 100644 (file)
 
        .text
 ENTRY(pthread_spin_lock)
-       ldstub          [%o0], %g1
+1:     ldstub          [%o0], %g1
        brnz,pn         %g1, 2f
         membar         #StoreLoad | #StoreStore
-1:     retl
+       retl
         mov            0, %o0
 2:     ldub            [%o0], %g1
        brnz,pt         %g1, 2b
diff --git a/nptl/tst-spin4.c b/nptl/tst-spin4.c
new file mode 100644 (file)
index 0000000..5b23a17
--- /dev/null
@@ -0,0 +1,109 @@
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static int count = 0;
+
+static void *
+thread_add_one (void *arg)
+{
+  int tmp;
+  pthread_spinlock_t *lock = (pthread_spinlock_t *) arg;
+
+  /* When do_test holds the lock for 1 sec, the two thread will be
+     in contention for the lock. */
+  if (pthread_spin_lock (lock) != 0)
+    {
+      puts ("thread_add_one(): spin_lock failed");
+      pthread_exit ((void *) 1l);
+    }
+
+  /* sleep 1s before modifying count */
+  tmp = count;
+  sleep (1);
+  count = tmp + 1;
+
+  if (pthread_spin_unlock (lock) != 0)
+    {
+      puts ("thread_add_one(): spin_unlock failed");
+      pthread_exit ((void *) 1l);
+    }
+
+  return NULL;
+}
+
+static int
+do_test (void)
+{
+  pthread_t thr1, thr2;
+  pthread_spinlock_t lock;
+  int tmp;
+
+  if (pthread_spin_init (&lock, PTHREAD_PROCESS_PRIVATE) != 0)
+    {
+      puts ("spin_init failed");
+      return 1;
+    }
+
+  if (pthread_spin_lock (&lock) != 0)
+    {
+      puts ("1st spin_lock failed");
+      return 1;
+    }
+
+  if (pthread_create (&thr1, NULL, thread_add_one, (void *) &lock) != 0)
+    {
+      puts ("1st pthread_create failed");
+      return 1;
+    }
+
+  if (pthread_create (&thr2, NULL, thread_add_one, (void *) &lock) != 0)
+    {
+      puts ("2nd pthread_create failed");
+      return 1;
+    }
+
+  /* sleep 1s before modifying count */
+  tmp = count;
+  sleep (1);
+  count = tmp + 1;
+
+  if (pthread_spin_unlock (&lock) != 0)
+    {
+      puts ("1st spin_unlock failed");
+      return 1;
+    }
+
+  void *status;
+  if (pthread_join (thr1, &status) != 0)
+    {
+      puts ("1st pthread_join failed");
+      return 1;
+    }
+  if (status != NULL)
+    {
+      puts ("failure in the 1st thread");
+      return 1;
+    }
+  if (pthread_join (thr2, &status) != 0)
+    {
+      puts ("2nd pthread_join failed");
+      return 1;
+    }
+  if (status != NULL)
+    {
+      puts ("failure in the 2nd thread");
+      return 1;
+    }
+
+  if (count != 3)
+    {
+      printf ("count is %d, should be 3\n", count);
+      return 1;
+    }
+  return 0;
+}
+
+#define TIMEOUT 5
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"