[PATCH] Robust and Real-time Mutexes in NPTL

"Liu, Bing Wei" <[email protected]>
Newsgroups gmane.linux.kernel.carrier-grade,gmane.comp.lib.phil
Message-ID <3ACA40606221794F80A5670F0AF15F84FEBB7B@pdsmsx403.ccr.corp.intel.com>
Hi All,

This is a ---prototype implementation--- that extends NPTL with
real-time and robust mutex features.  The intention is to have an
approach to locking that will benefit the applications that care
about responsiveness and robustness of the locks without affecting
other types of applications. Currently this is work in progress, and
the implementation is subject to much flux, both in the user or
kernel code.


Features
=======
- robust mutex
    Applications using a robust mutex can detect whether the previous
owner of the mutex terminated and then pass on the ownership to the
next waiter. The new owner can then attempt to cleanup the state
protected by the mutex, and re-initialize it for continued use.  If
cleanup of the state can't be done, the mutex can be marked
inconsistent so that any future attempts to lock it will get a status
indicating that it is inconsistent.

- priority inheritance mutex
    Applications using a priority inheritance mutex can temporarily
boost the priority of the current owner of the mutex, if a
higher-priority thread is blocked trying to lock the same mutex. This
will help to addresses the priority inversion issue and improve
real-time responsiveness.


Links
====
All related patches, documents, and test cases have been posted at
http://developer.osdl.org/dev/robustmutexes/, including:

- rtnptl-0.5.patch :  robust and real-time mutexes patch for nptl-0.36.
- README-rtnptl-0.5 :  release notes of rtnptl-0.5.
- INSTALL-rtnptl-0.5 :  a sample step-by-step procedure for building
a simple jail root of rtnptl-0.5 based on nptl-0.36
- rtnptl-test-0.5.tar.gz :  test cases for rtnptl-0.5
- README-rtnptl-tests-0.5 :  release notes of rtnptl-test-0.5
- rtfutex-2_5_67-6.patch:  real-time futex (rtfutex) patch for
kernel-2.5.67
- rtfutex-test-6.tar.gz :  test cases for rtfutex-6
- README-rtfutex-6 :  release notes of rtfutex-6
- a few png files to illustrate priority inheritance behavior.


A quick glance at rtnptl-0.5.patch 
========================
 Makefile                                          |    9
 Versions                                          |    5
 init.c                                            |    6
 pthread_mutex_consistent_np.c                     |   16 +
 pthread_mutex_init.c                              |    8
 pthread_mutex_lock.c                              |   26 ++
 pthread_mutex_setconsistency_np.c                 |   22 ++
 pthread_mutex_timedlock.c                         |   33 ++-
 pthread_mutex_trylock.c                           |   37 ++-
 pthread_mutex_unlock.c                            |   30 ++-
 pthread_mutexattr_getprotocol.c                   |   29 +++
 pthread_mutexattr_getrobust_np.c                  |   28 ++
 pthread_mutexattr_init.c                          |    5
 pthread_mutexattr_setprotocol.c                   |   54 +++++
 pthread_mutexattr_setrobust_np.c                  |   36 +++
 sysdeps/pthread/createthread.c                    |   12 +
 sysdeps/pthread/pthread.h                         |   56 +++++
 sysdeps/unix/sysv/linux/fork.c                    |    7
 sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h  |    8
 sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S |  210 ++++++++++
 sysdeps/unix/sysv/linux/i386/lowlevellock.h       |  160 ++++++++++
 sysdeps/unix/sysv/linux/internaltypes.h           |   12 +
 22 files changed, 775 insertions(+), 34 deletions(-)


Thank,
Bingwei Liu

Not speaking for my employer -- all opinions are my own (and my fault)


 <<README-rtnptl-0.5>>  <<rtnptl-0.5.patch>>
README-rtnptl-0.5 (application/octet-stream, 4.2 KB) - not displayed
rtnptl-0.5.patch (application/octet-stream, 42.1 KB)
diff -Naur -x '*CVS*' nptl-0.36/init.c rt___0_5/init.c
--- nptl-0.36/init.c	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/init.c	2003-06-19 13:36:35.000000000 +0800
@@ -2,6 +2,10 @@
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <[email protected]>, 2002.
 
+   Generate a signature for the initial thread, which can be used 
+   for mutexes' ownership checking.
+   Bing Wei Liu <[email protected]>, 2003
+   
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -275,6 +279,8 @@
 #endif
     __libc_pthread_init (&__fork_generation, __reclaim_stacks,
 			 ptr_pthread_functions);
+
+  lll_rtmutex_make_signature(0);
 }
 strong_alias (__pthread_initialize_minimal_internal,
 	      __pthread_initialize_minimal)
diff -Naur -x '*CVS*' nptl-0.36/Makefile rt___0_5/Makefile
--- nptl-0.36/Makefile	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/Makefile	2003-06-19 13:36:35.000000000 +0800
@@ -1,6 +1,9 @@
 # Copyright (C) 2002, 2003 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
+# Add six libpthread-routines about robust and real-time mutexes.
+# Bing Wei Liu <[email protected]>, 2003
+
 # The GNU C Library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 # License as published by the Free Software Foundation; either
@@ -58,6 +61,12 @@
 		      pthread_mutexattr_getpshared \
 		      pthread_mutexattr_setpshared \
 		      pthread_mutexattr_gettype pthread_mutexattr_settype \
+		      pthread_mutexattr_getprotocol \
+		      pthread_mutexattr_setprotocol \
+		      pthread_mutexattr_getrobust_np \
+		      pthread_mutexattr_setrobust_np \
+		      pthread_mutex_consistent_np \
+		      pthread_mutex_setconsistency_np \
 		      pthread_rwlock_init pthread_rwlock_destroy \
 		      pthread_rwlock_rdlock pthread_rwlock_timedrdlock \
 		      pthread_rwlock_wrlock pthread_rwlock_timedwrlock \
