2006-03-02 Lior Balkohen <balkohen@gmail.com>
authorDaniel Jacobowitz <dan@codesourcery.com>
Fri, 3 Mar 2006 01:16:30 +0000 (01:16 +0000)
committerDaniel Jacobowitz <dan@codesourcery.com>
Fri, 3 Mar 2006 01:16:30 +0000 (01:16 +0000)
* sysdeps/unix/sysv/linux/mips/nptl/bits/pthreadtypes.h
(__pthread_list_t, __pthread_slist_t): New typedefs.
(pthread_mutex_t): Replace __next and __prev fields with __list.
* sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h (FUTEX_WAKE_OP,
FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
(lll_futex_wake_unlock): Define.
(lll_robust_mutex_dead, lll_robust_mutex_trylock, lll_robust_mutex_lock,
lll_robust_mutex_cond_lock, lll_robust_mutex_timedlock,
lll_robust_mutex_unlock): New macros.
(__lll_robust_lock_wait, __lll_robust_timedlock_wait): New prototypes.
* sysdeps/unix/sysv/linux/mips/nptl/pt-vfork.S: Use correct path to
vfork.S.
* sysdeps/unix/sysv/linux/mips/nptl/vfork.S: Likewise.

ChangeLog.mips
sysdeps/unix/sysv/linux/mips/nptl/bits/pthreadtypes.h
sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h
sysdeps/unix/sysv/linux/mips/nptl/pt-vfork.S
sysdeps/unix/sysv/linux/mips/nptl/vfork.S

index 32566f9..7debe9d 100644 (file)
@@ -1,3 +1,19 @@
+2006-03-02  Lior Balkohen  <balkohen@gmail.com>
+
+       * sysdeps/unix/sysv/linux/mips/nptl/bits/pthreadtypes.h
+       (__pthread_list_t, __pthread_slist_t): New typedefs.
+       (pthread_mutex_t): Replace __next and __prev fields with __list.
+       * sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h (FUTEX_WAKE_OP,
+       FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+       (lll_futex_wake_unlock): Define.
+       (lll_robust_mutex_dead, lll_robust_mutex_trylock, lll_robust_mutex_lock,
+       lll_robust_mutex_cond_lock, lll_robust_mutex_timedlock,
+       lll_robust_mutex_unlock): New macros.
+       (__lll_robust_lock_wait, __lll_robust_timedlock_wait): New prototypes.  
+       * sysdeps/unix/sysv/linux/mips/nptl/pt-vfork.S: Use correct path to
+       vfork.S.
+       * sysdeps/unix/sysv/linux/mips/nptl/vfork.S: Likewise.
+
 2006-03-02  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * sysdeps/unix/sysv/linux/mips/ptrace.c: Delete file.
index d5e89a9..eda0a2f 100644 (file)
@@ -55,6 +55,20 @@ typedef union
 } pthread_attr_t;
 
 
+#if _MIPS_SIM == _ABI64
+typedef struct __pthread_internal_list
+{
+  struct __pthread_internal_list *__prev;
+  struct __pthread_internal_list *__next;
+} __pthread_list_t;
+#else
+typedef struct __pthread_internal_slist
+{
+  struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+#endif
+
+
 /* Data structures for mutex handling.  The structure of the attribute
    type is deliberately not exposed.  */
 typedef union
@@ -72,15 +86,14 @@ typedef union
     int __kind;
 #if _MIPS_SIM == _ABI64
     int __spins;
-    struct __pthread_mutex_s *__next;
-    struct __pthread_mutex_s *__prev;
+    __pthread_list_t __list;
 # define __PTHREAD_MUTEX_HAVE_PREV     1
 #else
     unsigned int __nusers;
     __extension__ union
     {
       int __spins;
-      struct __pthread_mutex_s *__next;
+      __pthread_slist_t __list;
     };
 #endif
   } __data;
index 5e3dd48..d5070e8 100644 (file)
@@ -30,6 +30,8 @@
 #define FUTEX_WAKE             1
 #define FUTEX_REQUEUE          3
 #define FUTEX_CMP_REQUEUE      4
+#define FUTEX_WAKE_OP          5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE  ((4 << 24) | 1)
 
 /* Initializer for compatibility lock. */
 #define LLL_MUTEX_LOCK_INITIALIZER (0)
     INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret;                \
   })
 
+#define lll_robust_mutex_dead(futexv) \
+  do                                                                         \
+    {                                                                        \
+      int *__futexp = &(futexv);                                             \
+      atomic_or (__futexp, FUTEX_OWNER_DIED);                                \
+      lll_futex_wake (__futexp, 1);                                          \
+    }                                                                        \
+  while (0)
+
 /* Returns non-zero if error happened, zero if success.  */
 #define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \
   ({                                                                         \
     INTERNAL_SYSCALL_ERROR_P (__ret, __err);                                 \
   })
 
