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.1 5/5


bits/posix_opt.h         |    9 +
bits/pthreadtypes.h      |    3
lowlevellock.h           |  235
+++++++++++++++++++++++++++++++++++++++++++++++
lowlevelrtlock.c         |   79 +++++++++++++++
pthread_cond_broadcast.c |    2
pthread_cond_signal.c    |    2
pthread_cond_timedwait.c |    2
pthread_cond_wait.c      |    2
8 files changed, 333 insertions(+), 1 deletion(-)

diff -urN src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/bits/posix_opt.h
src/nptl/sysdeps/unix/sysv/linux/ia64/bits/posix_opt.h
--- src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/bits/posix_opt.h
2004-01-31 11:49:05.000000000 +0800
+++ src/nptl/sysdeps/unix/sysv/linux/ia64/bits/posix_opt.h
2004-01-31 11:51:20.000000000 +0800
@@ -144,4 +144,13 @@
 /* The clock selection interfaces are available.  */
 #define _POSIX_CLOCK_SELECTION	200112L
 
+/* The Priority Inheritence of thread is available. */
+#define _POSIX_THREAD_PRIO_INHERIT 1
+
+/* The Priority Protect of thread is available. */
+#define _POSIX_THREAD_PRIO_PROTECT 2
+
+/* The robust mutex is available. */
+#define _POSIX_THREAD_ROBUST_MUTEX_NP 1
+
 #endif /* posix_opt.h */
diff -urN src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
src/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
--- src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
2004-01-31 11:49:05.000000000 +0800
+++ src/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
2004-01-31 11:51:20.000000000 +0800
@@ -52,10 +52,11 @@
     int __lock;
     unsigned int __count;
     int __owner;
-    unsigned int __nusers;
     /* KIND must stay at this position in the structure to maintain
        binary compatibility.  */
     int __kind;
+    unsigned int __nusers;
+    unsigned int __prioceiling;
   } __data;
   char __size[__SIZEOF_PTHREAD_MUTEX_T];
   long int __align;
diff -urN src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
src/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
--- src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
2004-01-31 11:49:05.000000000 +0800
+++ src/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
2004-01-31 11:51:20.000000000 +0800
@@ -2,6 +2,10 @@
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
+   Redirect lowlevellock to use Fast User SYNchronization(fusyn). 
+   Based on implementation for i386 by Boris Hu (Intel).
+   Dave Howell <david.p.howell@intel.com>, 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
@@ -111,6 +115,7 @@
 #define lll_mutex_unlock(futex) \
   __lll_mutex_unlock(&(futex))
 