diff -Naur -x '*CVS*' nptl-0.36/pthread_mutexattr_getprotocol.c rt___0_5/pthread_mutexattr_getprotocol.c
--- nptl-0.36/pthread_mutexattr_getprotocol.c	1970-01-01 08:00:00.000000000 +0800
+++ rt___0_5/pthread_mutexattr_getprotocol.c	2003-06-19 13:36:35.000000000 +0800
@@ -0,0 +1,29 @@
+/*
+ *  (C) 2002-2003 Intel Corporation
+ *  Bing Wei Liu <[email protected]>.
+ *
+ *  Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <pthreadP.h>
+
+
+int
+pthread_mutexattr_getprotocol (attr, protocol)
+     const pthread_mutexattr_t *attr;
+     int *protocol;
+{
+  const struct pthread_mutexattr *iattr;
+
+  iattr = (const struct pthread_mutexattr *) attr;
+
+  /* Use Bit 0, 1 to indicate the protocol of mutex :
+     -- PTHREAD_PRIO_NONE     (0x00)
+     -- PTHREAD_PRIO_INHERIT  (0x02)
+     -- PTHREAD_PRIO_PROTECT  (0x03)  */
+  *protocol = ((iattr->rtflags & RTFUTEX_FL_PRIO_MASK) == 0
+               ? PTHREAD_PRIO_NONE : ((iattr->rtflags & RTFUTEX_FL_PRIO_MASK) == RTFUTEX_FL_PRIO_INHERIT
+               ? PTHREAD_PRIO_INHERIT : PTHREAD_PRIO_PROTECT));
+
+  return 0;
+}
diff -Naur -x '*CVS*' nptl-0.36/pthread_mutexattr_getrobust_np.c rt___0_5/pthread_mutexattr_getrobust_np.c
--- nptl-0.36/pthread_mutexattr_getrobust_np.c	1970-01-01 08:00:00.000000000 +0800
+++ rt___0_5/pthread_mutexattr_getrobust_np.c	2003-06-19 13:36:35.000000000 +0800
@@ -0,0 +1,28 @@
+/*
+ *  (C) 2002-2003 Intel Corporation
+ *  Bing Wei Liu <[email protected]>.
+ *
+ *  Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <pthreadP.h>
+
+
+int
+pthread_mutexattr_getrobustness (attr, robustness)
+     const pthread_mutexattr_t *attr;
+     int *robustness;
+{
+  const struct pthread_mutexattr *iattr;
+
+  iattr = (const struct pthread_mutexattr *) attr;
+
+  /* Use Bit 2, 3 to indicate the robustness type of mutex :
+     -- PTHREAD_MUTEX_ROBUST_NP     (0x04)
+     -- PTHREAD_MUTEX_ROBUST_SUN_NP (0x0c)  */
+  *robustness = ((iattr->rtflags & RTFUTEX_FL_ROBUST_MASK) == 0
+               ? PTHREAD_MUTEX_STALL_NP : ((iattr->rtflags & RTFUTEX_FL_ROBUST_MASK) == RTFUTEX_FL_ROBUST
+               ? PTHREAD_MUTEX_ROBUST_NP : PTHREAD_MUTEX_ROBUST_SUN_NP));
+
+  return 0;
+}
diff -Naur -x '*CVS*' nptl-0.36/pthread_mutexattr_init.c rt___0_5/pthread_mutexattr_init.c
--- nptl-0.36/pthread_mutexattr_init.c	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/pthread_mutexattr_init.c	2003-06-19 13:36:35.000000000 +0800
@@ -2,6 +2,9 @@
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <[email protected]>, 2002.
 
+   Initialize the 'rtflags' attribute of the mutexattr.
+   Bing Wei Liu <[email protected]>, 2003
+
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -32,6 +35,8 @@
      process-shared or not.  By default it is zero, i.e., the mutex is
      not process-shared.  */
   ((struct pthread_mutexattr *) attr)->mutexkind = PTHREAD_MUTEX_NORMAL;
+  
+  ((struct pthread_mutexattr *) attr)->rtflags = 0;
 
   return 0;
 }
