This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
[RFC/PATCH] RT-NPTL-2.2 2/5
- From: "Hu, Boris" <boris dot hu at intel dot com>
- To: <libc-alpha at sources dot redhat dot com>
- Cc: "Robustmutexes" <robustmutexes at lists dot osdl dot org>
- Date: Thu, 29 Apr 2004 17:52:31 +0800
- Subject: [RFC/PATCH] RT-NPTL-2.2 2/5
pthread_mutex_setprioceiling.c | 33 +++++++++
pthread_mutex_timedlock.c | 34 +++++++--
pthread_mutex_trylock.c | 86 +++++++++++++++---------
pthread_mutex_unlock.c | 63 ++++++++++++++---
pthread_mutexattr_getfast_np.c | 24 ++++++
pthread_mutexattr_getprioceiling.c | 26 +++++++
pthread_mutexattr_getprotocol.c | 36 ++++++++++
pthread_mutexattr_getrobust_np.c | 37 ++++++++++
pthread_mutexattr_getserial_np.c | 24 ++++++
pthread_mutexattr_gettype.c | 2
pthread_mutexattr_init.c | 3
pthread_mutexattr_setfast_np.c | 28 +++++++
pthread_mutexattr_setprioceiling.c | 30 ++++++++
pthread_mutexattr_setprotocol.c | 43 ++++++++++++
pthread_mutexattr_setrobust_np.c | 45 ++++++++++++
pthread_mutexattr_setserial_np.c | 29 ++++++++
pthread_mutexattr_settype.c | 2
sysdeps/pthread/pthread.h | 132
+++++++++++++++++++++++++++++++++++++
tst-fast1.c | 117
++++++++++++++++++++++++++++++++
tst-serial1.c | 118
+++++++++++++++++++++++++++++++++
20 files changed, 859 insertions(+), 53 deletions(-)
--- /dev/null Thu Apr 29 09:10:10 2004
+++ robustmutexes/rtnptl/src/nptl/pthread_mutex_setprioceiling.c
Tue Apr 13 11:37:02 2004
@@ -0,0 +1,33 @@
+/*
+ * (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 *__old_ceiling)
+{
+
+ if (__prioceiling < MIN_USER_RT_PRIO || __prioceiling >
MAX_USER_RT_PRIO)
+ return EINVAL;
+
+ /* Use Bit PRIOCEILING_OFFSET - PRIOCEILING_OFFSET + 6 to
+ * indicate the priority ceiling value.
+ * -- MIN_USER_RT_PRIO ~~ MAX_USER_RT_PRIO
+ */
+ int res = pthread_mutex_lock (__mutex);
+ if (__builtin_expect (res != 0, 0))
+ return res;
+
+ *__old_ceiling = __mutex->__data.__kind & PRIOCEILING_MASK;
+ __mutex->__data.__kind &= ~PRIOCEILING_MASK;
+ __mutex->__data.__kind |= __prioceiling << PRIOCEILING_OFFSET;
+ pthread_mutex_unlock(__mutex);
+
+ return 0;
+}
--- robustmutexes/rtnptl/src/nptl/pthread_mutex_timedlock.c:1.1.1.1.2.1
Fri Mar 26 02:41:35 2004
+++ robustmutexes/rtnptl/src/nptl/pthread_mutex_timedlock.c Thu Apr
29 08:26:18 2004
@@ -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,19 @@
#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)
+# define LLL_MUTEX_TRYLOCK(mutex, tid) \
+ lll_rtmutex_trylock(mutex, tid)
+# else
+# define LLL_MUTEX_TIMEDLOCK(mutex, tid, abstime) \
+ lll_mutex_timedlock (mutex, abstime)
+# define LLL_MUTEX_TRYLOCK(mutex, tid) \
+ lll_mutex_trylock(mutex)
+# endif
+#endif
int
pthread_mutex_timedlock (mutex, abstime)
@@ -33,7 +49,7 @@
/* 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 (mutex->__data.__kind & ~NON_MUTEX_KIND_MASK)
{
/* Recursive mutex. */
case PTHREAD_MUTEX_RECURSIVE_NP:
@@ -52,7 +68,7 @@
else
{
/* We have to get the mutex. */
- result = lll_mutex_timedlock (mutex->__data.__lock, abstime);
+ result = LLL_MUTEX_TIMEDLOCK (mutex->__data.__lock, id,
abstime);
if (result != 0)
goto out;
@@ -75,14 +91,14 @@
case PTHREAD_MUTEX_TIMED_NP:
simple:
/* Normal mutex. */
- result = lll_mutex_timedlock (mutex->__data.__lock, abstime);
+ result = LLL_MUTEX_TIMEDLOCK (mutex->__data.__lock, id, abstime);
break;
case PTHREAD_MUTEX_ADAPTIVE_NP:
if (! __is_smp)
goto simple;
- if (lll_mutex_trylock (mutex->__data.__lock) != 0)
+ if (LLL_MUTEX_TRYLOCK (mutex->__data.__lock, id) != 0)
{
int cnt = 0;
int max_cnt = MIN (MAX_ADAPTIVE_COUNT,
@@ -91,7 +107,7 @@
{
if (cnt++ >= max_cnt)
{
- result = lll_mutex_timedlock (mutex->__data.__lock,
abstime);
+ result = LLL_MUTEX_TIMEDLOCK (mutex->__data.__lock,
id, abstime);
break;
}
@@ -99,7 +115,7 @@
BUSY_WAIT_NOP;
#endif
}
- while (lll_mutex_trylock (mutex->__data.__lock) != 0);
+ while (LLL_MUTEX_TRYLOCK (mutex->__data.__lock, id) != 0);
mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8;
}
@@ -114,5 +130,11 @@
}
out:
+ /* 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;
}
--- robustmutexes/rtnptl/src/nptl/pthread_mutex_trylock.c:1.1.1.1
Thu Oct 9 06:54:44 2003
+++ robustmutexes/rtnptl/src/nptl/pthread_mutex_trylock.c Sat Apr
17 11:54:02 2004
@@ -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,76 @@
#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 &
~NON_MUTEX_KIND_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)
--- robustmutexes/rtnptl/src/nptl/pthread_mutex_unlock.c:1.1.1.1
Thu Oct 9 06:54:44 2003
+++ robustmutexes/rtnptl/src/nptl/pthread_mutex_unlock.c Sat Apr
17 11:54:02 2004
@@ -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 &
~NON_MUTEX_KIND_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;
- return 0;
+ /* Always reset the owner field. */
+ LLL_MUTEX_UNLOCK (mutex->__data.__lock, id);
+
+ return result;
+
+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;
}
--- /dev/null Thu Apr 29 09:10:10 2004
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_getfast_np.c
Tue Mar 30 09:20:22 2004
@@ -0,0 +1,24 @@
+/*
+ * (C) 2004 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <pthreadP.h>
+
+
+int
+pthread_mutexattr_getfast_np (const pthread_mutexattr_t *attr,
+ int *fast_mode)
+{
+ const struct pthread_mutexattr *iattr;
+
+ iattr = (const struct pthread_mutexattr *) attr;
+
+ *fast_mode = iattr->mutexkind & FULOCK_FASTPATH_MODE
+ ? PTHREAD_MUTEX_FASTPATH_NP
+ : PTHREAD_MUTEX_KCO_NP;
+
+ return 0;
+}
--- /dev/null Thu Apr 29 09:10:10 2004
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_getprioceiling.c
Sat Apr 17 02:36:50 2004
@@ -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>
+
+
+int
+pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *__attr,
+ int *__prioceiling)
+{
+ const struct pthread_mutexattr *iattr;
+
+ iattr = (const struct pthread_mutexattr *) __attr;
+
+ /* Use Bit PRIOCEILING_OFFSET - PRIOCEILING_OFFSET + 6 to
+ * indicate the priority ceiling value.
+ * -- MIN_USER_RT_PRIO ~~ MAX_USER_RT_PRIO
+ */
+ *__prioceiling = (iattr->mutexkind & PRIOCEILING_MASK) >>
PRIOCEILING_OFFSET;
+
+ return 0;
+}
--- /dev/null Thu Apr 29 09:10:10 2004
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_getprotocol.c
Tue Mar 30 09:20:22 2004
@@ -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;
+}
--- /dev/null Thu Apr 29 09:10:10 2004
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_getrobust_np.c
Tue Mar 30 09:20:22 2004
@@ -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_getrobust_np (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;
+}
--- /dev/null Thu Apr 29 09:10:10 2004
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_getserial_np.c
Tue Mar 30 09:20:22 2004
@@ -0,0 +1,24 @@
+/*
+ * (C) 2004 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <pthreadP.h>
+
+
+int
+pthread_mutexattr_getserial_np (const pthread_mutexattr_t *attr,
+ int *serial_mode)
+{
+ const struct pthread_mutexattr *iattr;
+
+ iattr = (const struct pthread_mutexattr *) attr;
+
+ *serial_mode = iattr->mutexkind & FULOCK_SERIAL_MODE
+ ? PTHREAD_MUTEX_SERIAL_NP
+ : PTHREAD_MUTEX_UNSERIAL_NP;
+
+ return 0;
+}
--- robustmutexes/rtnptl/src/nptl/pthread_mutexattr_gettype.c:1.1.1.1
Thu Oct 9 06:54:44 2003
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_gettype.c Sat Apr
17 11:54:02 2004
@@ -31,7 +31,7 @@
/* We use bit 31 to single whether the mutex is going to be
process-shared or not. */
- *kind = iattr->mutexkind & ~0x80000000;
+ *kind = iattr->mutexkind & ~NON_MUTEX_KIND_MASK;
return 0;
}
--- robustmutexes/rtnptl/src/nptl/pthread_mutexattr_init.c:1.1.1.1
Thu Oct 9 06:54:44 2003
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_init.c Sat Apr
17 02:36:50 2004
@@ -31,7 +31,8 @@
/* We use bit 31 to single whether the mutex is going to be
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)->mutexkind = PTHREAD_MUTEX_NORMAL
+ | (MIN_USER_RT_PRIO << PRIOCEILING_OFFSET);
return 0;
}
--- /dev/null Thu Apr 29 09:10:10 2004
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_setfast_np.c
Sat Apr 17 11:54:02 2004
@@ -0,0 +1,28 @@
+/*
+ * (C) 2004 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <errno.h>
+#include <pthreadP.h>
+
+
+int pthread_mutexattr_setfast_np (pthread_mutexattr_t *attr,
+ int fast_mode)
+{
+ struct pthread_mutexattr *iattr;
+
+ if (fast_mode != PTHREAD_MUTEX_FASTPATH_NP && fast_mode !=
PTHREAD_MUTEX_KCO_NP)
+ return EINVAL;
+
+ iattr = (struct pthread_mutexattr *) attr;
+
+ if (fast_mode == PTHREAD_MUTEX_FASTPATH_NP)
+ iattr->mutexkind |= FULOCK_FASTPATH_MODE;
+ else
+ iattr->mutexkind &= ~FULOCK_FASTPATH_MODE;
+
+ return 0;
+}
--- /dev/null Thu Apr 29 09:10:10 2004
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_setprioceiling.c
Tue Apr 13 11:37:02 2004
@@ -0,0 +1,30 @@
+/*
+ * (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;
+
+ if (__prioceiling < MIN_USER_RT_PRIO || __prioceiling >
MAX_USER_RT_PRIO)
+ return EINVAL;
+
+ iattr = (const struct pthread_mutexattr *) __attr;
+
+ /* Use Bit PRIOCEILING_OFFSET - PRIOCEILING_OFFSET + 6 to indicate
+ * the priority ceiling value.
+ * -- MIN_USER_RT_PRIO ~~ MAX_USER_RT_PRIO
+ */
+ iattr->mutexkind &= ~PRIOCEILING_MASK;
+ iattr->mutexkind |= (__prioceiling << PRIOCEILING_OFFSET);
+
+ return 0;
+}
--- /dev/null Thu Apr 29 09:10:10 2004
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_setprotocol.c
Sat Apr 17 11:54:02 2004
@@ -0,0 +1,43 @@
+/*
+ * (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 &= ~((FULOCK_FL_PI | FULOCK_FL_PP) >> 1);
+ iattr->mutexkind |= rtflags >> 1;
+ iattr->mutexkind |= protocol == PTHREAD_PRIO_NONE ? 0 :
FULOCK_SERIAL_MODE;
+
+ return 0;
+}
--- /dev/null Thu Apr 29 09:10:10 2004
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_setrobust_np.c
Sat Apr 17 11:54:02 2004
@@ -0,0 +1,45 @@
+/*
+ * (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 (10)
+ */
+
+ if (robustness == PTHREAD_MUTEX_ROBUST_NP)
+ rtflags |= FULOCK_FL_RM;
+ else if (robustness == PTHREAD_MUTEX_ROBUST2_NP)
+ rtflags |= FULOCK_FL_RM_SUN;
+
+ iattr->mutexkind &= ~((FULOCK_FL_RM | FULOCK_FL_RM_SUN) >> 1);
+ iattr->mutexkind |= (rtflags >> 1);
+ iattr->mutexkind |= robustness == PTHREAD_MUTEX_NOROBUST_NP
+ ? 0 : FULOCK_SERIAL_MODE;
+
+ return 0;
+}
--- /dev/null Thu Apr 29 09:10:10 2004
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_setserial_np.c
Tue Mar 30 09:20:22 2004
@@ -0,0 +1,29 @@
+/*
+ * (C) 2004 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <errno.h>
+#include <pthreadP.h>
+
+
+int pthread_mutexattr_setserial_np (pthread_mutexattr_t *attr,
+ int fast_mode)
+{
+ struct pthread_mutexattr *iattr;
+
+ if (fast_mode != PTHREAD_MUTEX_SERIAL_NP
+ && fast_mode != PTHREAD_MUTEX_UNSERIAL_NP)
+ return EINVAL;
+
+ iattr = (struct pthread_mutexattr *) attr;
+
+ if (fast_mode == PTHREAD_MUTEX_SERIAL_NP)
+ iattr->mutexkind |= FULOCK_SERIAL_MODE;
+ else
+ iattr->mutexkind &= ~FULOCK_SERIAL_MODE;
+
+ return 0;
+}
--- robustmutexes/rtnptl/src/nptl/pthread_mutexattr_settype.c:1.1.1.1
Thu Oct 9 06:54:44 2003
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_settype.c Sat Apr
17 11:54:02 2004
@@ -35,7 +35,7 @@
/* We use bit 31 to single whether the mutex is going to be
process-shared or not. */
- iattr->mutexkind = (iattr->mutexkind & 0x80000000) | kind;
+ iattr->mutexkind = (iattr->mutexkind & NON_MUTEX_KIND_MASK) | kind;
return 0;
}
--- /dev/null Thu Apr 29 09:10:10 2004
+++ robustmutexes/rtnptl/src/nptl/tst-fast1.c Thu Apr 29 08:26:18 2004
@@ -0,0 +1,117 @@
+/*
+ * (C) 2004 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static pthread_mutex_t m;
+static pthread_barrier_t b;
+
+
+static void *
+tf (void *arg)
+{
+ if (pthread_mutex_lock (&m) != 0) {
+ puts ("child mutex_lock fail");
+ exit (1);
+ }
+
+ int e = pthread_barrier_wait (&b);
+ if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) {
+ puts ("child barrier_wait fail");
+ exit (1);
+ }
+
+ return NULL;
+}
+
+
+static int
+do_test (void)
+{
+ pthread_mutexattr_t a;
+
+ if (pthread_mutexattr_init (&a) != 0) {
+ puts ("mutexattr_init failed");
+ return 1;
+ }
+
+ if (pthread_mutexattr_setfast_np (&a, PTHREAD_MUTEX_KCO_NP) != 0) {
+ puts ("mutexattr_setfast_np failed");
+ return 1;
+ }
+
+ if (pthread_mutexattr_setrobust_np (&a, PTHREAD_MUTEX_ROBUST_NP) !=
0) {
+ puts ("mutexattr_setrobust_np failed");
+ return 1;
+ }
+
+ if (pthread_mutex_init (&m, &a) != 0) {
+ puts ("mutex_init failed");
+ return 1;
+ }
+
+ if (pthread_barrier_init (&b, NULL, 2) != 0) {
+ puts ("barrier_init failed");
+ return 1;
+ }
+
+ pthread_t th;
+
+ if (pthread_create (&th, NULL, tf, NULL) != 0) {
+ puts ("create failed");
+ return 1;
+ }
+
+ int e = pthread_barrier_wait (&b);
+ if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) {
+ puts ("barrier_wait fail");
+ return 1;
+ }
+
+ if (pthread_mutex_lock (&m) != EOWNERDEAD)
+ {
+ puts ("main mutex_lock failed");
+ return 1;
+ }
+
+ if (pthread_mutex_unlock (&m) != 0)
+ {
+ puts ("main mutex_unlock failed");
+ return 1;
+ }
+
+ if (pthread_join (th, NULL) != 0)
+ {
+ puts ("join failed");
+ return 1;
+ }
+
+ if (pthread_barrier_destroy (&b) != 0)
+ {
+ puts ("barrier_destroy failed");
+ return 1;
+ }
+
+ if (pthread_mutex_destroy (&m) != 0)
+ {
+ puts ("mutex_destroy failed");
+ return 1;
+ }
+
+ if (pthread_mutexattr_destroy (&a) != 0)
+ {
+ puts ("mutexattr_destroy failed");
+ return 1;
+ }
+
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
--- /dev/null Thu Apr 29 09:10:10 2004
+++ robustmutexes/rtnptl/src/nptl/tst-serial1.c Thu Apr 29 08:26:18 2004
@@ -0,0 +1,118 @@
+/*
+ * (C) 2004 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static pthread_mutex_t m;
+static pthread_barrier_t b;
+
+
+static void *
+tf (void *arg)
+{
+ if (pthread_mutex_lock (&m) != 0) {
+ puts ("child mutex_lock fail");
+ exit (1);
+ }
+
+ int e = pthread_barrier_wait (&b);
+ if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) {
+ puts ("child barrier_wait fail");
+ exit (1);
+ }
+
+ return NULL;
+}
+
+
+static int
+do_test (void)
+{
+ pthread_mutexattr_t a;
+
+ if (pthread_mutexattr_init (&a) != 0) {
+ puts ("mutexattr_init failed");
+ return 1;
+ }
+
+ if (pthread_mutexattr_setrobust_np (&a, PTHREAD_MUTEX_ROBUST_NP) !=
0) {
+ puts ("mutexattr_setrobust_np failed");
+ return 1;
+ }
+
+ if (pthread_mutexattr_setserial_np (&a, PTHREAD_MUTEX_UNSERIAL_NP) !=
0) {
+ puts ("mutexattr_setserial_np failed");
+ return 1;
+ }
+
+ if (pthread_mutex_init (&m, &a) != 0) {
+ puts ("mutex_init failed");
+ return 1;
+ }
+
+ if (pthread_barrier_init (&b, NULL, 2) != 0) {
+ puts ("barrier_init failed");
+ return 1;
+ }
+
+ pthread_t th;
+
+ if (pthread_create (&th, NULL, tf, NULL) != 0) {
+ puts ("create failed");
+ return 1;
+ }
+
+ int e = pthread_barrier_wait (&b);
+ if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) {
+ puts ("barrier_wait fail");
+ return 1;
+ }
+
+ if (pthread_mutex_lock (&m) != EOWNERDEAD)
+ {
+ puts ("main mutex_lock failed");
+ return 1;
+ }
+
+ if (pthread_mutex_unlock (&m) != 0)
+ {
+ puts ("main mutex_unlock failed");
+ return 1;
+ }
+
+ if (pthread_join (th, NULL) != 0)
+ {
+ puts ("join failed");
+ return 1;
+ }
+
+ if (pthread_barrier_destroy (&b) != 0)
+ {
+ puts ("barrier_destroy failed");
+ return 1;
+ }
+
+ if (pthread_mutex_destroy (&m) != 0)
+ {
+ puts ("mutex_destroy failed");
+ return 1;
+ }
+
+ if (pthread_mutexattr_destroy (&a) != 0)
+ {
+ puts ("mutexattr_destroy failed");
+ return 1;
+ }
+
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
--- robustmutexes/rtnptl/src/nptl/sysdeps/pthread/pthread.h:1.1.1.1.2.1
Fri Mar 26 02:41:38 2004
+++ robustmutexes/rtnptl/src/nptl/sysdeps/pthread/pthread.h Tue Apr
13 11:37:05 2004
@@ -59,6 +59,54 @@
#endif
};
+/* Robust mutex types. */
+enum
+{
+ PTHREAD_MUTEX_NOROBUST_NP,
+ PTHREAD_MUTEX_ROBUST_NP,
+#define PTHREAD_MUTEX_ROBUST_NP PTHREAD_MUTEX_ROBUST_NP
+ PTHREAD_MUTEX_ROBUST2_NP
+#define PTHREAD_MUTEX_ROBUST2_NP PTHREAD_MUTEX_ROBUST2_NP
+};
+
+/* Mutex Switching Modes. */
+enum
+{
+ PTHREAD_MUTEX_FASTPATH_NP,
+#define PTHREAD_MUTEX_FASTPATH_NP PTHREAD_MUTEX_FASTPATH_NP
+ PTHREAD_MUTEX_KCO_NP,
+#define PTHREAD_MUTEX_KCO_NP PTHREAD_MUTEX_KCO_NP
+ PTHREAD_MUTEX_SERIAL_NP,
+#define PTHREAD_MUTEX_SERIAL_NP PTHREAD_MUTEX_SERIAL_NP
+ PTHREAD_MUTEX_UNSERIAL_NP,
+#define PTHREAD_MUTEX_UNSERIAL_NP PTHREAD_MUTEX_UNSERIAL_NP
+ PTHREAD_MUTEX_SPIN_NP,
+#define PTHREAD_MUTEX_SPIN_NP PTHREAD_MUTEX_SPIN_NP
+ PTHREAD_MUTEX_UNSPIN_NP
+#define PTHREAD_MUTEX_UNSPIN_NP PTHREAD_MUTEX_UNSPIN_NP
+};
+
+/* Robust mutex states. */
+enum
+{
+ PTHREAD_MUTEX_ROBUST_NOP_NP=0,
+ PTHREAD_MUTEX_ROBUST_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 \
{ }
@@ -685,6 +733,90 @@
/* Set the process-shared flag of the mutex attribute ATTR. */
extern int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr,
int __pshared) __THROW;
+
+/* Get the mutex-robust flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getrobust_np (__const pthread_mutexattr_t
*
+ __restrict __attr,
+ int *__restrict __robusttype)
__THROW;
+
+/* Set the mutex-robust flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr,
+ int __robusttype) __THROW;
+
+/* Get the fast-path flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getfast_np (__const pthread_mutexattr_t
*__attr,
+ int *__restrict __fast_mode)
__THROW;
+
+/* Set the fast-path flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setfast_np (pthread_mutexattr_t *
+ __restrict __attr,
+ int __fast_mode) __THROW;
+
+/* Get the serial flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getserial_np (__const pthread_mutexattr_t
*__attr,
+ int *__restrict
+ __serial_mode) __THROW;
+
+/* Set the serial flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setserial_np (pthread_mutexattr_t *
+ __restrict __attr,
+ int __serial_mode) __THROW;
+
+/* Get the spin flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getspin_np (__const pthread_mutexattr_t
*__attr,
+ int *__restrict __spin_mode)
__THROW;
+
+/* Set the spin flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setspin_np (pthread_mutexattr_t *
+ __restrict __attr,
+ int __spin_mode) __THROW;
+
+/* Set the mutex to given state */
+extern int pthread_mutex_setconsistency_np (pthread_mutex_t *
+ __restrict __mutex,
+ int __state) __THROW;
+
+/* Set the mutex to '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,
+ int *__restrict __old_ceiling)
__THROW;
+
+/* Get the serial flag of the mutex. */
+extern int pthread_mutex_getfast_np (__const pthread_mutex_t *
+ __restrict __mutex,
+ int *__restrict __fast_mode)
__THROW;
+
+/* Set the serial flag of the mutex. */
+extern int pthread_mutex_setfast_np (pthread_mutex_t *__restrict
__mutex,
+ int __fast_mode) __THROW;
#ifdef __USE_UNIX98
/* Return in *KIND the mutex kind attribute in *ATTR. */
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}