+/* Returns non-zero if error happened, zero if success.  */
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \
+  ({                                                                         \
+    INTERNAL_SYSCALL_DECL (__err);                                           \
+    long int __ret;                                                          \
+                                                                             \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6,                               \
+                             (futexp), FUTEX_WAKE_OP, (nr_wake),             \
+                             (nr_wake2), (futexp2),                          \
+                             FUTEX_OP_CLEAR_WAKE_IF_GT_ONE);                 \
+    INTERNAL_SYSCALL_ERROR_P (__ret, __err);                                 \
+  })
 
 static inline int __attribute__((always_inline))
 __lll_mutex_trylock(int *futex)
@@ -89,7 +112,16 @@ __lll_mutex_cond_trylock(int *futex)
 #define lll_mutex_cond_trylock(lock)   __lll_mutex_cond_trylock (&(lock))
 
 
+static inline int __attribute__((always_inline))
+__lll_robust_mutex_trylock(int *futex, int id)
+{
+  return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0;
+}
+#define lll_robust_mutex_trylock(lock, id) \
+  __lll_robust_mutex_trylock (&(lock), id)
+
 extern void __lll_lock_wait (int *futex) attribute_hidden;
+extern int __lll_robust_lock_wait (int *futex) attribute_hidden;
 
 static inline void __attribute__((always_inline))
 __lll_mutex_lock(int *futex)
@@ -100,6 +132,18 @@ __lll_mutex_lock(int *futex)
 #define lll_mutex_lock(futex) __lll_mutex_lock (&(futex))
 
 
+static inline int __attribute__ ((always_inline))
+__lll_robust_mutex_lock (int *futex, int id)
+{
+  int result = 0;
+  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+    result = __lll_robust_lock_wait (futex);
+  return result;
+}
+#define lll_robust_mutex_lock(futex, id) \
+  __lll_robust_mutex_lock (&(futex), id)
+
+
 static inline void __attribute__ ((always_inline))
 __lll_mutex_cond_lock (int *futex)
 {
@@ -109,8 +153,14 @@ __lll_mutex_cond_lock (int *futex)
 #define lll_mutex_cond_lock(futex) __lll_mutex_cond_lock (&(futex))
 
 
+#define lll_robust_mutex_cond_lock(futex, id) \
+  __lll_robust_mutex_lock (&(futex), (id) | FUTEX_WAITERS)
+
+
 extern int __lll_timedlock_wait (int *futex, const struct timespec *)
        attribute_hidden;
+extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *)
+       attribute_hidden;
 
 static inline int __attribute__ ((always_inline))
 __lll_mutex_timedlock (int *futex, const struct timespec *abstime)
@@ -124,6 +174,19 @@ __lll_mutex_timedlock (int *futex, const struct timespec *abstime)
   __lll_mutex_timedlock (&(futex), abstime)
 
 
+static inline int __attribute__ ((always_inline))
+__lll_robust_mutex_timedlock (int *futex, const struct timespec *abstime,
+                             int id)
+{
+  int result = 0;
+  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+    result = __lll_robust_timedlock_wait (futex, abstime);
+  return result;
+}
+#define lll_robust_mutex_timedlock(futex, abstime, id) \
+  __lll_robust_mutex_timedlock (&(futex), abstime, id)
+
+
 static inline void __attribute__ ((always_inline))
 __lll_mutex_unlock (int *futex)
 {
@@ -135,6 +198,17 @@ __lll_mutex_unlock (int *futex)
 
 
 static inline void __attribute__ ((always_inline))
+__lll_robust_mutex_unlock (int *futex, int mask)
+{
+  int val = atomic_exchange_rel (futex, 0);
+  if (__builtin_expect (val & mask, 0))
+    lll_futex_wake (futex, 1);
+}
+#define lll_robust_mutex_unlock(futex) \
+  __lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS)
+
+
+static inline void __attribute__ ((always_inline))
 __lll_mutex_unlock_force (int *futex)
 {
   (void) atomic_exchange_rel (futex, 0);
index fe2b81b..652dfb1 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -34,4 +34,4 @@
        sw      a2, PID_OFFSET(v1);     /* Restore the PID.  */         \
 1:
 
-#include <../sysdeps/unix/sysv/linux/mips/vfork.S>
+#include <sysdeps/unix/sysv/linux/mips/vfork.S>
index 874a2e2..b93a924 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -39,4 +39,4 @@
 2:     sw      a2, PID_OFFSET(v1);     /* Restore the PID.  */         \
 1:
 
-#include <../sysdeps/unix/sysv/linux/mips/vfork.S>
+#include <sysdeps/unix/sysv/linux/mips/vfork.S>