diff -Naur -x '*CVS*' nptl-0.36/pthread_mutexattr_setprotocol.c rt___0_5/pthread_mutexattr_setprotocol.c
--- nptl-0.36/pthread_mutexattr_setprotocol.c	1970-01-01 08:00:00.000000000 +0800
+++ rt___0_5/pthread_mutexattr_setprotocol.c	2003-06-19 13:36:35.000000000 +0800
@@ -0,0 +1,54 @@
+/*
+ *  (C) 2002-2003 Intel Corporation
+ *  Bing Wei Liu <[email protected]>.
+ *
+ *  Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <errno.h>
+#include <pthreadP.h>
+
+/*
+ *  Real-time Extension for NPTL (C) 2002-2003 Intel Corp
+ *  Created by: Bing Wei Liu <[email protected]>.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+  
+int
+pthread_mutexattr_setprotocol (attr, protocol)
+     pthread_mutexattr_t *attr;
+     int protocol;
+{
+  struct pthread_mutexattr *iattr;
+
+  if (protocol < PTHREAD_PRIO_NONE || protocol > PTHREAD_PRIO_PROTECT)
+    return EINVAL;
+
+  iattr = (struct pthread_mutexattr *) attr;
+
+  /* Use Bit 0, 1 to indicate the protocol of mutex :
+     -- PTHREAD_PRIO_NONE     (00)
+     -- PTHREAD_PRIO_INHERIT  (10)
+     -- PTHREAD_PRIO_PROTECT  (11)  */
+  iattr->rtflags &= ~RTFUTEX_FL_PRIO_MASK;	/* Reset Bit 0, 1 */
+  
+  if (protocol == PTHREAD_PRIO_INHERIT)
+      iattr->rtflags |= (RTFUTEX_FL_PRIO_INHERIT | RTFUTEX_FL_ROBUST);
+  else if (protocol == PTHREAD_PRIO_PROTECT)
+      iattr->rtflags |= (RTFUTEX_FL_PRIO_PROTECT | RTFUTEX_FL_ROBUST);
+
+  return 0;
+}
diff -Naur -x '*CVS*' nptl-0.36/pthread_mutexattr_setrobust_np.c rt___0_5/pthread_mutexattr_setrobust_np.c
--- nptl-0.36/pthread_mutexattr_setrobust_np.c	1970-01-01 08:00:00.000000000 +0800
+++ rt___0_5/pthread_mutexattr_setrobust_np.c	2003-06-19 13:36:35.000000000 +0800
@@ -0,0 +1,36 @@
+/*
+ *  (C) 2002-2003 Intel Corporation
+ *  Bing Wei Liu <[email protected]>.
+ *
+ *  Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <errno.h>
+#include <pthreadP.h>
+
+
+int
+pthread_mutexattr_setrobust_np (attr, robustness)
+     pthread_mutexattr_t *attr;
+     int robustness;
+{
+  struct pthread_mutexattr *iattr;
+
+  if (robustness < PTHREAD_MUTEX_STALL_NP || robustness > PTHREAD_MUTEX_ROBUST_SUN_NP)
+    return EINVAL;
+
+  iattr = (struct pthread_mutexattr *) attr;
+
+  /* Use Bit 2, 3 to indicate the robustness type of mutex :
+     -- PTHREAD_MUTEX_STALL_NP      (00xx)
+     -- PTHREAD_MUTEX_ROBUST_NP     (01xx)
+     -- PTHREAD_MUTEX_ROBUST_SUN_NP (11xx)  */
+  iattr->rtflags &= ~RTFUTEX_FL_ROBUST_MASK;  	/* Reset Bit 2, 3 */
+  
+  if (robustness == PTHREAD_MUTEX_ROBUST_NP)
+      iattr->rtflags |= RTFUTEX_FL_ROBUST;
+  else if (robustness == PTHREAD_MUTEX_ROBUST_SUN_NP)
+      iattr->rtflags |= RTFUTEX_FL_ROBUST_SUN;
+
+  return 0;
+}
diff -Naur -x '*CVS*' nptl-0.36/pthread_mutex_consistent_np.c rt___0_5/pthread_mutex_consistent_np.c
--- nptl-0.36/pthread_mutex_consistent_np.c	1970-01-01 08:00:00.000000000 +0800
+++ rt___0_5/pthread_mutex_consistent_np.c	2003-06-19 13:36:35.000000000 +0800
@@ -0,0 +1,16 @@
+/*
+ *  (C) 2002-2003 Intel Corporation
+ *  Bing Wei Liu <[email protected]>.
+ *
+ *  Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <errno.h>
+#include "pthreadP.h"
+
+int 
+pthread_mutex_consistent_np(mutex)
+    pthread_mutex_t *mutex;
+{
+    return lll_rtmutex_set_consistency(mutex->__data.__lock, MUTEX_STATE_HEALTH_NP);
+}
diff -Naur -x '*CVS*' nptl-0.36/pthread_mutex_init.c rt___0_5/pthread_mutex_init.c
--- nptl-0.36/pthread_mutex_init.c	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/pthread_mutex_init.c	2003-06-19 13:36:35.000000000 +0800
@@ -2,6 +2,9 @@
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <[email protected]>, 2002.
 
+   Initialize the '__rtflags' attribute of the mutex.
+   Bing Wei Liu <[email protected]>, 2003
+
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -25,7 +28,8 @@
 static const struct pthread_mutexattr default_attr =
   {
     /* Default is a normal mutex, not shared between processes.  */
-    .mutexkind = PTHREAD_MUTEX_NORMAL
+    .mutexkind = PTHREAD_MUTEX_NORMAL,
+    .rtflags = 0
   };
 
 
@@ -46,6 +50,8 @@
   /* Copy the values from the attribute.  */
   mutex->__data.__kind = imutexattr->mutexkind & ~0x80000000;
 
+  mutex->__data.__rtflags = imutexattr->rtflags;
+
   /* Default values: mutex not used yet.  */
   // mutex->__count = 0;	already done by memset
   // mutex->__owner = NULL;	already done by memset
diff -Naur -x '*CVS*' nptl-0.36/pthread_mutex_lock.c rt___0_5/pthread_mutex_lock.c
--- nptl-0.36/pthread_mutex_lock.c	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/pthread_mutex_lock.c	2003-06-19 13:36:35.000000000 +0800
@@ -2,6 +2,9 @@
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <[email protected]>, 2002.
 
+   Redirect lowlevellock to use real-time futexes.
+   Bing Wei Liu <[email protected]>, 2003
+
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -27,6 +30,7 @@
      pthread_mutex_t *mutex;
 {
   struct pthread *pd = THREAD_SELF;
+  int ret = 0;
 
   switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
     {
@@ -45,7 +49,9 @@
       else
 	{
 	  /* We have to get the mutex.  */
-	  lll_mutex_lock (mutex->__data.__lock);
+          ret = lll_rtmutex_lock (mutex->__data.__lock, pd->tid);
+          if (__builtin_expect(ret != 0, 0))
+            goto out_err;
 
 	  /* Record the ownership.  */
 	  mutex->__data.__owner = pd;
@@ -66,13 +72,25 @@
     case PTHREAD_MUTEX_TIMED_NP:
     case PTHREAD_MUTEX_ADAPTIVE_NP:
       /* Normal mutex.  */
-      lll_mutex_lock (mutex->__data.__lock);
-      /* Record the ownership.  */
+      ret = lll_rtmutex_lock (mutex->__data.__lock, pd->tid);
+      if (__builtin_expect(ret != 0, 0))
+        goto out_err;
+      /* Record the ownership. */
       mutex->__data.__owner = pd;
       break;
     }
-
+    
   return 0;
+
+ out_err:
+  if(__builtin_expect(ret == ESRCH, 0)) /* EDEADOWNER */ 
+    if((mutex->__data.__rtflags & RTFUTEX_FL_ROBUST_MASK) == 0) /* non-robust mutex */
+      {
+	/* FIXME: nchts, nchts, this is not the right way to print an error message from inside glibc ... */
+        printf("error: mutex %p previous owner died: deadlock\n", mutex);
+        abort();
+      }
+  return ret;
 }
 strong_alias (__pthread_mutex_lock, pthread_mutex_lock)
 strong_alias (__pthread_mutex_lock, __pthread_mutex_lock_internal)
diff -Naur -x '*CVS*' nptl-0.36/pthread_mutex_setconsistency_np.c rt___0_5/pthread_mutex_setconsistency_np.c
--- nptl-0.36/pthread_mutex_setconsistency_np.c	1970-01-01 08:00:00.000000000 +0800
+++ rt___0_5/pthread_mutex_setconsistency_np.c	2003-06-19 13:36:35.000000000 +0800
@@ -0,0 +1,22 @@
+/*
+ *  (C) 2002-2003 Intel Corporation
+ *  Bing Wei Liu <[email protected]>.
+ *
+ *  Distributed under the FSF's LGPL license, v2 or later. */
+
+#include <errno.h>
+#include "pthreadP.h"
+
+int 
+pthread_mutex_setconsistency_np(mutex, state)
+    pthread_mutex_t *mutex;
+    int state;
+{
+    int result = 0;
+    
+    if(state != MUTEX_STATE_HEALTH_NP && state != MUTEX_STATE_NOT_RECOVERABLE_NP)
+      return EINVAL;
+    
+    result = lll_rtmutex_set_consistency(mutex->__data.__lock, state);
+    return result;
+}
diff -Naur -x '*CVS*' nptl-0.36/pthread_mutex_timedlock.c rt___0_5/pthread_mutex_timedlock.c
--- nptl-0.36/pthread_mutex_timedlock.c	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/pthread_mutex_timedlock.c	2003-06-19 13:36:35.000000000 +0800
@@ -2,6 +2,9 @@
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <[email protected]>, 2002.
 
+   Redirect lowlevellock to use real-time futexes.
+   Bing Wei Liu <[email protected]>, 2003
+
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -46,18 +49,17 @@
 	    return EAGAIN;
 
 	  ++mutex->__data.__count;
-
-	  goto out;
 	}
       else
 	{
 	  /* We have to get the mutex.  */
-	  result = lll_mutex_timedlock (mutex->__data.__lock, abstime);
+	  result = lll_rtmutex_timedlock (mutex->__data.__lock, pd->tid, abstime);
 
-	  if (result != 0)
-	    goto out;
+	  if (__builtin_expect(result != 0, 0))
+	    goto out_err;
 
-	  /* Only locked once so far.  */
+	  /* Record the ownership.  */
+	  mutex->__data.__owner = pd;
 	  mutex->__data.__count = 1;
 	}
       break;
