This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC/PATCH] RT-NPTL-2.3 4/7


pthread_mutexattr_setunlock_np.c         |   35 ++++
 sysdeps/pthread/pthread.h                |  148 ++++++++++++++++++++
 sysdeps/unix/sysv/linux/Makefile         |    3 
 sysdeps/unix/sysv/linux/internaltypes.h  |   23 +++
 sysdeps/unix/sysv/linux/lowlevelrtlock.c |  227
+++++++++++++++++++++++++++++++
 tst-fast1.c                              |  117 +++++++++++++++
 tst-options1.c                           |   46 ++++++
 tst-serial1.c                            |  119 ++++++++++++++++
 8 files changed, 716 insertions(+), 2 deletions(-)

--- /dev/null	Fri Jul 23 03:18:16 2004
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_setunlock_np.c
Tue May 25 05:16:58 2004
@@ -0,0 +1,35 @@
+/*
+ *  (C) 2004 Intel Corporation
+ *  Boris Hu <boris.hu@intel.com>
+ *
+ *  Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <errno.h>
+#include <pthreadP.h>
+
+
+int pthread_mutexattr_setunlock_np (pthread_mutexattr_t *attr,
+                                    int fast_mode)
+{
+  struct pthread_mutexattr *iattr;
+
+  iattr = (struct pthread_mutexattr *) attr;
+
+  iattr->mutexkind &= ~FULOCK_UNLOCK_TYPE_MASK;
+  switch (fast_mode) {
+  case PTHREAD_MUTEX_UNLOCK_SERIAL_NP:
+    iattr->mutexkind |= (FULOCK_UNLOCK_SERIAL <<
FULOCK_UNLOCK_TYPE_OFFSET); 
+    break;
+  case PTHREAD_MUTEX_UNLOCK_PARALLEL_NP:
+    iattr->mutexkind |= (FULOCK_UNLOCK_PARALLEL <<
FULOCK_UNLOCK_TYPE_OFFSET);
+    break;
+  case PTHREAD_MUTEX_UNLOCK_AUTO_NP:
+    iattr->mutexkind |= (FULOCK_UNLOCK_AUTO <<
FULOCK_UNLOCK_TYPE_OFFSET);
+    break;
+  default:
+    return EINVAL;
+  }
+  
+  return 0;
+}
--- /dev/null	Fri Jul 23 03:18:16 2004
+++ robustmutexes/rtnptl/src/nptl/tst-fast1.c	Tue May 11 12:01:35 2004
@@ -0,0 +1,117 @@
+/*
+ *  (C) 2004 Intel Corporation
+ *  Boris Hu <boris.hu@intel.com>
+ *
+ *  Distributed under the FSF's LGPL license, v2 or later. */
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static pthread_mutex_t m;
+static pthread_barrier_t b;
+
+
+static void *
+tf (void *arg)
+{
+  if (pthread_mutex_lock (&m) != 0) {
+    puts ("child mutex_lock fail");
+    exit (1);
+  }
+
+  int e = pthread_barrier_wait (&b);
+  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) {
+    puts ("child barrier_wait fail");
+    exit (1);
+  }
+    
+  return NULL;
+}
+
+
+static int
+do_test (void)
+{
+  pthread_mutexattr_t a;
+
+  if (pthread_mutexattr_init (&a) != 0) {
+    puts ("mutexattr_init failed");
+    return 1;
+  }
+
+  if (pthread_mutexattr_setfast_np (&a, PTHREAD_MUTEX_SLOWPATH_NP) !=
0) {
+    puts ("mutexattr_setfast_np failed");
+    return 1;
+  }
+
+  if (pthread_mutexattr_setrobust_np (&a, PTHREAD_MUTEX_ROBUST_NP) !=
0) {
+    puts ("mutexattr_setrobust_np failed");
+    return 1;
+  }
+    
+  if (pthread_mutex_init (&m, &a) != 0) {
+    puts ("mutex_init failed");
+    return 1;
+  }
+
+  if (pthread_barrier_init (&b, NULL, 2) != 0) {
+    puts ("barrier_init failed");
+    return 1;
+  }
+
+  pthread_t th;
+
+  if (pthread_create (&th, NULL, tf, NULL) != 0) {
+    puts ("create failed");
+    return 1;
+  }
+
+  int e = pthread_barrier_wait (&b);
+  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) {
+    puts ("barrier_wait fail");
+    return 1;
+  }
+  
+  if (pthread_mutex_lock (&m) != EOWNERDEAD)
+    {
+      puts ("main mutex_lock failed");
+      return 1;
+    }
+
+  if (pthread_mutex_unlock (&m) != 0)
+    {
+      puts ("main mutex_unlock failed");
+      return 1;
+    }
+
+  if (pthread_join (th, NULL) != 0)
+    {
+      puts ("join failed");
+      return 1;
+    }
+
+  if (pthread_barrier_destroy (&b) != 0)
+    {
+      puts ("barrier_destroy failed");
+      return 1;
+    }
+
+  if (pthread_mutex_destroy (&m) != 0)
+    {
+      puts ("mutex_destroy failed");
+      return 1;
+    }
+
+  if (pthread_mutexattr_destroy (&a) != 0)
+    {
+      puts ("mutexattr_destroy failed");
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
--- /dev/null	Fri Jul 23 03:18:17 2004
+++ robustmutexes/rtnptl/src/nptl/tst-options1.c	Sat May 15
06:24:14 2004
@@ -0,0 +1,46 @@
+/*
+ *  (C) 2004 Intel Corporation
+ *  Boris Hu <boris.hu@intel.com>
+ *
+ *  Distributed under the FSF's LGPL license, v2 or later. */
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int
+do_test (void)
+{
+  int ret;
+
+  ret = sysconf (_SC_THREAD_ROBUST_MUTEX_NP);
+  if (-1 == ret) {
+    puts ("Robust Mutexes Feature doesn't support!");
+    exit (1);
+  }
+  else
+    puts ("Robust Mutexes Feature supports!");
+
+  ret = sysconf (_SC_THREAD_MUTEX_SERIAL_NP);
+  if (-1 == ret) {
+    puts ("Mutex Serial/Unserial Switching Extention doesn't
support!");
+    exit (1);
+  }
+  else
+    puts ("Mutex Serial/Unserial Switching Extention supports!");
+
+  ret = sysconf (_SC_THREAD_MUTEX_FAST_NP);
+  if (-1 == ret) {
+    puts ("Mutex Fastpath/Slowpath Switching Extention doesn't
support!");
+    exit (1);
+  }
+  else
+    puts ("Mutex Fastpath/Slowpath Switching Extention supports!");
+
+  return 0;
+
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
--- /dev/null	Fri Jul 23 03:18:17 2004
+++ robustmutexes/rtnptl/src/nptl/tst-serial1.c	Thu May 27 01:39:57 2004
@@ -0,0 +1,119 @@
+/*
+ *  (C) 2004 Intel Corporation
+ *  Boris Hu <boris.hu@intel.com>
+ *
+ *  Distributed under the FSF's LGPL license, v2 or later. */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static pthread_mutex_t m;
+static pthread_barrier_t b;
+
+
+static void *
+tf (void *arg)
+{
+  if (pthread_mutex_lock (&m) != 0) {
+    puts ("child mutex_lock fail");
+    exit (1);
+  }
+
+  int e = pthread_barrier_wait (&b);
+  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) {
+    puts ("child barrier_wait fail");
+    exit (1);
+  }
+    
+  return NULL;
+}
+
+
+static int
+do_test (void)
+{
+  pthread_mutexattr_t a;
+
+  if (pthread_mutexattr_init (&a) != 0) {
+    puts ("mutexattr_init failed");
+    return 1;
+  }
+
+  if (pthread_mutexattr_setrobust_np (&a, PTHREAD_MUTEX_ROBUST_NP) !=
0) {
+    puts ("mutexattr_setrobust_np failed");
+    return 1;
+  }
+
+  if (pthread_mutexattr_setunlock_np (
+       &a,PTHREAD_MUTEX_UNLOCK_PARALLEL_NP) != 0) {
+    puts ("mutexattr_setserial_np failed");
+    return 1;
+  }
+
+  if (pthread_mutex_init (&m, &a) != 0) {
+    puts ("mutex_init failed");
+    return 1;
+  }
+
+  if (pthread_barrier_init (&b, NULL, 2) != 0) {
+    puts ("barrier_init failed");
+    return 1;
+  }
+
+  pthread_t th;
+
+  if (pthread_create (&th, NULL, tf, NULL) != 0) {
+    puts ("create failed");
+    return 1;
+  }
+
+  int e = pthread_barrier_wait (&b);
+  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) {
+    puts ("barrier_wait fail");
+    return 1;
+  }
+  
+  if (pthread_mutex_lock (&m) != EOWNERDEAD)
+    {
+      puts ("main mutex_lock failed");
+      return 1;
+    }
+
+  if (pthread_mutex_unlock (&m) != 0)
+    {
+      puts ("main mutex_unlock failed");
+      return 1;
+    }
+
+  if (pthread_join (th, NULL) != 0)
+    {
+      puts ("join failed");
+      return 1;
+    }
+
+  if (pthread_barrier_destroy (&b) != 0)
+    {
+      puts ("barrier_destroy failed");
+      return 1;
+    }
+
+  if (pthread_mutex_destroy (&m) != 0)
+    {
+      puts ("mutex_destroy failed");
+      return 1;
+    }
+
+  if (pthread_mutexattr_destroy (&a) != 0)
+    {
+      puts ("mutexattr_destroy failed");
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
--- robustmutexes/rtnptl/src/nptl/sysdeps/pthread/pthread.h:1.1.1.1.2.1
Fri Mar 26 02:41:38 2004
+++ robustmutexes/rtnptl/src/nptl/sysdeps/pthread/pthread.h	Mon Jun
7 05:21:35 2004
@@ -59,6 +59,56 @@
 #endif
 };
 
+/* Robust mutex types. */
+enum
+{
+  PTHREAD_MUTEX_NOROBUST_NP,
+  PTHREAD_MUTEX_ROBUST_NP,
+#define PTHREAD_MUTEX_ROBUST_NP PTHREAD_MUTEX_ROBUST_NP
+  PTHREAD_MUTEX_ROBUST2_NP
+#define PTHREAD_MUTEX_ROBUST2_NP PTHREAD_MUTEX_ROBUST2_NP  
+};
+
+/* Mutex Switching Modes. */
+enum
+{
+  PTHREAD_MUTEX_FASTPATH_NP,
+#define PTHREAD_MUTEX_FASTPATH_NP       PTHREAD_MUTEX_FASTPATH_NP
+  PTHREAD_MUTEX_SLOWPATH_NP,
+#define PTHREAD_MUTEX_SLOWPATH_NP       PTHREAD_MUTEX_SLOWPATH_NP
+  PTHREAD_MUTEX_UNLOCK_SERIAL_NP,
+#define PTHREAD_MUTEX_UNLOCK_SERIAL_NP  PTHREAD_MUTEX_UNLOCK_SERIAL_NP

+  PTHREAD_MUTEX_UNLOCK_PARALLEL_NP,
+#define PTHREAD_MUTEX_UNLOCK_PARALLEL_NP
PTHREAD_MUTEX_UNLOCK_PARALLEL_NP
+  PTHREAD_MUTEX_UNLOCK_AUTO_NP,
+#define PTHREAD_MUTEX_UNLOCK_AUTO_NP    PTHREAD_MUTEX_UNLOCK_AUTO_NP  
+  PTHREAD_MUTEX_SPIN_NP,
+#define PTHREAD_MUTEX_SPIN_NP           PTHREAD_MUTEX_SPIN_NP
+  PTHREAD_MUTEX_UNSPIN_NP
+#define PTHREAD_MUTEX_UNSPIN_NP         PTHREAD_MUTEX_UNSPIN_NP
+};
+
+/* Robust mutex states. */
+enum
+{
+  PTHREAD_MUTEX_ROBUST_NOP_NP=0,
+  PTHREAD_MUTEX_ROBUST_CONSISTENT_NP,
+  PTHREAD_MUTEX_ROBUST_NOTRECOVERABLE_NP,
+  PTHREAD_MUTEX_ROBUST_RELEASE_NP,
+  PTHREAD_MUTEX_ROBUST_INIT_NP = PTHREAD_MUTEX_ROBUST_RELEASE_NP
+};
+
+/* Mutex protocols. */
+enum
+{
+  PTHREAD_PRIO_NONE=1,
+  PTHREAD_PRIO_INHERIT,
+#define PTHREAD_PRIO_INHERIT	PTHREAD_PRIO_INHERIT
+  PTHREAD_PRIO_PROTECT
+#define PTHREAD_PRIO_PROTECT	PTHREAD_PRIO_PROTECT
+};
+
+
 /* Mutex initializers.  */
 #define PTHREAD_MUTEX_INITIALIZER \
   { }
@@ -685,6 +735,104 @@
 /* Set the process-shared flag of the mutex attribute ATTR.  */
 extern int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr,
 					 int __pshared) __THROW;
+
+/* Get the mutex-robust flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getrobust_np (__const pthread_mutexattr_t
*
+					   __restrict __attr,
+					   int *__restrict __robusttype)
__THROW;
+
+/* Set the mutex-robust flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr,
+					   int __robusttype) __THROW;
+
+/* Get the fast-path flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_getfast_np (__const pthread_mutexattr_t
*__attr,
+                                         int *__restrict __fast_mode)
__THROW;
+
+/* Set the fast-path flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_setfast_np (pthread_mutexattr_t *
+                                         __restrict __attr,
+                                         int __fast_mode) __THROW;
+
+/* Get the serial flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_getunlock_np (__const pthread_mutexattr_t
*__attr,
+                                           int *__restrict
+                                           __serial_mode) __THROW;
+
+/* Set the serial flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_setunlock_np (pthread_mutexattr_t *
+                                           __restrict __attr,
+                                           int __serial_mode) __THROW;
+
+/* Get the spin flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_getspin_np (__const pthread_mutexattr_t
*__attr,
+                                         int *__restrict __spin_mode)
__THROW;
+
+/* Set the spin flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_setspin_np (pthread_mutexattr_t *
+                                         __restrict __attr,
+                                         int __spin_mode) __THROW;
+
+/* Set the mutex to given state  */
+extern int pthread_mutex_setconsistency_np (pthread_mutex_t *
+                                            __restrict __mutex,
+					    int __state) __THROW;
+
+/* Set the mutex to consistent state  */
+extern int pthread_mutex_consistent_np (pthread_mutex_t *
+                                        __restrict __mutex) __THROW;
+
+/* Get the mutex state  */
+extern int pthread_mutex_getconsistency_np (pthread_mutex_t *
+                                            __restrict __mutex,
+					    int *__restrict __state)
__THROW;
+/* Access fusyn layer interface */
+extern int pthread_mutex_ctl_np (pthread_mutex_t *
+                                 __restrict __mutex,
+                                 int __ctl) __THROW;
+
+/* Get the procotol of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_getprotocol (__const pthread_mutexattr_t *
+					  __restrict __attr,
+					  int *__restrict __protocol)
__THROW;
+
+/* Set the procotol of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_setprotocol (pthread_mutexattr_t *__attr,
+					  int __protocol) __THROW;
+
+/* Get the priority ceiling value of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getprioceiling (__const
pthread_mutexattr_t *
+                                             __restrict __attr,
+                                             int *__restrict
__prioceiling) __THROW;
+
+/* Set the priority ceiling value of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setprioceiling (pthread_mutexattr_t
*__restrict __attr,
+                                             int __prioceiling)
__THROW;
+
+/* Get the priority ceiling value of the mutex. */
+extern int pthread_mutex_getprioceiling (__const pthread_mutex_t *
+                                         __restrict __mutex,
+                                         int *__restrict __prioceiling)
__THROW;
+
+/* Set the priority ceiling value of the mutex. */
+extern int pthread_mutex_setprioceiling (pthread_mutex_t *__restrict
__mutex,
+                                         int __prioceiling,
+                                         int *__restrict __old_ceiling)
__THROW;
+
+/* Get the serial flag of the mutex.  */
+extern int pthread_mutex_getunlock_np (__const pthread_mutex_t *
+                                       __restrict __mutex,
+                                       int *__restrict __serial_mode)
__THROW;
+
+/* Set the serial flag of the mutex.  */
+extern int pthread_mutex_setunlock_np (pthread_mutex_t *__restrict
__mutex,
+                                       int __serial_mode) __THROW;
+
+extern int pthread_mutex_whose_owner_dead_np (pthread_mutex_t 
+                                              *__restrict __mutex,
+                                              const struct timespec
+                                              *__restrict __reltime)
__THROW;
+
 
 #ifdef __USE_UNIX98
 /* Return in *KIND the mutex kind attribute in *ATTR.  */
---
robustmutexes/rtnptl/src/nptl/sysdeps/unix/sysv/linux/Makefile:1.1.1.1.2
.1	Tue Jan  6 06:34:06 2004
+++ robustmutexes/rtnptl/src/nptl/sysdeps/unix/sysv/linux/Makefile
Wed Jul 14 08:49:27 2004
@@ -21,7 +21,8 @@
 sysdep_routines += register-atfork unregister-atfork libc_pthread_init
\
 		   libc_multiple_threads
 
-libpthread-sysdep_routines += pt-fork pthread_mutex_cond_lock
+libpthread-sysdep_routines += pt-fork pthread_mutex_cond_lock \
+				pthread_mutex_rq_lock
 
 gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \
 			lowlevelbarrier.sym unwindbuf.sym
---
robustmutexes/rtnptl/src/nptl/sysdeps/unix/sysv/linux/internaltypes.h:1.
1.1.1.2.3	Fri Mar 26 02:41:40 2004
+++
robustmutexes/rtnptl/src/nptl/sysdeps/unix/sysv/linux/internaltypes.h
Fri Jun 11 08:40:58 2004
@@ -48,7 +48,21 @@
 #define ATTR_FLAG_SCHED_SET		0x0020
 #define ATTR_FLAG_POLICY_SET		0x0040
 
+/* Priority Protection Ceiling Mask. */
+#define PRIOCEILING_MASK                0x0007f800
+#define PRIOCEILING_OFFSET              11
+#define MIN_USER_RT_PRIO                1
+#define MAX_USER_RT_PRIO                100
 
+/* Bit set if fast-path mode. */
+#define FULOCK_FASTPATH_MODE            0x04000000
+/* Bit set if serial mode. */
+#define FULOCK_UNLOCK_TYPE_MASK         0x03000000
+#define FULOCK_UNLOCK_TYPE_OFFSET       24
+
+#define NON_MUTEX_KIND_MASK             (0xf80000 |
FULOCK_FASTPATH_MODE \
+                                         | FULOCK_UNLOCK_TYPE_MASK
\
+                                         | PRIOCEILING_MASK)
 /* Mutex attribute data structure.  */
 struct pthread_mutexattr
 {
@@ -56,7 +70,14 @@
 
      Bit 31 is set if the mutex is to be shared between processes.
 
-     Bit 0 to 30 contain one of the PTHREAD_MUTEX_ values to identify
+     Flags for realtime mutex extension.
+        Bit 30 and 29 for mutex protocol attributes.
+        Bit 28 and 27 for mutex robustness attributes.
+        Bit 26 for fulock fast-path and KCO mode switching flag.
+        Bit 25 and 24 for fulock serialization switching flag.
+        Bit 11-19 to record priority ceiling value.
+     
+     Bits left contain one of the PTHREAD_MUTEX_ values to identify
      the type of the mutex.  */
   int mutexkind;
 };
--- /dev/null	Fri Jul 23 03:18:17 2004
+++
robustmutexes/rtnptl/src/nptl/sysdeps/unix/sysv/linux/lowlevelrtlock.c
Wed Jun  9 12:38:03 2004
@@ -0,0 +1,227 @@
+/*
+ *  (C) 2003 Intel Corporation
+ *  Boris Hu <boris.hu@intel.com>
+ *
+ *  Distributed under the FSF's LGPL license, v2 or later. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <pthread.h>
+#include <pthreadP.h>
+#include <lowlevellock.h>
+#include <sys/time.h>
+#include <atomic.h>
+
+#include <linux/fulock.h>
+
+inline int
+__attribute__ ((always_inline))
+is_mutex_robust (const pthread_mutex_t *mutex)
+{
+  return (mutex->__data.__kind & ((FULOCK_FL_RM | FULOCK_FL_RM_SUN) >>
1));
+}
+
+
+inline int
+__attribute__ ((always_inline))
+is_mutexattr_robust (const struct pthread_mutexattr *attr)
+{
+  return (attr->mutexkind & ((FULOCK_FL_RM | FULOCK_FL_RM_SUN) >> 1));
+}
+
+
+inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_trylock (volatile int *vfulock, unsigned flags,
+                       unsigned rtflags, unsigned tid)
+{
+  unsigned old_value;
+  int result;
+  INTERNAL_SYSCALL_DECL (err);
+
+restart:
+  if (flags & FULOCK_FL_KCO)
+    goto kco_mode;
+
+  result = EBUSY;
+  old_value = atomic_compare_and_exchange_val_acq (vfulock, tid,
VFULOCK_UNLOCKED);
+  if (old_value == VFULOCK_UNLOCKED) /* If it was unlocked, fulock
acquired */
+    result = 0;
+  else if (old_value == VFULOCK_NR)
+    result = ENOTRECOVERABLE;
+  else if ((old_value == VFULOCK_WP))
+    result = EBUSY;
+  else if (flags & FULOCK_FL_RM)
+  {
+  kco_mode: 
+    result = INTERNAL_SYSCALL (ufulock_lock, err, 3, vfulock, flags,
0);
+    if (INTERNAL_SYSCALL_ERROR_P (result, err))
+      result = INTERNAL_SYSCALL_ERRNO (result, err);
+
+    switch (result)
+      {
+      case 0:
+      case EBUSY:
+      case ETIMEDOUT:
+      case EOWNERDEAD:
+      case ENOTRECOVERABLE:
+        return result;
+      default:
+          goto restart;
+      }
+  }
+  return result;    /* Taken (waiters in kernel)! */
+}
+
+
+inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_timedlock (volatile int *vfulock, unsigned flags,
+                         unsigned rtflags, unsigned pid,
+                         const struct timeout *timeout)
+{
+  int result;
+  INTERNAL_SYSCALL_DECL (err);
+  
+restart:
+  if (!(flags & FULOCK_FL_KCO)
+      && ! atomic_compare_and_exchange_bool_acq (vfulock, pid,
VFULOCK_UNLOCKED))
+    return 0;
+
+  //FIXME: should we respin it again? for pthread_mutex_lock has done
it.
+  //  int cnt = 0;
+  //  int max_cnt = MIN (MAX_ADAPTIVE_COUNT,
+  //                   mutex->__data.__spins * 2 + 10);
+  //if (cnt++  < max_cnt)
+  //  goto restart;
+      
+  result = INTERNAL_SYSCALL (ufulock_lock, err, 3, vfulock, flags,
timeout);
+ 
+  result = INTERNAL_SYSCALL_ERROR_P (result, err)
+    ? INTERNAL_SYSCALL_ERRNO (result, err) : result;
+
+  //  mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8;
+  
+  switch (result)
+  {
+  case 0:
+  case EBUSY:
+  case ETIMEDOUT:
+  case EOWNERDEAD:
+  case ENOTRECOVERABLE:
+    return result;
+  default:
+    goto restart;
+  }
+  return 0;  /* Lock acquired. */
+}
+
+
+inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_lock (volatile int *vfulock, unsigned flags,
+                    unsigned rtflags, unsigned tid)
+{
+  return __lll_rtmutex_timedlock (vfulock, flags, rtflags,
+                                  tid, (const void *) ~0);
+}
+
+
+inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_unlock (volatile int *vfulock, unsigned flags,
+                      unsigned rtflags, unsigned tid)
+{
+  int result = EPERM;
+  unsigned old_value;
+  INTERNAL_SYSCALL_DECL (err);
+
+  if (flags & FULOCK_FL_KCO)
+    goto kco_mode;
+  while (1)
+  {
+    old_value = *vfulock;
+    if (old_value == VFULOCK_NR)
+    {
+      result = ENOTRECOVERABLE;
+      break;
+    }
+    else if (old_value >= VFULOCK_WP)
+    {
+    kco_mode:
+      result = INTERNAL_SYSCALL (ufulock_unlock, err, 3, vfulock,
flags,
+                                 (rtflags & FULOCK_UNLOCK_TYPE_MASK)
+                                 >> FULOCK_UNLOCK_TYPE_OFFSET);
+      if (INTERNAL_SYSCALL_ERROR_P (result, err)) {
+        result = INTERNAL_SYSCALL_ERRNO (result, err);
+        break;
+      }
+      break;
+    }
+    else if (! atomic_compare_and_exchange_bool_acq (vfulock,
VFULOCK_UNLOCKED,
+                                                     old_value)) {
+      result = 0;
+      break;
+    }
+  }    
+  return result;
+}
+
+
+inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_unlock_nocheck (volatile int *vfulock, unsigned flags,
+                              unsigned rtflags)
+{
+  int result; 
+  INTERNAL_SYSCALL_DECL (err);
+
+  result = INTERNAL_SYSCALL (ufulock_unlock, err, 3, vfulock, flags,
0);
+  return INTERNAL_SYSCALL_ERROR_P (result, err)
+    ? INTERNAL_SYSCALL_ERRNO (result, err)
+    : result;
+}
+
+
+inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_set_consistency (volatile int *vfulock,
+                               unsigned flags, unsigned rtflags,
+                               enum fulock_ctl consistency)
+{
+  int result;
+  INTERNAL_SYSCALL_DECL (err);
+
+  result = INTERNAL_SYSCALL (ufulock_ctl, err, 3, vfulock,
+                             flags, consistency);
+  return INTERNAL_SYSCALL_ERROR_P (result, err)
+    ? INTERNAL_SYSCALL_ERRNO (result, err)
+    : result;
+}
+
+
+inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_get_consistency (volatile int *vfulock, unsigned flags,
+                               unsigned rtflags, int *state)
+{
+  int result;
+  INTERNAL_SYSCALL_DECL (err);
+  
+  result = INTERNAL_SYSCALL (ufulock_ctl, err, 3, vfulock, flags, 0);
+  if (! INTERNAL_SYSCALL_ERROR_P (result, err))
+    *state = result;
+  return 0;
+}
+
+
+int
+__lll_rtmutex_ctl (volatile int *vfulock, unsigned flags, int ctl)
+{
+  int result;
+  INTERNAL_SYSCALL_DECL (err);
+  
+  result = INLINE_SYSCALL (ufulock_ctl, 3, vfulock, flags, ctl);
+  return result;
+}s

Boris Hu (Hu Jiangtao)
Intel China Software Center 
86-021-5257-4545#1277
iNET: 8-752-1277
************************************
There are my thoughts, not my employer's.
************************************
"gpg --recv-keys --keyserver wwwkeys.pgp.net 0FD7685F"
{0FD7685F:CFD6 6F5C A2CB 7881 725B  CEA0 956F 9F14 0FD7 685F}

Attachment: rtnptl-2.3.patch-3
Description: rtnptl-2.3.patch-3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]