]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fixed pthread_spin_lock on sparc32/64 (bug 16882)
authorGuo Yixuan <culu.gyx@gmail.com>
Tue, 3 Jun 2014 23:19:11 +0000 (16:19 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 4 Jun 2014 00:20:08 +0000 (17:20 -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 2a14ec2399f0da1ba8114467e324507c48612fcd..9c95cc05b9d9ffe93504bd8c311cf0ab6e26da14 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 4cbe73644e10a1672b80e221da44572668a7abfe..31664e40cc5ac04afd63d59a6d969b329b2ec4b4 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -29,7 +29,7 @@ Version 2.18
   15429, 15431, 15432, 15441, 15442, 15448, 15465, 15480, 15485, 15488,
   15490, 15492, 15493, 15497, 15506, 15529, 15536, 15553, 15577, 15583,
   15618, 15627, 15631, 15654, 15655, 15666, 15667, 15674, 15711, 15755,
-  15759, 15985.
+  15759, 15985, 16882.
 
 * CVE-2013-2207 Incorrectly granting access to another user's pseudo-terminal
   has been fixed by disabling the use of pt_chown (Bugzilla #15755).
index cd601e5f5a06035113c8cc4e442c572c21e21888..9f02c68506323a26594ba40b6776fc9f41ff6260 100644 (file)
@@ -208,7 +208,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 7099f2984a3702c35a8fcfa9ea9267277431a2d7..ad13681412a997944d8cd9bb822a3cdbaa1c2264 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 11091e900ba2af694405a4227ec6702591361020..8896a71c9aa6127086fccd7ddc08f3cff1ed4a34 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"