@@ -75,14 +77,23 @@
     case PTHREAD_MUTEX_TIMED_NP:
     case PTHREAD_MUTEX_ADAPTIVE_NP:
       /* Normal mutex.  */
-      result = lll_mutex_timedlock (mutex->__data.__lock, abstime);
+      result = lll_rtmutex_timedlock (mutex->__data.__lock, pd->tid, abstime);
+      if (__builtin_expect(result != 0, 0))
+        goto out_err;
+
+      mutex->__data.__owner = pd;
       break;
     }
 
-  if (result == 0)
-    /* Record the ownership.  */
-    mutex->__data.__owner = pd;
+  return 0;
 
- out:
+ out_err:
+  if(__builtin_expect(result == ESRCH, 0)) /* EDEADOWNER */ 
+    if((mutex->__data.__rtflags & RTFUTEX_FL_ROBUST_MASK) == 0) /* non-robust mutex */
+      {
+	/* FIXME: nchts, nchts, this is not the right way to print an error message from inside glibc ... */
+        printf("error: mutex %p previous owner died: deadlock\n", mutex);
+        abort();
+      }
   return result;
 }
diff -Naur -x '*CVS*' nptl-0.36/pthread_mutex_trylock.c rt___0_5/pthread_mutex_trylock.c
--- nptl-0.36/pthread_mutex_trylock.c	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/pthread_mutex_trylock.c	2003-06-19 13:36:35.000000000 +0800
@@ -2,6 +2,9 @@
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <[email protected]>, 2002.
 
+   Redirect lowlevellock to use real-time futexes.
+   Bing Wei Liu <[email protected]>, 2003
+
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -27,6 +30,7 @@
      pthread_mutex_t *mutex;
 {
   struct pthread *pd = THREAD_SELF;
+  int ret = 0;
 
   switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
     {
@@ -41,15 +45,18 @@
 	    return EAGAIN;
 
 	  ++mutex->__data.__count;
-	  return 0;
 	}
 
-      if (lll_mutex_trylock (mutex->__data.__lock) == 0)
+      else
 	{
+	  /* We have to get the mutex.  */
+          ret = lll_rtmutex_trylock (mutex->__data.__lock, pd->tid);
+          if (__builtin_expect(ret != 0, 0))
+            goto out_err;
+
 	  /* Record the ownership.  */
 	  mutex->__data.__owner = pd;
 	  mutex->__data.__count = 1;
-	  return 0;
 	}
       break;
 
@@ -60,15 +67,23 @@
     case PTHREAD_MUTEX_TIMED_NP:
     case PTHREAD_MUTEX_ADAPTIVE_NP:
       /* Normal mutex.  */
-      if (lll_mutex_trylock (mutex->__data.__lock) == 0)
-	{
-	  /* Record the ownership.  */
-	  mutex->__data.__owner = pd;
-
-	  return 0;
-	}
+      ret = lll_rtmutex_trylock (mutex->__data.__lock, pd->tid);
+      if (__builtin_expect(ret != 0, 0))
+        goto out_err;
+      /* Record the ownership. */
+      mutex->__data.__owner = pd;
+      break;
     }
+  return 0;
 
-  return EBUSY;
+ out_err:
+  if(__builtin_expect(ret == ESRCH, 0)) /* EDEADOWNER */ 
+    if((mutex->__data.__rtflags & RTFUTEX_FL_ROBUST_MASK) == 0) /* non-robust mutex */
+      {
+	/* FIXME: nchts, nchts, this is not the right way to print an error message from inside glibc ... */
+        printf("error: mutex %p previous owner died: deadlock\n", mutex);
+        abort();
+      }
+  return ret;
 }
 strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock)
diff -Naur -x '*CVS*' nptl-0.36/pthread_mutex_unlock.c rt___0_5/pthread_mutex_unlock.c
--- nptl-0.36/pthread_mutex_unlock.c	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/pthread_mutex_unlock.c	2003-06-19 13:36:35.000000000 +0800
@@ -2,6 +2,9 @@
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <[email protected]>, 2002.
 