+//#warning FIXME: requeue feature will be added when the fusyn is
ready. 
 
 #define __lll_mutex_unlock_force(futex)		\
   ((void) ({					\
@@ -190,4 +195,234 @@
 #define lll_cond_broadcast(cond) \
   __lll_cond_broadcast (cond)
 
+// USE_FUSYN_ROBUST_MUTEX macro to enable/disable the RM features.
+#define USE_FUSYN_ROBUST_MUTEX  1
+
+#ifdef  USE_FUSYN_ROBUST_MUTEX
+
+#include <linux/fulock.h>
+#include <sysdep.h>
+#include <errno.h>
+#include <pthread.h>
+
+#ifndef __set_errno
+#define __set_errno(e) (errno = (e))
+#endif
+
+//#define SEA_DEBUG       1  // To Enable the debug info
+
+#ifdef SEA_DEBUG
+int printf(const char *format, ...); 	/* To make GCC happy */
+
+/* Indicate location */
+#  define SEA_L
\
+       do {
\
+                unsigned id = THREAD_GETMEM (THREAD_SELF, tid);
\
+                printf("[%d] %s:%s() %d line: \n", id, __FILE__,
\
+                       __FUNCTION__, __LINE__);
\
+        } while (0)
+
+/* Location-aware printf */
+#  define SEA_P(fmt, args...)
\
+        do {
\
+                unsigned id = THREAD_GETMEM (THREAD_SELF, tid);
\
+                printf("[%d] %s:%s() %d line: " fmt "\n",
\
+                        id, __FILE__,__FUNCTION__,__LINE__,args);
\
+        } while (0)
+                                
+#else
+#  define SEA_L
+#  define SEA_P(fmt, args...)
+#endif 
+
+/* Add lll_rtmutex_* to support fusyn */
+#define FUSYN_FL_RT_MASK	0x78000000
+#define MUTEX_OFF_KIND		3
+
+#define __LK_FL(mutex)
\
+        ({ unsigned k_flags;
\
+           unsigned flags =((pthread_mutex_t *)(mutex))->__data.__kind
\
+                                & FUSYN_FL_RT_MASK;
\
+           k_flags = ((flags << 1) & FULOCK_FL_USER_MK);
\
+           k_flags;})
+
+static inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_trylock (volatile unsigned *vfulock, unsigned flags,
unsigned tid)
+{
+  unsigned old_value;
+  
+ restart:
+  old_value = atomic_compare_and_exchange_val_acq (vfulock, tid,
VFULOCK_UNLOCKED);
+  if (old_value == VFULOCK_UNLOCKED) /* If it was unlocked, fulock
acquired */
+    return 0;
+  else if (__builtin_expect (old_value == VFULOCK_NR, 0))
+    return ENOTRECOVERABLE;
+  else
+  {
+    if ((old_value == VFULOCK_KCO) || (flags & FULOCK_FL_RM))
+    {
+      int result = INLINE_SYSCALL (ufulock_lock, 3, vfulock, flags, 0);
+      if (__builtin_expect (result < 0, 0))
+      {
+	if (result == -EAGAIN || result == -EINTR)
+	  goto restart;
+	result = -result;
+      }
+      return result;
+    }
+  }
+  return EBUSY;
+}
+#define lll_rtmutex_trylock(futex, tid) \
+	__lll_rtmutex_trylock(&(futex), __LK_FL(&(futex)), tid)
+
+
+extern int
+__lll_rtmutex_timedlock (volatile unsigned *vfulock, unsigned flags,
+			 unsigned tid, const struct timespec *rel);
+#define lll_rtmutex_timedlock(futex, tid, timeout) \
+        __lll_rtmutex_timedlock(&(futex), __LK_FL(&(futex)), tid,
timeout)
+
+
+static inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_lock (volatile unsigned *vfulock, unsigned flags,
unsigned tid)
+{
+  int result;
+ restart:
+  if (!atomic_compare_and_exchange_bool_acq (vfulock, tid,
VFULOCK_UNLOCKED))
+    return 0;
+  result = INLINE_SYSCALL (ufulock_lock, 3, vfulock, flags, (void
*)-1);
+  if (__builtin_expect (result < 0, 0))
+  {
+    if (result == -EAGAIN || result == -EINTR)
+      goto restart;
+    result = -result;
+  }
+  return result;  
+}
+#define lll_rtmutex_lock(futex, tid) \
+	__lll_rtmutex_lock(&(futex), __LK_FL(&(futex)), tid)
+
+
+static inline int
+__attribute__ ((always_inline)) 
+__lll_rtmutex_unlock (volatile unsigned *vfulock, unsigned flags,
unsigned tid)     
+{
+  unsigned old_value;
+  
+  while (1)
+  {
+    old_value = *vfulock;
+    if (__builtin_expect (old_value == VFULOCK_NR, 0))
+      return ENOTRECOVERABLE;
+    else if (old_value >= VFULOCK_KCO)
+    {
+      int result;
+      result = INLINE_SYSCALL(ufulock_unlock, 3, vfulock, flags, 0);
+      return (result < 0) ? -result : 0;
+    }
+    else if (! atomic_compare_and_exchange_bool_acq (vfulock,
VFULOCK_UNLOCKED,
+                                                   old_value))
+      return 0;
+  }
+}
+#define lll_rtmutex_unlock(futex, tid) \
+	__lll_rtmutex_unlock(&(futex), __LK_FL(&(futex)), tid)
+
+
+static inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_unlock_nocheck (volatile unsigned *vfulock)
+{
+  int result = INLINE_SYSCALL (ufulock_unlock, 3, vfulock,
__LK_FL(vfulock), 0);
+  return result ? -result : 0;
+}
+#define lll_rtmutex_unlock_nocheck(futex) \
+        __lll_rtmutex_unlock_nocheck(&(futex))
+
+
+static inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_set_consistency (volatile unsigned *vfulock,
+                               enum fulock_con consistency)
+{
+  int result = INLINE_SYSCALL (ufulock_consistency, 3, vfulock,
+				       __LK_FL(vfulock), consistency);
+  return result ? -result : 0;
+}
+#define lll_rtmutex_set_consistency(futex, state) \
+        __lll_rtmutex_set_consistency(&(futex), state)
+
+
+static inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_get_consistency (volatile unsigned *vfulock, int *state)
+{
+  *state = INLINE_SYSCALL (ufulock_consistency, 3, vfulock,
+					        __LK_FL(vfulock), 0);
+  return 0;
+}
+#define lll_rtmutex_get_consistency(futex, state) \
+        __lll_rtmutex_get_consistency(&(futex), state)
+
+
+static inline int
+__attribute__ ((always_inline))
+is_mutex_robust(pthread_mutex_t *mutex)
+{
+  return (mutex->__data.__kind & ((FULOCK_FL_RM | FULOCK_FL_RM_SUN) >>
1));
+}
+
+static inline int
+__attribute__ ((always_inline))
+is_mutex_healthy(pthread_mutex_t *mutex)
+{
+  int state;
+  pthread_mutex_getconsistency_np (mutex, &state);
+  return state == PTHREAD_MUTEX_ROBUST_CONSISTENT_NP;
+}
+
+#define CONDVAR_RM_FLAGS        FULOCK_FL_RM
+
+#define lll_cmutex_lock(fulock, id)   \
+  do {
\
+        while (__lll_rtmutex_lock(&(fulock), CONDVAR_RM_FLAGS, id))
\
+                lll_rtmutex_set_consistency(fulock,
\
+                       PTHREAD_MUTEX_ROBUST_CONSISTENT_NP);
\
+  } while (0)
+     
+#define lll_cmutex_unlock(fulock, id) \
+        __lll_rtmutex_unlock(&(fulock), CONDVAR_RM_FLAGS, id)
+
+#define LLL_CMUTEX_LOCK(mutex, tid)     \
+        lll_cmutex_lock (mutex, tid)
+
+#define LLL_CMUTEX_UNLOCK(mutex, tid)   \
+        lll_cmutex_unlock (mutex, tid)
+
+#else  /* Normal NPTL */
+
+#define FUSYN_FL_RT_MASK        0
+
+#define LLL_CMUTEX_LOCK(mutex, tid)     \
+        lll_mutex_lock(mutex)
+
+#define LLL_CMUTEX_UNLOCK(mutex, tid)   \
+        lll_mutex_unlock (mutex)
+
+#define lll_rtmutex_get_consistency(futex, state) 0
+
+#define lll_rtmutex_set_consistency(futex, state) 0
+
+#define lll_rtmutex_unlock_nocheck(futex) 0
+
+#define __LK_FL(fulock) 0
+
+#define FUSYN_FL_RT_BITS        0
+     
+#endif /* USE_FUSYN_ROBUST_MUTEX */
+
+
 #endif	/* lowlevellock.h */
diff -urN src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/lowlevelrtlock.c
src/nptl/sysdeps/unix/sysv/linux/ia64/lowlevelrtlock.c
--- src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/lowlevelrtlock.c
1970-01-01 08:00:00.000000000 +0800
+++ src/nptl/sysdeps/unix/sysv/linux/ia64/lowlevelrtlock.c
2004-01-31 11:51:20.000000000 +0800
@@ -0,0 +1,79 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by David Howell <david.p.howell@intel.com>, 2003.
+
+   Redirect lowlevellock to use Fast User SYNchronization(fusyn). 
+   Based on implementation for i386 by Boris Hu (Intel).
+   Dave Howell <david.p.howell@intel.com>, 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
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <sys/time.h>
+#include <pthread.h>
+#include <pthreadP.h>
+
+#include <linux/fulock.h>
+
+int __lll_rtmutex_timedlock (volatile unsigned *vfulock, unsigned
flags, 
+			     unsigned pid, const struct timespec *rel)
+{
+  int result;
+  struct timeval tv;
+  struct timespec rt, *p = NULL;
+
+  if (rel != (void *)-1 && rel != NULL) {
+    if (rel->tv_nsec < 0 || rel->tv_nsec >= 1000000000)
+      return EINVAL;
+
+    (void) __gettimeofday (&tv, NULL);
+  
+    rt.tv_sec = rel->tv_sec - tv.tv_sec;
+    rt.tv_nsec = rel->tv_nsec - tv.tv_usec * 1000;
+    if (rt.tv_nsec < 0)
+      {
+        rt.tv_nsec += 1000000000;
+        --rt.tv_sec;
+      }
+    if (rt.tv_sec < 0)
+      return ETIMEDOUT;
+    p = &rt;
+  } else if ((void *)-1 == rel)
+    p = (void *)-1;
+  
+ restart:
+  if (! atomic_compare_and_exchange_bool_acq (vfulock, pid,
VFULOCK_UNLOCKED))
+    return 0;
+  result = INLINE_SYSCALL (ufulock_lock, 3, vfulock, flags, (void *)p);
+  SEA_P("result :%d\n", result);
+  if (__builtin_expect (result < 0, 0))
+  {
+    result = -result;
+    SEA_P("result set to :%d\n", result);
+    if (result == EAGAIN || result == EINTR)
+      goto restart;
+  }
+  return result;  
+}
+
+int is_mutexattr_robust (const struct pthread_mutexattr *attr)
+{
+  return (attr->mutexkind & ((FULOCK_FL_RM | FULOCK_FL_RM_SUN) >> 1));
+}
+
diff -urN
src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_broadcast.c
src/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_broadcast.c
--- src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_broadcast.c
1970-01-01 08:00:00.000000000 +0800
+++ src/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_broadcast.c
2004-01-31 11:51:20.000000000 +0800
@@ -0,0 +1,2 @@
+
+#include "../i386/pthread_cond_broadcast.c"
diff -urN
src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_signal.c
src/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_signal.c
--- src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_signal.c
1970-01-01 08:00:00.000000000 +0800
+++ src/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_signal.c
2004-01-31 11:51:20.000000000 +0800
@@ -0,0 +1,2 @@
+
+#include "../i386/pthread_cond_signal.c"
diff -urN
src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_timedwait.c
src/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_timedwait.c
--- src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_timedwait.c
1970-01-01 08:00:00.000000000 +0800
+++ src/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_timedwait.c
2004-01-31 11:51:20.000000000 +0800
@@ -0,0 +1,2 @@
+
+#include "../i386/pthread_cond_timedwait.c"
diff -urN src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_wait.c
src/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_wait.c
--- src.cvs/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_wait.c
1970-01-01 08:00:00.000000000 +0800
+++ src/nptl/sysdeps/unix/sysv/linux/ia64/pthread_cond_wait.c
2004-01-31 11:51:20.000000000 +0800
@@ -0,0 +1,2 @@
+
+#include "../i386/pthread_cond_wait.c"


Good Luck !
Boris Hu (Hu Jiangtao)
Software Engineer@ICSL
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}


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