[RFC/PATCH] RT-NPTL-2.1 2/5
Hu, Boris
boris.hu@intel.com
Mon Feb 2 03:17:00 GMT 2004
Makefile | 12 +
pthread_create.c | 5
pthread_mutex_getconsistency_np.c | 18 ++
pthread_mutex_getprioceiling.c | 22 +++
pthread_mutex_init.c | 11 +
pthread_mutex_lock.c | 68
++++++---
pthread_mutex_lock_waiting_for_mutex_whose_owner_died_np.c | 26 +++
pthread_mutex_setconsistency_np.c | 25 +++
pthread_mutex_setprioceiling.c | 26 +++
pthread_mutex_timedlock.c | 91
++++++++-----
pthread_mutex_trylock.c | 87
+++++++-----
pthread_mutex_unlock.c | 63
+++++++--
pthread_mutexattr_getprioceiling.c | 25 +++
pthread_mutexattr_getprotocol.c | 36 +++++
pthread_mutexattr_getrobust_np.c | 37 +++++
pthread_mutexattr_setprioceiling.c | 29 ++++
pthread_mutexattr_setprotocol.c | 41 +++++
pthread_mutexattr_setrobust_np.c | 42 ++++++
sysdeps/pthread/pthread.h | 75
++++++++++
19 files changed, 636 insertions(+), 103 deletions(-)
diff -urN src.cvs/nptl/Makefile src/nptl/Makefile
--- src.cvs/nptl/Makefile 2004-01-31 11:49:05.000000000 +0800
+++ src/nptl/Makefile 2004-01-31 11:51:20.000000000 +0800
@@ -53,10 +53,21 @@
pthread_mutex_init pthread_mutex_destroy \
pthread_mutex_lock pthread_mutex_trylock \
pthread_mutex_timedlock pthread_mutex_unlock \
+ pthread_mutex_getconsistency_np \
+ pthread_mutex_setconsistency_np \
+ pthread_mutex_getprioceiling \
+ pthread_mutex_setprioceiling \
+
pthread_mutex_lock_waiting_for_mutex_whose_owner_died_np \
pthread_mutexattr_init pthread_mutexattr_destroy \
pthread_mutexattr_getpshared \
pthread_mutexattr_setpshared \
pthread_mutexattr_gettype
pthread_mutexattr_settype \
+ pthread_mutexattr_getrobust_np \
+ pthread_mutexattr_setrobust_np \
+ pthread_mutexattr_getprotocol \
+ pthread_mutexattr_setprotocol \
+ pthread_mutexattr_getprioceiling \
+ pthread_mutexattr_setprioceiling \
pthread_rwlock_init pthread_rwlock_destroy \
pthread_rwlock_rdlock pthread_rwlock_timedrdlock \
pthread_rwlock_wrlock pthread_rwlock_timedwrlock \
@@ -102,6 +113,7 @@
pt-longjmp \
cancellation \
lowlevellock \
+ lowlevelrtlock \
pt-vfork \
ptw-write ptw-read ptw-close ptw-fcntl ptw-accept
\
ptw-connect ptw-recv ptw-recvfrom ptw-recvmsg
ptw-send \
diff -urN src.cvs/nptl/pthread_create.c src/nptl/pthread_create.c
--- src.cvs/nptl/pthread_create.c 2004-01-31 11:49:05.000000000
+0800
+++ src/nptl/pthread_create.c 2004-01-31 11:51:20.000000000 +0800
@@ -2,6 +2,9 @@
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+ Enable priority scheduling parameters feature.
+ Boris Hu <boris.hu@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
@@ -399,7 +402,7 @@
/* Determine scheduling parameters for the thread.
XXX How to determine whether scheduling handling is needed? */
- if (0 && attr != NULL)
+ if (attr != NULL)
{
if (iattr->flags & ATTR_FLAG_NOTINHERITSCHED)
{
diff -urN src.cvs/nptl/pthread_mutexattr_getprioceiling.c
src/nptl/pthread_mutexattr_getprioceiling.c
--- src.cvs/nptl/pthread_mutexattr_getprioceiling.c 1970-01-01
08:00:00.000000000 +0800
+++ src/nptl/pthread_mutexattr_getprioceiling.c 2004-01-31
11:51:20.000000000 +0800
@@ -0,0 +1,25 @@
+/*
+ * (C) 2003 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <pthreadP.h>
+
+
+int
+pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *__attr,
+ int *__prioceiling)
+{
+ const struct pthread_mutexattr *iattr;
+
+ iattr = (const struct pthread_mutexattr *) __attr;
+
+ /* Use Bit 0-6 to indicate the priority ceiling value.
+ * -- 0 ~~ MAX_USER_RT_PRIO
+ */
+ *__prioceiling = iattr->mutexkind & PRIOCEILING_MASK;
+
+ return 0;
+}
diff -urN src.cvs/nptl/pthread_mutexattr_getprotocol.c
src/nptl/pthread_mutexattr_getprotocol.c
--- src.cvs/nptl/pthread_mutexattr_getprotocol.c 1970-01-01
08:00:00.000000000 +0800
+++ src/nptl/pthread_mutexattr_getprotocol.c 2004-01-31
11:51:20.000000000 +0800
@@ -0,0 +1,36 @@
+/*
+ * (C) 2002-2003 Intel Corporation
+ * Bing Wei Liu <bing.wei.liu@intel.com>.
+ *
+ * Reimplement to sync with fusyn and POSIX spec.
+ * (C) 2003 Intel Corporation Boris Hu <boris.hu@intel.com>
+ *
+ * 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;
+ int rtflags;
+
+ iattr = (const struct pthread_mutexattr *) attr;
+
+ /* Use Bit 30, 29 to indicate the protocol of mutex :
+ -- PTHREAD_PRIO_NONE (00)
+ -- PTHREAD_PRIO_INHERIT (10)
+ -- PTHREAD_PRIO_PROTECT (01) */
+
+ rtflags = iattr->mutexkind << 1;
+
+ *protocol = rtflags & FULOCK_FL_PI ? PTHREAD_PRIO_INHERIT
+ : rtflags & FULOCK_FL_PP ? PTHREAD_PRIO_PROTECT
+ : PTHREAD_PRIO_NONE;
+
+ return 0;
+}
diff -urN src.cvs/nptl/pthread_mutexattr_getrobust_np.c
src/nptl/pthread_mutexattr_getrobust_np.c
--- src.cvs/nptl/pthread_mutexattr_getrobust_np.c 1970-01-01
08:00:00.000000000 +0800
+++ src/nptl/pthread_mutexattr_getrobust_np.c 2004-01-31
11:51:20.000000000 +0800
@@ -0,0 +1,37 @@
+/*
+ * (C) 2002-2003 Intel Corporation
+ * Bing Wei Liu <bing.wei.liu@intel.com>.
+ *
+ * Reimplement to sync with fusyn and POSIX spec.
+ * (C) 2003 Intel Corporation Boris Hu <boris.hu@intel.com>
+ *
+ * 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;
+ int rtflags;
+
+ iattr = (const struct pthread_mutexattr *) attr;
+
+ /* Use Bit 28, 27 to indicate the robustness type of mutex :
+ * -- PTHREAD_MUTEX_NOROBUST_NP (00)
+ * -- PTHREAD_MUTEX_ROBUST_NP (01)
+ * -- PTHREAD_MUTEX_ROBUST2_NP (10)
+ */
+
+ rtflags = iattr->mutexkind << 1;
+
+ *robustness = rtflags & FULOCK_FL_RM ? PTHREAD_MUTEX_ROBUST_NP
+ : rtflags & FULOCK_FL_RM_SUN ? PTHREAD_MUTEX_ROBUST2_NP
+ : PTHREAD_MUTEX_NOROBUST_NP;
+
+ return 0;
+}
diff -urN src.cvs/nptl/pthread_mutexattr_setprioceiling.c
src/nptl/pthread_mutexattr_setprioceiling.c
--- src.cvs/nptl/pthread_mutexattr_setprioceiling.c 1970-01-01
08:00:00.000000000 +0800
+++ src/nptl/pthread_mutexattr_setprioceiling.c 2004-01-31
11:51:20.000000000 +0800
@@ -0,0 +1,29 @@
+/*
+ * (C) 2003 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <pthreadP.h>
+#include <errno.h>
+
+int
+pthread_mutexattr_setprioceiling (pthread_mutexattr_t *__attr,
+ int __prioceiling)
+{
+ struct pthread_mutexattr *iattr;
+ int errno = EINVAL;
+
+ if (__prioceiling < 0 || __prioceiling > MAX_USER_RT_PRIO)
+ return errno;
+
+ iattr = (const struct pthread_mutexattr *) __attr;
+
+ /* Use Bit 0-6 to indicate the priority ceiling value.
+ * -- 0 ~~ MAX_USER_RT_PRIO
+ */
+ iattr->mutexkind |= (__prioceiling & PRIOCEILING_MASK);
+
+ return 0;
+}
diff -urN src.cvs/nptl/pthread_mutexattr_setprotocol.c
src/nptl/pthread_mutexattr_setprotocol.c
--- src.cvs/nptl/pthread_mutexattr_setprotocol.c 1970-01-01
08:00:00.000000000 +0800
+++ src/nptl/pthread_mutexattr_setprotocol.c 2004-01-31
11:51:20.000000000 +0800
@@ -0,0 +1,41 @@
+/*
+ * (C) 2002-2003 Intel Corporation
+ * Bing Wei Liu <bing.wei.liu@intel.com>.
+ *
+ * Reimplement to sync with fusyn and POSIX spec.
+ * (C) 2003 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_setprotocol (attr, protocol)
+ pthread_mutexattr_t *attr;
+ int protocol;
+{
+ struct pthread_mutexattr *iattr;
+ int rtflags = 0;
+
+ if (protocol < PTHREAD_PRIO_NONE || protocol > PTHREAD_PRIO_PROTECT)
+ return EINVAL;
+
+ iattr = (struct pthread_mutexattr *) attr;
+
+ /* Use Bit 30, 29 to indicate the protocol of mutex :
+ -- PTHREAD_PRIO_NONE (00)
+ -- PTHREAD_PRIO_INHERIT (10)
+ -- PTHREAD_PRIO_PROTECT (01) */
+
+ if (protocol == PTHREAD_PRIO_INHERIT)
+ rtflags |= FULOCK_FL_PI | FULOCK_FL_RM;
+ else if (protocol == PTHREAD_PRIO_PROTECT)
+ rtflags |= FULOCK_FL_PP | FULOCK_FL_RM;
+
+ iattr->mutexkind |= rtflags >> 1;
+
+ return 0;
+}
diff -urN src.cvs/nptl/pthread_mutexattr_setrobust_np.c
src/nptl/pthread_mutexattr_setrobust_np.c
--- src.cvs/nptl/pthread_mutexattr_setrobust_np.c 1970-01-01
08:00:00.000000000 +0800
+++ src/nptl/pthread_mutexattr_setrobust_np.c 2004-01-31
11:51:20.000000000 +0800
@@ -0,0 +1,42 @@
+/*
+ * (C) 2002-2003 Intel Corporation
+ * Bing Wei Liu <bing.wei.liu@intel.com>.
+ *
+ * Reimplement to sync with fusyn and POSIX spec.
+ * (C) 2003 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_setrobust_np (attr, robustness)
+ pthread_mutexattr_t *attr;
+ int robustness;
+{
+ struct pthread_mutexattr *iattr;
+ unsigned int rtflags = 0;
+
+ if (robustness < PTHREAD_MUTEX_NOROBUST_NP || robustness >
PTHREAD_MUTEX_ROBUST2_NP)
+ return EINVAL;
+
+ iattr = (struct pthread_mutexattr *) attr;
+
+ /* Use Bit 28, 27 to indicate the robustness type of mutex :
+ * -- PTHREAD_MUTEX_NOROBUST_NP (00)
+ * -- PTHREAD_MUTEX_ROBUST_NP (01)
+ * -- PTHREAD_MUTEX_ROBUST2_NP (11)
+ */
+
+ if (robustness == PTHREAD_MUTEX_ROBUST_NP)
+ rtflags |= FULOCK_FL_RM;
+ else if (robustness == PTHREAD_MUTEX_ROBUST2_NP)
+ rtflags |= FULOCK_FL_RM_SUN;
+
+ iattr->mutexkind |= rtflags >> 1;
+
+ return 0;
+}
diff -urN src.cvs/nptl/pthread_mutex_getconsistency_np.c
src/nptl/pthread_mutex_getconsistency_np.c
--- src.cvs/nptl/pthread_mutex_getconsistency_np.c 1970-01-01
08:00:00.000000000 +0800
+++ src/nptl/pthread_mutex_getconsistency_np.c 2004-01-31
11:51:20.000000000 +0800
@@ -0,0 +1,18 @@
+/*
+ * (C) 2002-2003 Intel Corporation
+ * Bing Wei Liu <bing.wei.liu@intel.com>.
+ *
+ * Reimplement to sync with fusyn and POSIX spec.
+ * (C) 2003 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_mutex_getconsistency_np(const pthread_mutex_t *mutex, int
*state)
+{
+ return lll_rtmutex_get_consistency (mutex->__data.__lock, state);
+}
diff -urN src.cvs/nptl/pthread_mutex_getprioceiling.c
src/nptl/pthread_mutex_getprioceiling.c
--- src.cvs/nptl/pthread_mutex_getprioceiling.c 1970-01-01
08:00:00.000000000 +0800
+++ src/nptl/pthread_mutex_getprioceiling.c 2004-01-31
11:51:20.000000000 +0800
@@ -0,0 +1,22 @@
+/*
+ * (C) 2003 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <pthreadP.h>
+
+
+int
+pthread_mutex_getprioceiling (const pthread_mutex_t *__mutex,
+ int *__prioceiling)
+{
+ /* Use Bit 0-6 to indicate the priority ceiling value.
+ * -- 0 ~~ MAX_USER_RT_PRIO
+ */
+
+ *__prioceiling = __mutex->__data.__prioceiling;
+
+ return 0;
+}
diff -urN src.cvs/nptl/pthread_mutex_init.c
src/nptl/pthread_mutex_init.c
--- src.cvs/nptl/pthread_mutex_init.c 2004-01-31 11:49:05.000000000
+0800
+++ src/nptl/pthread_mutex_init.c 2004-01-31 11:51:20.000000000
+0800
@@ -40,9 +40,16 @@
imutexattr = (const struct pthread_mutexattr *) mutexattr ?:
&default_attr;
+ if (__builtin_expect (is_mutexattr_robust (imutexattr), 0)) {
+ lll_rtmutex_set_consistency (mutex->__data.__lock,
+ PTHREAD_MUTEX_ROBUST_CONSISTENT_NP);
+ return 0;
+ }
+
+
/* Clear the whole variable. */
memset (mutex, '\0', __SIZEOF_PTHREAD_MUTEX_T);
-
+
/* Copy the values from the attribute. */
mutex->__data.__kind = imutexattr->mutexkind & ~0x80000000;
@@ -51,6 +58,8 @@
// mutex->__owner = 0; already done by memset
// mutex->__nusers = 0; already done by memset
+ mutex->__data.__prioceiling = imutexattr->mutexkind &
PRIOCEILING_MASK;
+
return 0;
}
strong_alias (__pthread_mutex_init, pthread_mutex_init)
diff -urN src.cvs/nptl/pthread_mutex_lock.c
src/nptl/pthread_mutex_lock.c
--- src.cvs/nptl/pthread_mutex_lock.c 2004-01-31 11:49:05.000000000
+0800
+++ src/nptl/pthread_mutex_lock.c 2004-01-31 11:51:20.000000000
+0800
@@ -2,6 +2,9 @@
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+ Redirect lowlevellock to use Fast User SYNchronization(fusyn).
+ Boris Hu <boris.hu@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
@@ -22,9 +25,20 @@
#include "pthreadP.h"
#include <lowlevellock.h>
+#include <stdio.h>
+#include <stdlib.h>
#ifndef LLL_MUTEX_LOCK
-# define LLL_MUTEX_LOCK(mutex) lll_mutex_lock (mutex)
+# ifdef USE_FUSYN_ROBUST_MUTEX
+# define LLL_MUTEX_LOCK(mutex, tid) \
+ do { \
+ result = lll_rtmutex_lock (mutex,tid); \
+ if (__builtin_expect (0 != result, 0)) \
+ goto out_err; \
+ } while (0)
+# else
+# define LLL_MUTEX_LOCK(mutex, tid) lll_mutex_lock(mutex)
+# endif
#endif
@@ -33,55 +47,65 @@
pthread_mutex_t *mutex;
{
pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
-
- switch (__builtin_expect (mutex->__data.__kind,
PTHREAD_MUTEX_TIMED_NP))
+ int result = 0;
+
+ switch (__builtin_expect (mutex->__data.__kind & ~FUSYN_FL_RT_MASK,
+ PTHREAD_MUTEX_TIMED_NP))
{
/* Recursive mutex. */
case PTHREAD_MUTEX_RECURSIVE_NP:
/* Check whether we already hold the mutex. */
if (mutex->__data.__owner == id)
- {
- /* Just bump the counter. */
- if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
- /* Overflow of the counter. */
- return EAGAIN;
-
- ++mutex->__data.__count;
-
- return 0;
- }
-
+ {
+ /* Just bump the counter. */
+ if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+ /* Overflow of the counter. */
+ return EAGAIN;
+
+ ++mutex->__data.__count;
+
+ return 0;
+ }
+
/* We have to get the mutex. */
- LLL_MUTEX_LOCK (mutex->__data.__lock);
+ LLL_MUTEX_LOCK (mutex->__data.__lock, id);
mutex->__data.__count = 1;
break;
-
+
/* Error checking mutex. */
case PTHREAD_MUTEX_ERRORCHECK_NP:
/* Check whether we already hold the mutex. */
if (mutex->__data.__owner == id)
- return EDEADLK;
-
+ return EDEADLK;
+
/* FALLTHROUGH */
-
+
default:
/* Correct code cannot set any other type. */
case PTHREAD_MUTEX_TIMED_NP:
case PTHREAD_MUTEX_ADAPTIVE_NP:
/* Normal mutex. */
- LLL_MUTEX_LOCK (mutex->__data.__lock);
+ LLL_MUTEX_LOCK (mutex->__data.__lock, id);
break;
}
-
+
/* Record the ownership. */
assert (mutex->__data.__owner == 0);
mutex->__data.__owner = id;
+
#ifndef NO_INCR
++mutex->__data.__nusers;
#endif
-
return 0;
+
+out_err:
+ /* owner dead or not recoverable */
+ if (__builtin_expect (EOWNERDEAD == result || ENOTRECOVERABLE ==
result, 0))
+ if (! is_mutex_robust (mutex)) /* non-robust mutex */
+ pthread_mutex_lock_waiting_for_mutex_whose_owner_died_np (mutex,
(void *)-1);
+
+ return result;
}
#ifndef __pthread_mutex_lock
strong_alias (__pthread_mutex_lock, pthread_mutex_lock)
diff -urN
src.cvs/nptl/pthread_mutex_lock_waiting_for_mutex_whose_owner_died_np.c
src/nptl/pthread_mutex_lock_waiting_for_mutex_whose_owner_died_np.c
---
src.cvs/nptl/pthread_mutex_lock_waiting_for_mutex_whose_owner_died_np.c
1970-01-01 08:00:00.000000000 +0800
+++ src/nptl/pthread_mutex_lock_waiting_for_mutex_whose_owner_died_np.c
2004-01-31 11:51:20.000000000 +0800
@@ -0,0 +1,26 @@
+/*
+ * (C) 2003 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * (C) 2003 Intel Corporation Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <pthreadP.h>
+#include <errno.h>
+#include <time.h>
+
+int
+pthread_mutex_lock_waiting_for_mutex_whose_owner_died_np
(pthread_mutex_t *__mutex,
+ const struct timespec *__reltime)
+{
+ /* Hang to tell the position when the owner of the lock is dead
+ * for non-RM lock. */
+ if ((void *)-1 == __reltime)
+ while (1) ;
+ else
+ nanosleep(__reltime, NULL);
+
+ return ETIMEDOUT;
+}
diff -urN src.cvs/nptl/pthread_mutex_setconsistency_np.c
src/nptl/pthread_mutex_setconsistency_np.c
--- src.cvs/nptl/pthread_mutex_setconsistency_np.c 1970-01-01
08:00:00.000000000 +0800
+++ src/nptl/pthread_mutex_setconsistency_np.c 2004-01-31
11:51:20.000000000 +0800
@@ -0,0 +1,25 @@
+/*
+ * (C) 2002-2003 Intel Corporation
+ * Bing Wei Liu <bing.wei.liu@intel.com>.
+ *
+ * Reimplement to sync with fusyn and POSIX spec.
+ * (C) 2003 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_mutex_setconsistency_np(mutex, state)
+ pthread_mutex_t *mutex;
+ int state;
+{
+ int result = 0;
+
+ if (state < 0 || state > PTHREAD_MUTEX_ROBUST_DEADOWNER_NP)
+ return EINVAL;
+
+ result = lll_rtmutex_set_consistency (mutex->__data.__lock, state);
+ return 0;
+}
diff -urN src.cvs/nptl/pthread_mutex_setprioceiling.c
src/nptl/pthread_mutex_setprioceiling.c
--- src.cvs/nptl/pthread_mutex_setprioceiling.c 1970-01-01
08:00:00.000000000 +0800
+++ src/nptl/pthread_mutex_setprioceiling.c 2004-01-31
11:51:20.000000000 +0800
@@ -0,0 +1,26 @@
+/*
+ * (C) 2003 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <pthreadP.h>
+#include <errno.h>
+
+int
+pthread_mutex_setprioceiling (pthread_mutex_t *__mutex,
+ int __prioceiling)
+{
+ int errno = EINVAL;
+
+ if (__prioceiling < 0 || __prioceiling > MAX_USER_RT_PRIO)
+ return errno;
+
+ /* Use Bit 0-6 to indicate the priority ceiling value.
+ * -- 0 ~~ MAX_USER_RT_PRIO
+ */
+ __mutex->__data.__prioceiling = __prioceiling;
+
+ return 0;
+}
diff -urN src.cvs/nptl/pthread_mutex_timedlock.c
src/nptl/pthread_mutex_timedlock.c
--- src.cvs/nptl/pthread_mutex_timedlock.c 2004-01-31
11:49:05.000000000 +0800
+++ src/nptl/pthread_mutex_timedlock.c 2004-01-31 11:51:20.000000000
+0800
@@ -2,6 +2,9 @@
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+ Redirect lowlevellock to use Fast User SYNchronization(fusyn).
+ Boris Hu <boris.hu@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
@@ -17,10 +20,21 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <assert.h>
#include <errno.h>
+#include <stdio.h>
#include "pthreadP.h"
#include <lowlevellock.h>
+#ifndef LLL_MUTEX_TIMEDLOCK
+# ifdef USE_FUSYN_ROBUST_MUTEX
+# define LLL_MUTEX_TIMEDLOCK(mutex, tid, abstime) \
+ lll_rtmutex_timedlock (mutex, tid, abstime);
+# else
+# define LLL_MUTEX_TIMEDLOCK(mutex, tid, abstime) \
+ lll_mutex_timedlock (mutex, abstime)
+# endif
+#endif
int
pthread_mutex_timedlock (mutex, abstime)
@@ -33,59 +47,66 @@
/* We must not check ABSTIME here. If the thread does not block
abstime must not be checked for a valid value. */
- switch (mutex->__data.__kind)
+ switch (__builtin_expect (mutex->__data.__kind & ~FUSYN_FL_RT_MASK,
+ PTHREAD_MUTEX_TIMED_NP))
{
/* Recursive mutex. */
case PTHREAD_MUTEX_RECURSIVE_NP:
/* Check whether we already hold the mutex. */
if (mutex->__data.__owner == id)
- {
- /* Just bump the counter. */
- if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
- /* Overflow of the counter. */
- return EAGAIN;
-
- ++mutex->__data.__count;
-
- goto out;
- }
+ {
+ /* Just bump the counter. */
+ if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+ /* Overflow of the counter. */
+ return EAGAIN;
+
+ ++mutex->__data.__count;
+
+ return 0;
+ }
else
- {
- /* We have to get the mutex. */
- result = lll_mutex_timedlock (mutex->__data.__lock, abstime);
-
- if (result != 0)
- goto out;
-
- /* Only locked once so far. */
- mutex->__data.__count = 1;
- }
+ {
+ /* We have to get the mutex. */
+ result = LLL_MUTEX_TIMEDLOCK (mutex->__data.__lock, id,
abstime);
+ if (0 != result)
+ goto out_err;
+
+ /* Only locked once so far. */
+ mutex->__data.__count = 1;
+ }
break;
-
+
/* Error checking mutex. */
case PTHREAD_MUTEX_ERRORCHECK_NP:
/* Check whether we already hold the mutex. */
if (mutex->__data.__owner == id)
- return EDEADLK;
-
+ return EDEADLK;
+
/* FALLTHROUGH */
-
+
default:
/* Correct code cannot set any other type. */
case PTHREAD_MUTEX_TIMED_NP:
case PTHREAD_MUTEX_ADAPTIVE_NP:
/* Normal mutex. */
- result = lll_mutex_timedlock (mutex->__data.__lock, abstime);
+ result = LLL_MUTEX_TIMEDLOCK (mutex->__data.__lock, id, abstime);
+ if (0 != result)
+ goto out_err;
break;
}
-
- if (result == 0)
- {
- /* Record the ownership. */
- mutex->__data.__owner = id;
- ++mutex->__data.__nusers;
- }
-
- out:
+
+ /* Record the ownership. */
+ mutex->__data.__owner = id;
+ ++mutex->__data.__nusers;
+
+ return 0;
+
+out_err:
+ /* owner dead or not recoverable */
+ if (__builtin_expect(EOWNERDEAD == result || ENOTRECOVERABLE ==
result, 0))
+ if ( !is_mutex_robust (mutex)) /* non-robust mutex */
+ result = pthread_mutex_lock_waiting_for_mutex_whose_owner_died_np
(
+ mutex, abstime);
+
return result;
}
diff -urN src.cvs/nptl/pthread_mutex_trylock.c
src/nptl/pthread_mutex_trylock.c
--- src.cvs/nptl/pthread_mutex_trylock.c 2004-01-31
11:49:05.000000000 +0800
+++ src/nptl/pthread_mutex_trylock.c 2004-01-31 11:51:20.000000000
+0800
@@ -1,6 +1,9 @@
/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ Redirect lowlevellock to use Fast User SYNchronization(fusyn).
+ Boris Hu <boris.hu@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
@@ -21,57 +24,77 @@
#include "pthreadP.h"
#include <lowlevellock.h>
+#ifndef LLL_MUTEX_TRYLOCK
+# ifdef USE_FUSYN_ROBUST_MUTEX
+# define LLL_MUTEX_TRYLOCK(mutex, tid) \
+ lll_rtmutex_trylock (mutex, tid)
+# else
+# define LLL_MUTEX_TRYLOCK(mutex, tid) \
+ ({ int ret = lll_mutex_trylock (mutex); \
+ ret = 0 != ret ? EBUSY : 0; \
+ ret; })
+# endif
+#endif
int
__pthread_mutex_trylock (mutex)
pthread_mutex_t *mutex;
{
- pid_t id;
+ pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
+ int result;
- switch (__builtin_expect (mutex->__data.__kind,
PTHREAD_MUTEX_TIMED_NP))
+ switch (__builtin_expect (mutex->__data.__kind & ~FUSYN_FL_RT_MASK,
+ PTHREAD_MUTEX_TIMED_NP))
{
/* Recursive mutex. */
case PTHREAD_MUTEX_RECURSIVE_NP:
- id = THREAD_GETMEM (THREAD_SELF, tid);
/* Check whether we already hold the mutex. */
if (mutex->__data.__owner == id)
- {
- /* Just bump the counter. */
- if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
- /* Overflow of the counter. */
- return EAGAIN;
-
- ++mutex->__data.__count;
- return 0;
- }
-
- if (lll_mutex_trylock (mutex->__data.__lock) == 0)
- {
- /* Record the ownership. */
- mutex->__data.__owner = id;
- mutex->__data.__count = 1;
- ++mutex->__data.__nusers;
- return 0;
- }
- break;
+ {
+ /* Just bump the counter. */
+ if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+ /* Overflow of the counter. */
+ return EAGAIN;
+
+ ++mutex->__data.__count;
+ return 0;
+ }
+
+ result = LLL_MUTEX_TRYLOCK (mutex->__data.__lock, id);
+ if (__builtin_expect (0 != result, 0))
+ goto out_err;
+
+ /* Record the ownership. */
+ mutex->__data.__owner = id;
+ mutex->__data.__count = 1;
+ ++mutex->__data.__nusers;
+ break;
+
case PTHREAD_MUTEX_ERRORCHECK_NP:
/* Error checking mutex. We do not check for deadlocks. */
default:
- /* Correct code cannot set any other type. */
+ /* Correct code cannot set any other type. */
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 = THREAD_GETMEM (THREAD_SELF, tid);
- ++mutex->__data.__nusers;
-
- return 0;
- }
+ result = LLL_MUTEX_TRYLOCK (mutex->__data.__lock, id);
+ if (__builtin_expect (0 != result, 0))
+ goto out_err;
+
+ /* Record the ownership. */
+ mutex->__data.__owner = id;
+ ++mutex->__data.__nusers;
}
+
+ return 0;
+
+out_err:
+ /* owner dead or not recoverable */
+ if (__builtin_expect (EOWNERDEAD == result || ENOTRECOVERABLE ==
result, 0))
+ if (! is_mutex_robust(mutex)) /* non-robust mutex */
+ pthread_mutex_lock_waiting_for_mutex_whose_owner_died_np (mutex,
(void *)-1);
- return EBUSY;
+ return result;
}
strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock)
diff -urN src.cvs/nptl/pthread_mutex_unlock.c
src/nptl/pthread_mutex_unlock.c
--- src.cvs/nptl/pthread_mutex_unlock.c 2004-01-31 11:49:05.000000000
+0800
+++ src/nptl/pthread_mutex_unlock.c 2004-01-31 11:51:20.000000000
+0800
@@ -2,6 +2,9 @@
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+ Redirect lowlevellock to use Fast User SYNchronization(fusyn).
+ Boris Hu <boris.hu@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
@@ -21,6 +24,17 @@
#include "pthreadP.h"
#include <lowlevellock.h>
+#ifndef LLL_MUTEX_UNLOCK
+# ifdef USE_FUSYN_ROBUST_MUTEX
+# define LLL_MUTEX_UNLOCK(mutex, tid) \
+ do { \
+ result = lll_rtmutex_unlock(mutex,tid); \
+ } while (0)
+# else
+# define LLL_MUTEX_UNLOCK(mutex, tid) lll_mutex_unlock(mutex)
+# endif
+#endif
+
int
internal_function attribute_hidden
@@ -28,23 +42,27 @@
pthread_mutex_t *mutex;
int decr;
{
- switch (__builtin_expect (mutex->__data.__kind,
PTHREAD_MUTEX_TIMED_NP))
+ pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
+ int result = 0;
+
+ switch (__builtin_expect (mutex->__data.__kind & ~FUSYN_FL_RT_MASK,
+ PTHREAD_MUTEX_TIMED_NP))
{
case PTHREAD_MUTEX_RECURSIVE_NP:
/* Recursive mutex. */
- if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
- return EPERM;
+ if (mutex->__data.__owner != id)
+ return EPERM;
if (--mutex->__data.__count != 0)
- /* We still hold the mutex. */
- return 0;
+ /* We still hold the mutex. */
+ return 0;
break;
case PTHREAD_MUTEX_ERRORCHECK_NP:
/* Error checking mutex. */
- if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid)
- || ! lll_mutex_islocked (mutex->__data.__lock))
- return EPERM;
+ if (mutex->__data.__owner != id
+ || ! lll_mutex_islocked (mutex->__data.__lock))
+ return EPERM;
break;
default:
@@ -55,16 +73,37 @@
break;
}
- /* Always reset the owner field. */
mutex->__data.__owner = 0;
+
if (decr)
/* One less user. */
--mutex->__data.__nusers;
- /* Unlock. */
- lll_mutex_unlock (mutex->__data.__lock);
+ if (__builtin_expect (mutex->__data.__kind & (FULOCK_FL_RM_SUN >> 1),
0))
+ goto solaris_compat_mode;
+
+ /* Always reset the owner field. */
+ LLL_MUTEX_UNLOCK (mutex->__data.__lock, id);
+
+ return result;
- return 0;
+solaris_compat_mode:
+ {
+ int owner_tid = mutex->__data.__lock;
+ if (__builtin_expect (owner_tid == VFULOCK_DEAD, 0))
+ {
+ if ((result = lll_rtmutex_set_consistency ( \
+ mutex->__data.__lock,
+ PTHREAD_MUTEX_ROBUST_CONSISTENT_NP)) != 0)
+ return result;
+ result = lll_rtmutex_unlock_nocheck (mutex->__data.__lock);
+ }
+ else
+ {
+ LLL_MUTEX_UNLOCK (mutex->__data.__lock, id);
+ }
+ }
+ return result;
}
diff -urN src.cvs/nptl/sysdeps/pthread/pthread.h
src/nptl/sysdeps/pthread/pthread.h
--- src.cvs/nptl/sysdeps/pthread/pthread.h 2004-01-31
11:49:05.000000000 +0800
+++ src/nptl/sysdeps/pthread/pthread.h 2004-01-31 11:51:20.000000000
+0800
@@ -59,6 +59,37 @@
#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
+};
+
+/* Robust mutex states. */
+enum
+{
+ PTHREAD_MUTEX_ROBUST_NOP_NP=0,
+ PTHREAD_MUTEX_ROBUST_INIT_NP,
+ PTHREAD_MUTEX_ROBUST_CONSISTENT_NP,
+ PTHREAD_MUTEX_ROBUST_NOTRECOVERABLE_NP,
+ PTHREAD_MUTEX_ROBUST_DEADOWNER_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 \
{ }
@@ -684,6 +715,50 @@
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;
+
+/* Set the mutex to given state */
+extern int pthread_mutex_setconsistency_np (pthread_mutex_t *__restrict
__mutex,
+ int __state) __THROW;
+
+/* Set the mutex to 'health' state */
+extern int pthread_mutex_getconsistency_np (__const pthread_mutex_t
*__restrict __mutex,
+ int *__restrict __state)
__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) __THROW;
+
#ifdef __USE_UNIX98
/* Return in *KIND the mutex kind attribute in *ATTR. */
extern int pthread_mutexattr_gettype (__const pthread_mutexattr_t
*__restrict
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}
More information about the Libc-alpha
mailing list