+   Redirect lowlevellock to use real-time futexes.
+   Bing Wei Liu <[email protected]>, 2003
+
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -26,6 +29,8 @@
 __pthread_mutex_unlock (mutex)
      pthread_mutex_t *mutex;
 {
+  int ret = 0;
+  
   switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
     {
     case PTHREAD_MUTEX_RECURSIVE_NP:
@@ -57,10 +62,27 @@
       break;
     }
 
-  /* Unlock.  */
-  lll_mutex_unlock (mutex->__data.__lock);
-
-  return 0;
+  if (__builtin_expect ((mutex->__data.__rtflags & RTFUTEX_FL_ROBUST_MASK) == RTFUTEX_FL_ROBUST_SUN, 0))
+    goto solaris_compat_mode;
+  
+  ret = lll_rtmutex_unlock (mutex->__data.__lock, THREAD_SELF->tid);
+  return ret;
+
+ solaris_compat_mode:
+  {
+    int owner_tid = mutex->__data.__lock & (~RTFUTEX_WAITERS_PRESENT);
+    if (__builtin_expect (owner_tid == RTFUTEX_DEAD_OWNER, 0))
+      {
+        if ((ret = lll_rtmutex_set_consistency (mutex->__data.__lock, 1)) != 0)
+          return ret;
+        ret = lll_rtmutex_unlock_nocheck (mutex->__data.__lock);
+      }
+    else
+      {
+        ret = lll_rtmutex_unlock (mutex->__data.__lock, THREAD_SELF->tid);
+      }
+  }
+  return ret;
 }
 strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock)
 strong_alias (__pthread_mutex_unlock, __pthread_mutex_unlock_internal)
diff -Naur -x '*CVS*' nptl-0.36/sysdeps/pthread/createthread.c rt___0_5/sysdeps/pthread/createthread.c
--- nptl-0.36/sysdeps/pthread/createthread.c	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/sysdeps/pthread/createthread.c	2003-06-19 13:36:35.000000000 +0800
@@ -2,6 +2,10 @@
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <[email protected]>, 2002.
 
+   Set 'CLONE_SIGNATURE' flag to create threads' signature, which 
+   can be used for mutexes' ownership checking.
+   Bing Wei Liu <[email protected]>, 2003
+
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -27,6 +31,8 @@
 
 
 #define CLONE_SIGNAL    	(CLONE_SIGHAND | CLONE_THREAD)
+#define CLONE_SIGNATURE 0x02000000      /* Assign a signature to the process */
+volatile int do_signature = 1;
 
 /* Unless otherwise specified, the thread "register" is going to be
    initialized with a pointer to the TCB.  */
@@ -50,6 +56,8 @@
 static int
 create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
 {
+  int more_flags = do_signature ? CLONE_SIGNATURE : 0;
+
 #ifdef PREPARE_CREATE
   PREPARE_CREATE;
 #endif
@@ -78,7 +86,7 @@
 	  if (ARCH_CLONE (start_thread_debug, STACK_VARIABLES_ARGS,
 			  CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL |
 			  CLONE_SETTLS | CLONE_PARENT_SETTID |
-			  CLONE_CHILD_CLEARTID | CLONE_DETACHED | 0,
+	  	          CLONE_CHILD_CLEARTID | CLONE_DETACHED | more_flags,
 			  pd, &pd->tid, TLS_VALUE, &pd->tid) == -1)
 	    /* Failed.  */
 	    return errno;
@@ -151,7 +159,7 @@
   if (ARCH_CLONE (start_thread, STACK_VARIABLES_ARGS,
 		  CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL |
 		  CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
-		  CLONE_DETACHED | 0, pd, &pd->tid, TLS_VALUE, &pd->tid) == -1)
+	          CLONE_DETACHED | more_flags, pd, &pd->tid, TLS_VALUE, &pd->tid) == -1)
     /* Failed.  */
     return errno;
 
diff -Naur -x '*CVS*' nptl-0.36/sysdeps/pthread/pthread.h rt___0_5/sysdeps/pthread/pthread.h
--- nptl-0.36/sysdeps/pthread/pthread.h	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/sysdeps/pthread/pthread.h	2003-06-19 13:36:35.000000000 +0800
@@ -1,6 +1,10 @@
 /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
+   Add a few structure definitions and extern functions 
+   about robust and real-time mutexes.
+   Bing Wei Liu <[email protected]>, 2003
+
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -59,6 +63,33 @@
 #endif
 };
 
+/* 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
+};
+
+/* Robust Mutex types. */
+enum
+{
+  PTHREAD_MUTEX_STALL_NP=1,
+  PTHREAD_MUTEX_ROBUST_NP,
+#define PTHREAD_MUTEX_ROBUST_NP	 PTHREAD_MUTEX_ROBUST_NP
+  PTHREAD_MUTEX_ROBUST_SUN_NP
+#define PTHREAD_MUTEX_ROBUST_SUN_NP  PTHREAD_MUTEX_ROBUST_SUN_NP
+};
+
+/* Robust Mutex states. */
+enum
+{
+  MUTEX_STATE_HEALTH_NP,
+  MUTEX_STATE_NOT_RECOVERABLE_NP
+};
+
 /* Mutex initializers.  */
 #define PTHREAD_MUTEX_INITIALIZER \
   { }
@@ -542,6 +573,31 @@
      __THROW;
 #endif
 
+/* 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 mutex-robust flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_getrobust_np (__const pthread_mutexattr_t *
+					   __restrict __attr,
+					   int *__restrict __robustness) __THROW;
+
+/* Set the mutex-robust flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr,
+					   int __robustness) __THROW;
+
+/* Set the mutex to given state  */
+extern int pthread_mutex_setconsistency_np (pthread_mutex_t *__mutex,
+					    int __state) __THROW;
+
+/* Set the mutex to 'health' state  */
+extern int pthread_mutex_consistent_np (pthread_mutex_t *__mutex) __THROW;
+
 
 #ifdef __USE_UNIX98
 /* Functions for handling read-write locks.  */
diff -Naur -x '*CVS*' nptl-0.36/sysdeps/unix/sysv/linux/fork.c rt___0_5/sysdeps/unix/sysv/linux/fork.c
--- nptl-0.36/sysdeps/unix/sysv/linux/fork.c	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/sysdeps/unix/sysv/linux/fork.c	2003-06-19 13:36:35.000000000 +0800
@@ -2,6 +2,10 @@
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <[email protected]>, 2002.
 
+   Generate a signature for the forked thread, which can be used 
+   for mutexes' ownership checking.
+   Bing Wei Liu <[email protected]>, 2003
+
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -118,6 +122,9 @@
 
       /* Initialize the fork lock.  */
       __fork_lock = (lll_lock_t) LLL_LOCK_INITIALIZER;
+
+     /* Create signature for the newly forked proc/thread */
+      lll_rtmutex_make_signature(0);
     }
   else
     {
diff -Naur -x '*CVS*' nptl-0.36/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h rt___0_5/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h
--- nptl-0.36/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h	2003-06-19 13:36:35.000000000 +0800
@@ -1,6 +1,9 @@
 /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
+   Add a '__rtflags' attribute to pthread_mutex_t.
+   Bing Wei Liu <[email protected]>, 2003
+
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -21,7 +24,7 @@
 
 #define __SIZEOF_PTHREAD_ATTR_T 36
 #define __SIZEOF_PTHREAD_MUTEX_T 24
-#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+#define __SIZEOF_PTHREAD_MUTEXATTR_T 8
 #define __SIZEOF_PTHREAD_COND_T 48
 #define __SIZEOF_PTHREAD_COND_COMPAT_T 12
 #define __SIZEOF_PTHREAD_CONDATTR_T 4
@@ -55,6 +58,9 @@
     /* KIND must stay at this position in the structure to maintain
        binary compatibility.  */
     int __kind;
+    
+    /* Flags for realtime mutex extension. */
+    int __rtflags;
   } __data;
   char __size[__SIZEOF_PTHREAD_MUTEX_T];
   long int __align;
diff -Naur -x '*CVS*' nptl-0.36/sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S rt___0_5/sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S
--- nptl-0.36/sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/sysdeps/unix/sysv/linux/i386/i486/lowlevelmutex.S	2003-06-19 13:36:36.000000000 +0800
@@ -2,6 +2,10 @@
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <[email protected]>, 2002.
 
+   Add a set of __lll_rtmutex_* functions to utilize real-time 
+   futexes (rtfutex).
+   Bing Wei Liu <[email protected]>, 2003
+
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -173,3 +177,209 @@
 	popl	%ebx
 	ret
 	.size	__lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
+
+
+
+/* Add __lll_rtmutex_* to support rtfutex */
+
+#define FUTEX_RT_WAIT		3
+#define FUTEX_RT_WAKE		4
+#define FUTEX_RT_CONSISTENCY	5
+#define FUTEX_RT_MKSIG		6
+#define FUTEX_RT_TRYLOCK	7
+
+#define MUTEX_OFF_FLAGS 	16
+
+
+	.globl	__lll_rtmutex_lock_wait
+	.type	__lll_rtmutex_lock_wait,@function
+	.hidden	__lll_rtmutex_lock_wait
+	.align	16
+__lll_rtmutex_lock_wait:
+	pushl	%esi
+	pushl	%ebx
+	pushl	%ecx
+	pushl	%edx
+
+	movl	%eax, %ebx
+	movl 	$FUTEX_RT_WAIT, %ecx
+	movl	MUTEX_OFF_FLAGS(%ebx), %edx	/* %edx: __protocol (flags)  */
+	xorl	%esi, %esi			/* No timeout.  */
+1:
+	movl	$SYS_futex, %eax
+	ENTER_KERNEL
+	
+	cmpl	$-EINTR, %eax
+	je	1b
+	neg	%eax
+	
+	popl	%edx
+	popl	%ecx
+	popl	%ebx
+	popl	%esi
+	ret
+	.size	__lll_rtmutex_lock_wait,.-__lll_rtmutex_lock_wait
+
+
+	.globl	__lll_rtmutex_trylock
+	.type	__lll_rtmutex_trylock,@function
+	.hidden	__lll_rtmutex_trylock
+	.align	16
+__lll_rtmutex_trylock:
+	pushl	%esi
+	pushl	%ebx
+	pushl	%ecx
+	pushl	%edx
+
+	movl	%eax, %ebx
+	movl 	$FUTEX_RT_TRYLOCK, %ecx
+	movl	MUTEX_OFF_FLAGS(%ebx), %edx	/* %edx: __protocol (flags)  */
+	xorl	%esi, %esi			/* No timeout.  */
+	movl	$SYS_futex, %eax
+	ENTER_KERNEL
+	
+	neg	%eax
+	
+	popl	%edx
+	popl	%ecx
+	popl	%ebx
+	popl	%esi
+	ret
+	.size	__lll_rtmutex_trylock,.-__lll_rtmutex_trylock
+
+
+	.globl	__lll_rtmutex_timedlock_wait
+	.type	__lll_rtmutex_timedlock_wait,@function
+	.hidden	__lll_rtmutex_timedlock_wait
+	.align	16
+__lll_rtmutex_timedlock_wait:
+	/* Check for a valid timeout value.  */
+	cmpl	$1000000000, 4(%edx)
+	jae	3f
+
+	pushl	%edi
+	pushl	%esi
+	pushl	%ecx
+	pushl	%ebx
+	pushl	%ebp
+
+	/* Stack frame for the timespec and timeval structs.  */
+	subl	$8, %esp
+
+	movl	%eax, %ebp
+	movl	%edx, %edi
+
+	/* Get current time.  */
+1:
+	movl	%esp, %ebx
+	xorl	%ecx, %ecx
+	movl	$SYS_gettimeofday, %eax
+	ENTER_KERNEL
+
+	/* Compute relative timeout.  */
+	movl	4(%esp), %eax
+	movl	$1000, %edx
+	mul	%edx		/* Milli seconds to nano seconds.  */
+	movl	(%edi), %ecx
+	movl	4(%edi), %edx
+	subl	(%esp), %ecx
+	subl	%eax, %edx
+	jns	4f
+	addl	$1000000000, %edx
+	decl	%ecx
+4:	testl	%ecx, %ecx
+	js	5f		/* Time is already up.  */
+
+	/* Futex call.  */
+	movl	%ecx, (%esp)	/* Store relative timeout.  */
+	movl	%edx, 4(%esp)
+	movl	%esp, %esi
+	movl	%ebp, %ebx
+	movl	MUTEX_OFF_FLAGS(%ebx), %edx
+	movl 	$FUTEX_RT_WAIT, %ecx
+	movl	$SYS_futex, %eax
+	ENTER_KERNEL
+
+	cmpl	$-EINTR, %eax
+	je	1b
+	neg	%eax
+
+6:	addl	$8, %esp
+	popl	%ebp
+	popl	%ebx
+	popl	%ecx
+	popl	%esi
+	popl	%edi
+	ret
+
+3:	movl	$EINVAL, %eax
+	ret
+
+5:	movl	$ETIMEDOUT, %eax
+	jmp	6b
+	.size	__lll_rtmutex_timedlock_wait,.-__lll_rtmutex_timedlock_wait
+	
+
+	.globl	__lll_rtmutex_unlock_wake
+	.type	__lll_rtmutex_unlock_wake,@function
+	.hidden	__lll_rtmutex_unlock_wake
+	.align	16
+__lll_rtmutex_unlock_wake:
+	pushl	%ebx
+	pushl	%ecx
+
+	movl	%eax, %ebx
+	movl	$FUTEX_RT_WAKE, %ecx
+	movl	$SYS_futex, %eax
+	ENTER_KERNEL
+
+	cmpl	$0, %eax
+	jl	2f
+	xorl	%eax, %eax
+	
+1:	popl	%ecx
+	popl	%ebx
+	ret
+	
+2:	neg	%eax
+	jmp	1b
+	.size	__lll_rtmutex_unlock_wake,.-__lll_rtmutex_unlock_wake
+
+
+	.globl	__lll_rtmutex_set_consistency
+	.type	__lll_rtmutex_set_consistency,@function
+	.hidden	__lll_rtmutex_set_consistency
+	.align	16
+__lll_rtmutex_set_consistency:
+	pushl	%ebx
+	pushl	%ecx
+
+	movl	%eax, %ebx
+	movl	$FUTEX_RT_CONSISTENCY, %ecx
+	movl	$SYS_futex, %eax
+	ENTER_KERNEL
+
+	neg	%eax
+
+	popl	%ecx
+	popl	%ebx
+	ret
+	.size	__lll_rtmutex_set_consistency,.-__lll_rtmutex_set_consistency
+
+
+	.globl	__lll_rtmutex_make_signature
+	.type	__lll_rtmutex_make_signature,@function
+	.hidden	__lll_rtmutex_make_signature
+	.align	16
+__lll_rtmutex_make_signature:
+	pushl	%ecx
+
+	movl	$FUTEX_RT_MKSIG, %ecx
+	movl	$SYS_futex, %eax
+	ENTER_KERNEL
+
+	neg	%eax
+
+	popl	%ecx
+	ret
+	.size	__lll_rtmutex_make_signature,.-__lll_rtmutex_make_signature
diff -Naur -x '*CVS*' nptl-0.36/sysdeps/unix/sysv/linux/i386/lowlevellock.h rt___0_5/sysdeps/unix/sysv/linux/i386/lowlevellock.h
--- nptl-0.36/sysdeps/unix/sysv/linux/i386/lowlevellock.h	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/sysdeps/unix/sysv/linux/i386/lowlevellock.h	2003-06-19 13:36:35.000000000 +0800
@@ -2,6 +2,10 @@
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <[email protected]>, 2002.
 
+   Add a set of lll_rtmutex_* definitions to utilize real-time 
+   futexes (rtfutex).
+   Bing Wei Liu <[email protected]>, 2003
+
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -241,6 +245,162 @@
   (futex != 0)
 
 
+/* Add lll_rtmutex_* to support rtfutex */
+
+#define RTFUTEX_WAITERS_PRESENT 0x80000000
+#define RTFUTEX_DEAD_OWNER      (~RTFUTEX_WAITERS_PRESENT)
+#define RTFUTEX_NOT_RECOVERABLE (RTFUTEX_DEAD_OWNER & ~0X1)
+#define RTFUTEX_DEAD_MASK       (RTFUTEX_NOT_RECOVERABLE)
+
+#define RTFUTEX_FL_PRIO_INHERIT  0x02
+#define RTFUTEX_FL_PRIO_PROTECT  0x03
+#define RTFUTEX_FL_PRIO_MASK     0x03
+#define RTFUTEX_FL_ROBUST        0x04
+#define RTFUTEX_FL_ROBUST_SUN    0x0c
+#define RTFUTEX_FL_ROBUST_MASK   0x0c
+
+
+/* Preserves all registers but %eax.  */
+extern int __lll_rtmutex_lock_wait (int *__futex)
+     __attribute ((regparm (1))) attribute_hidden;
+/* Preserves all registers but %eax.  */
+extern int __lll_rtmutex_trylock (int *__futex)
+     __attribute ((regparm (1))) attribute_hidden;
+/* Does not preserve %eax and %edx.  */
+extern int __lll_rtmutex_timedlock_wait (int *__futex,
+			 	         const struct timespec *abstime)
+     __attribute ((regparm (2))) attribute_hidden;
+/* Preserves all registers but %eax.  */
+extern int __lll_rtmutex_unlock_wake (int *__futex)
+     __attribute ((regparm (1))) attribute_hidden;
+/* Does not preserve %eax and %edx.  */
+extern int __lll_rtmutex_set_consistency (int *__futex, int state)
+     __attribute ((regparm (2))) attribute_hidden;
+/* Preserves all registers but %edx.  */
+extern int __lll_rtmutex_make_signature (int tid)
+     __attribute ((regparm (1))) attribute_hidden;
+
+
+#define lll_rtmutex_trylock(futex, tid)                                 \
+  ({ int result;                                                        \
+     __asm __volatile ("1:                                   \n\t"      \
+                           "xorl     %%eax, %%eax            \n\t"      \
+                            LOCK_INSTR "                     \n\t"      \
+                           "cmpxchgl %2, %1                  \n\t"      \
+                           "jne      2f                      \n"        \
+                       ".subsection 1                        \n"        \
+                       "2:                                   \n\t"      \
+                           "andl     %3, %%eax	             \n\t"      \
+                           "cmpl     %3, %%eax               \n\t"      \
+                           "je       3f                      \n"        \
+                           "movl     %4, %%eax               \n\t"      \
+                           "jmp      4f                      \n"        \
+                       "3:                                   \n\t"      \
+                           "leal     %1, %%eax               \n\t"      \
+                           "call     __lll_rtmutex_trylock   \n\t"      \
+                           "jmp      4f                      \n"        \
+                       ".previous                            \n"        \
+                       "4:"                                             \
+                       : "=&a" (result), "+m" (futex)                   \
+                       : "r" (tid), "i" (RTFUTEX_DEAD_MASK),            \
+                         "i" (EBUSY)                                    \
+                       : "memory");                                     \
+    result; })
+
+
+#define lll_rtmutex_lock(futex, tid)                                    \
+  ({ int result;                                                        \
+     __asm __volatile ("1:                                   \n\t"      \
+                           "xorl     %%eax, %%eax            \n\t"      \
+                            LOCK_INSTR "                     \n\t"      \
+                           "cmpxchgl %2, %1                  \n\t"      \
+                           "jne      2f                      \n"        \
+                       ".subsection 1                        \n"        \
+                       "2:                                   \n\t"      \
+                           "leal     %1, %%eax               \n\t"      \
+                           "call     __lll_rtmutex_lock_wait \n\t"      \
+                           "jmp      3f                      \n"        \
+                       ".previous                            \n"        \
+                       "3:"                                             \
+                       : "=&a" (result), "+m" (futex)                   \
+                       : "r" (tid)                                      \
+                       : "memory");                                     \
+    result; })
+
+
+#define lll_rtmutex_timedlock(futex, tid, timeout)                                    \
+  ({ int result, ignore1;                                               \
+     __asm __volatile ("1:                                   \n\t"      \
+                           "xorl     %%eax, %%eax            \n\t"      \
+                            LOCK_INSTR "                     \n\t"      \
+                           "cmpxchgl %3, %1                  \n\t"      \
+                           "jne      2f                      \n"        \
+                       ".subsection 1                        \n"        \
+                       "2:                                   \n\t"      \
+                           "leal     %1, %%eax               \n\t"      \
+                           "movl     %4, %%edx               \n\t"      \
+                           "call     __lll_rtmutex_timedlock_wait \n\t" \
+                           "jmp      3f                      \n"        \
+                       ".previous                            \n"        \
+                       "3:"                                             \
+                       : "=&a" (result), "+m" (futex), "=&d" (ignore1)  \
+                       : "r" (tid), "m" (timeout)                       \
+                       : "memory");                                     \
+    result; })
+
+
+#define lll_rtmutex_unlock(futex, tid) \
+  ({ int result;                                                        \
+     __asm __volatile ("    xorl     %%ecx, %%ecx              \n\t"    \
+                            LOCK_INSTR "                       \n\t"    \
+                           "cmpxchgl %%ecx, %1                 \n\t"    \
+                           "jne      1f                        \n\t"    \
+                           "xorl     %0, %0                    \n"      \
+                       ".subsection 1                          \n"      \
+                       "1:                                     \n\t"    \
+                           "andl     %3, %%eax                 \n\t"    \
+                           "jz       2f                        \n\t"    \
+                           "leal     %1, %%eax                 \n\t"    \
+                           "call     __lll_rtmutex_unlock_wake \n\t"    \
+                           "jmp      3f                        \n"      \
+                       "2:                                     \n\t"    \
+                           "movl     $0, %1                    \n\t"    \
+                           "jmp      3f                        \n"      \
+                       ".previous                              \n"      \
+                       "3:"                                             \
+                       : "=a" (result), "+m" (futex)                    \
+                       : "a" (tid),                                     \
+                         "i" (RTFUTEX_WAITERS_PRESENT)                  \
+                       : "%ecx", "memory");                             \
+     result; })
+
+
+#define lll_rtmutex_unlock_nocheck(futex) \
+  ({ int result;						      \
+    __asm __volatile ("leal %1, %%eax\n\t"			      \
+		      "call __lll_rtmutex_unlock_wake\n\t"	      \
+                      : "=a" (result)                                 \
+                      : "m" (futex));                                 \
+     result; })
+
+
+#define lll_rtmutex_set_consistency(futex, state) \
+  ({ int result, ignore1;                                             \
+     __asm __volatile ("leal %2, %%eax\n\t"                           \
+                       "call __lll_rtmutex_set_consistency\n\t"       \
+                       : "=a" (result), "=&d" (ignore1)               \
+                       : "m" (futex), "1" (state));                   \
+     result; })
+
+#define lll_rtmutex_make_signature(tid) \
+  ({ int result, ignore1;                                             \
+     __asm __volatile ("call __lll_rtmutex_make_signature\n\t"        \
+                       : "=a" (result), "=&d" (ignore1)               \
+                       : "1" (tid));                                  \
+     result; })
+
+
+
 /* The kernel notifies a process with uses CLONE_CLEARTID via futex
    wakeup when the clone terminates.  The memory location contains the
    thread ID while the clone is running and is reset to zero
diff -Naur -x '*CVS*' nptl-0.36/sysdeps/unix/sysv/linux/internaltypes.h rt___0_5/sysdeps/unix/sysv/linux/internaltypes.h
--- nptl-0.36/sysdeps/unix/sysv/linux/internaltypes.h	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/sysdeps/unix/sysv/linux/internaltypes.h	2003-06-19 13:36:35.000000000 +0800
@@ -2,6 +2,9 @@
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <[email protected]>, 2002.
 
+   Add a 'rtflags' attribute to struct 'pthread_mutexattr'.
+   Bing Wei Liu <[email protected]>, 2003
+
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -57,6 +60,15 @@
      Bit 0 to 30 contain one of the PTHREAD_MUTEX_ values to identify
      the type of the mutex.  */
   int mutexkind;
+
+  /* Flags for realtime mutex extension.
+  
+     Bit 0 and 1 for mutex protocol attributes.
+     
+     Bit 2 and 3 for mutex robustness attributes.
+     
+     The rest reserved for future use. */
+  int rtflags;
 };
 
 
diff -Naur -x '*CVS*' nptl-0.36/Versions rt___0_5/Versions
--- nptl-0.36/Versions	2003-04-28 14:22:23.000000000 +0800
+++ rt___0_5/Versions	2003-05-30 17:11:36.000000000 +0800
@@ -206,11 +206,16 @@
     # 1003.1-2001 function accidentally left out in 2.2.
     pthread_barrierattr_getpshared;
 
+    # 1003.1-2001 function (realtime)
+    pthread_mutexattr_getprotocol; pthread_mutexattr_setprotocol;
+
     # Unix CS option.
     pthread_condattr_getclock; pthread_condattr_setclock;
 
     # Proposed API extensions.
     pthread_tryjoin_np; pthread_timedjoin_np;
+    pthread_mutexattr_getrobust_np; pthread_mutexattr_setrobust_np;
+    pthread_mutex_consistent_np; pthread_mutex_setconsistency_np;
 
     # New cancellation cleanup handling.
     __pthread_register_cancel; __pthread_unregister_cancel;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.