[RFC/PATCH] RT-NPTL-2.3 4/7
Hu, Boris
boris.hu@intel.com
Sat Jul 24 06:47:00 GMT 2004
pthread_mutexattr_setunlock_np.c | 35 ++++
sysdeps/pthread/pthread.h | 148 ++++++++++++++++++++
sysdeps/unix/sysv/linux/Makefile | 3
sysdeps/unix/sysv/linux/internaltypes.h | 23 +++
sysdeps/unix/sysv/linux/lowlevelrtlock.c | 227
+++++++++++++++++++++++++++++++
tst-fast1.c | 117 +++++++++++++++
tst-options1.c | 46 ++++++
tst-serial1.c | 119 ++++++++++++++++
8 files changed, 716 insertions(+), 2 deletions(-)
--- /dev/null Fri Jul 23 03:18:16 2004
+++ robustmutexes/rtnptl/src/nptl/pthread_mutexattr_setunlock_np.c
Tue May 25 05:16:58 2004
@@ -0,0 +1,35 @@
+/*
+ * (C) 2004 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+
+
+#include <errno.h>
+#include <pthreadP.h>
+
+
+int pthread_mutexattr_setunlock_np (pthread_mutexattr_t *attr,
+ int fast_mode)
+{
+ struct pthread_mutexattr *iattr;
+
+ iattr = (struct pthread_mutexattr *) attr;
+
+ iattr->mutexkind &= ~FULOCK_UNLOCK_TYPE_MASK;
+ switch (fast_mode) {
+ case PTHREAD_MUTEX_UNLOCK_SERIAL_NP:
+ iattr->mutexkind |= (FULOCK_UNLOCK_SERIAL <<
FULOCK_UNLOCK_TYPE_OFFSET);
+ break;
+ case PTHREAD_MUTEX_UNLOCK_PARALLEL_NP:
+ iattr->mutexkind |= (FULOCK_UNLOCK_PARALLEL <<
FULOCK_UNLOCK_TYPE_OFFSET);
+ break;
+ case PTHREAD_MUTEX_UNLOCK_AUTO_NP:
+ iattr->mutexkind |= (FULOCK_UNLOCK_AUTO <<
FULOCK_UNLOCK_TYPE_OFFSET);
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+}
--- /dev/null Fri Jul 23 03:18:16 2004
+++ robustmutexes/rtnptl/src/nptl/tst-fast1.c Tue May 11 12:01:35 2004
@@ -0,0 +1,117 @@
+/*
+ * (C) 2004 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static pthread_mutex_t m;
+static pthread_barrier_t b;
+
+
+static void *
+tf (void *arg)
+{
+ if (pthread_mutex_lock (&m) != 0) {
+ puts ("child mutex_lock fail");
+ exit (1);
+ }
+
+ int e = pthread_barrier_wait (&b);
+ if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) {
+ puts ("child barrier_wait fail");
+ exit (1);
+ }
+
+ return NULL;
+}
+
+
+static int
+do_test (void)
+{
+ pthread_mutexattr_t a;
+
+ if (pthread_mutexattr_init (&a) != 0) {
+ puts ("mutexattr_init failed");
+ return 1;
+ }
+
+ if (pthread_mutexattr_setfast_np (&a, PTHREAD_MUTEX_SLOWPATH_NP) !=
0) {
+ puts ("mutexattr_setfast_np failed");
+ return 1;
+ }
+
+ if (pthread_mutexattr_setrobust_np (&a, PTHREAD_MUTEX_ROBUST_NP) !=
0) {
+ puts ("mutexattr_setrobust_np failed");
+ return 1;
+ }
+
+ if (pthread_mutex_init (&m, &a) != 0) {
+ puts ("mutex_init failed");
+ return 1;
+ }
+
+ if (pthread_barrier_init (&b, NULL, 2) != 0) {
+ puts ("barrier_init failed");
+ return 1;
+ }
+
+ pthread_t th;
+
+ if (pthread_create (&th, NULL, tf, NULL) != 0) {
+ puts ("create failed");
+ return 1;
+ }
+
+ int e = pthread_barrier_wait (&b);
+ if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) {
+ puts ("barrier_wait fail");
+ return 1;
+ }
+
+ if (pthread_mutex_lock (&m) != EOWNERDEAD)
+ {
+ puts ("main mutex_lock failed");
+ return 1;
+ }
+
+ if (pthread_mutex_unlock (&m) != 0)
+ {
+ puts ("main mutex_unlock failed");
+ return 1;
+ }
+
+ if (pthread_join (th, NULL) != 0)
+ {
+ puts ("join failed");
+ return 1;
+ }
+
+ if (pthread_barrier_destroy (&b) != 0)
+ {
+ puts ("barrier_destroy failed");
+ return 1;
+ }
+
+ if (pthread_mutex_destroy (&m) != 0)
+ {
+ puts ("mutex_destroy failed");
+ return 1;
+ }
+
+ if (pthread_mutexattr_destroy (&a) != 0)
+ {
+ puts ("mutexattr_destroy failed");
+ return 1;
+ }
+
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
--- /dev/null Fri Jul 23 03:18:17 2004
+++ robustmutexes/rtnptl/src/nptl/tst-options1.c Sat May 15
06:24:14 2004
@@ -0,0 +1,46 @@
+/*
+ * (C) 2004 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int
+do_test (void)
+{
+ int ret;
+
+ ret = sysconf (_SC_THREAD_ROBUST_MUTEX_NP);
+ if (-1 == ret) {
+ puts ("Robust Mutexes Feature doesn't support!");
+ exit (1);
+ }
+ else
+ puts ("Robust Mutexes Feature supports!");
+
+ ret = sysconf (_SC_THREAD_MUTEX_SERIAL_NP);
+ if (-1 == ret) {
+ puts ("Mutex Serial/Unserial Switching Extention doesn't
support!");
+ exit (1);
+ }
+ else
+ puts ("Mutex Serial/Unserial Switching Extention supports!");
+
+ ret = sysconf (_SC_THREAD_MUTEX_FAST_NP);
+ if (-1 == ret) {
+ puts ("Mutex Fastpath/Slowpath Switching Extention doesn't
support!");
+ exit (1);
+ }
+ else
+ puts ("Mutex Fastpath/Slowpath Switching Extention supports!");
+
+ return 0;
+
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
--- /dev/null Fri Jul 23 03:18:17 2004
+++ robustmutexes/rtnptl/src/nptl/tst-serial1.c Thu May 27 01:39:57 2004
@@ -0,0 +1,119 @@
+/*
+ * (C) 2004 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static pthread_mutex_t m;
+static pthread_barrier_t b;
+
+
+static void *
+tf (void *arg)
+{
+ if (pthread_mutex_lock (&m) != 0) {
+ puts ("child mutex_lock fail");
+ exit (1);
+ }
+
+ int e = pthread_barrier_wait (&b);
+ if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) {
+ puts ("child barrier_wait fail");
+ exit (1);
+ }
+
+ return NULL;
+}
+
+
+static int
+do_test (void)
+{
+ pthread_mutexattr_t a;
+
+ if (pthread_mutexattr_init (&a) != 0) {
+ puts ("mutexattr_init failed");
+ return 1;
+ }
+
+ if (pthread_mutexattr_setrobust_np (&a, PTHREAD_MUTEX_ROBUST_NP) !=
0) {
+ puts ("mutexattr_setrobust_np failed");
+ return 1;
+ }
+
+ if (pthread_mutexattr_setunlock_np (
+ &a,PTHREAD_MUTEX_UNLOCK_PARALLEL_NP) != 0) {
+ puts ("mutexattr_setserial_np failed");
+ return 1;
+ }
+
+ if (pthread_mutex_init (&m, &a) != 0) {
+ puts ("mutex_init failed");
+ return 1;
+ }
+
+ if (pthread_barrier_init (&b, NULL, 2) != 0) {
+ puts ("barrier_init failed");
+ return 1;
+ }
+
+ pthread_t th;
+
+ if (pthread_create (&th, NULL, tf, NULL) != 0) {
+ puts ("create failed");
+ return 1;
+ }
+
+ int e = pthread_barrier_wait (&b);
+ if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) {
+ puts ("barrier_wait fail");
+ return 1;
+ }
+
+ if (pthread_mutex_lock (&m) != EOWNERDEAD)
+ {
+ puts ("main mutex_lock failed");
+ return 1;
+ }
+
+ if (pthread_mutex_unlock (&m) != 0)
+ {
+ puts ("main mutex_unlock failed");
+ return 1;
+ }
+
+ if (pthread_join (th, NULL) != 0)
+ {
+ puts ("join failed");
+ return 1;
+ }
+
+ if (pthread_barrier_destroy (&b) != 0)
+ {
+ puts ("barrier_destroy failed");
+ return 1;
+ }
+
+ if (pthread_mutex_destroy (&m) != 0)
+ {
+ puts ("mutex_destroy failed");
+ return 1;
+ }
+
+ if (pthread_mutexattr_destroy (&a) != 0)
+ {
+ puts ("mutexattr_destroy failed");
+ return 1;
+ }
+
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
--- robustmutexes/rtnptl/src/nptl/sysdeps/pthread/pthread.h:1.1.1.1.2.1
Fri Mar 26 02:41:38 2004
+++ robustmutexes/rtnptl/src/nptl/sysdeps/pthread/pthread.h Mon Jun
7 05:21:35 2004
@@ -59,6 +59,56 @@
#endif
};
+/* Robust mutex types. */
+enum
+{
+ PTHREAD_MUTEX_NOROBUST_NP,
+ PTHREAD_MUTEX_ROBUST_NP,
+#define PTHREAD_MUTEX_ROBUST_NP PTHREAD_MUTEX_ROBUST_NP
+ PTHREAD_MUTEX_ROBUST2_NP
+#define PTHREAD_MUTEX_ROBUST2_NP PTHREAD_MUTEX_ROBUST2_NP
+};
+
+/* Mutex Switching Modes. */
+enum
+{
+ PTHREAD_MUTEX_FASTPATH_NP,
+#define PTHREAD_MUTEX_FASTPATH_NP PTHREAD_MUTEX_FASTPATH_NP
+ PTHREAD_MUTEX_SLOWPATH_NP,
+#define PTHREAD_MUTEX_SLOWPATH_NP PTHREAD_MUTEX_SLOWPATH_NP
+ PTHREAD_MUTEX_UNLOCK_SERIAL_NP,
+#define PTHREAD_MUTEX_UNLOCK_SERIAL_NP PTHREAD_MUTEX_UNLOCK_SERIAL_NP
+ PTHREAD_MUTEX_UNLOCK_PARALLEL_NP,
+#define PTHREAD_MUTEX_UNLOCK_PARALLEL_NP
PTHREAD_MUTEX_UNLOCK_PARALLEL_NP
+ PTHREAD_MUTEX_UNLOCK_AUTO_NP,
+#define PTHREAD_MUTEX_UNLOCK_AUTO_NP PTHREAD_MUTEX_UNLOCK_AUTO_NP
+ PTHREAD_MUTEX_SPIN_NP,
+#define PTHREAD_MUTEX_SPIN_NP PTHREAD_MUTEX_SPIN_NP
+ PTHREAD_MUTEX_UNSPIN_NP
+#define PTHREAD_MUTEX_UNSPIN_NP PTHREAD_MUTEX_UNSPIN_NP
+};
+
+/* Robust mutex states. */
+enum
+{
+ PTHREAD_MUTEX_ROBUST_NOP_NP=0,
+ PTHREAD_MUTEX_ROBUST_CONSISTENT_NP,
+ PTHREAD_MUTEX_ROBUST_NOTRECOVERABLE_NP,
+ PTHREAD_MUTEX_ROBUST_RELEASE_NP,
+ PTHREAD_MUTEX_ROBUST_INIT_NP = PTHREAD_MUTEX_ROBUST_RELEASE_NP
+};
+
+/* Mutex protocols. */
+enum
+{
+ PTHREAD_PRIO_NONE=1,
+ PTHREAD_PRIO_INHERIT,
+#define PTHREAD_PRIO_INHERIT PTHREAD_PRIO_INHERIT
+ PTHREAD_PRIO_PROTECT
+#define PTHREAD_PRIO_PROTECT PTHREAD_PRIO_PROTECT
+};
+
+
/* Mutex initializers. */
#define PTHREAD_MUTEX_INITIALIZER \
{ }
@@ -685,6 +735,104 @@
/* Set the process-shared flag of the mutex attribute ATTR. */
extern int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr,
int __pshared) __THROW;
+
+/* Get the mutex-robust flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getrobust_np (__const pthread_mutexattr_t
*
+ __restrict __attr,
+ int *__restrict __robusttype)
__THROW;
+
+/* Set the mutex-robust flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr,
+ int __robusttype) __THROW;
+
+/* Get the fast-path flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getfast_np (__const pthread_mutexattr_t
*__attr,
+ int *__restrict __fast_mode)
__THROW;
+
+/* Set the fast-path flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setfast_np (pthread_mutexattr_t *
+ __restrict __attr,
+ int __fast_mode) __THROW;
+
+/* Get the serial flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getunlock_np (__const pthread_mutexattr_t
*__attr,
+ int *__restrict
+ __serial_mode) __THROW;
+
+/* Set the serial flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setunlock_np (pthread_mutexattr_t *
+ __restrict __attr,
+ int __serial_mode) __THROW;
+
+/* Get the spin flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getspin_np (__const pthread_mutexattr_t
*__attr,
+ int *__restrict __spin_mode)
__THROW;
+
+/* Set the spin flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setspin_np (pthread_mutexattr_t *
+ __restrict __attr,
+ int __spin_mode) __THROW;
+
+/* Set the mutex to given state */
+extern int pthread_mutex_setconsistency_np (pthread_mutex_t *
+ __restrict __mutex,
+ int __state) __THROW;
+
+/* Set the mutex to consistent state */
+extern int pthread_mutex_consistent_np (pthread_mutex_t *
+ __restrict __mutex) __THROW;
+
+/* Get the mutex state */
+extern int pthread_mutex_getconsistency_np (pthread_mutex_t *
+ __restrict __mutex,
+ int *__restrict __state)
__THROW;
+/* Access fusyn layer interface */
+extern int pthread_mutex_ctl_np (pthread_mutex_t *
+ __restrict __mutex,
+ int __ctl) __THROW;
+
+/* Get the procotol of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getprotocol (__const pthread_mutexattr_t *
+ __restrict __attr,
+ int *__restrict __protocol)
__THROW;
+
+/* Set the procotol of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setprotocol (pthread_mutexattr_t *__attr,
+ int __protocol) __THROW;
+
+/* Get the priority ceiling value of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getprioceiling (__const
pthread_mutexattr_t *
+ __restrict __attr,
+ int *__restrict
__prioceiling) __THROW;
+
+/* Set the priority ceiling value of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setprioceiling (pthread_mutexattr_t
*__restrict __attr,
+ int __prioceiling)
__THROW;
+
+/* Get the priority ceiling value of the mutex. */
+extern int pthread_mutex_getprioceiling (__const pthread_mutex_t *
+ __restrict __mutex,
+ int *__restrict __prioceiling)
__THROW;
+
+/* Set the priority ceiling value of the mutex. */
+extern int pthread_mutex_setprioceiling (pthread_mutex_t *__restrict
__mutex,
+ int __prioceiling,
+ int *__restrict __old_ceiling)
__THROW;
+
+/* Get the serial flag of the mutex. */
+extern int pthread_mutex_getunlock_np (__const pthread_mutex_t *
+ __restrict __mutex,
+ int *__restrict __serial_mode)
__THROW;
+
+/* Set the serial flag of the mutex. */
+extern int pthread_mutex_setunlock_np (pthread_mutex_t *__restrict
__mutex,
+ int __serial_mode) __THROW;
+
+extern int pthread_mutex_whose_owner_dead_np (pthread_mutex_t
+ *__restrict __mutex,
+ const struct timespec
+ *__restrict __reltime)
__THROW;
+
#ifdef __USE_UNIX98
/* Return in *KIND the mutex kind attribute in *ATTR. */
---
robustmutexes/rtnptl/src/nptl/sysdeps/unix/sysv/linux/Makefile:1.1.1.1.2
.1 Tue Jan 6 06:34:06 2004
+++ robustmutexes/rtnptl/src/nptl/sysdeps/unix/sysv/linux/Makefile
Wed Jul 14 08:49:27 2004
@@ -21,7 +21,8 @@
sysdep_routines += register-atfork unregister-atfork libc_pthread_init
\
libc_multiple_threads
-libpthread-sysdep_routines += pt-fork pthread_mutex_cond_lock
+libpthread-sysdep_routines += pt-fork pthread_mutex_cond_lock \
+ pthread_mutex_rq_lock
gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \
lowlevelbarrier.sym unwindbuf.sym
---
robustmutexes/rtnptl/src/nptl/sysdeps/unix/sysv/linux/internaltypes.h:1.
1.1.1.2.3 Fri Mar 26 02:41:40 2004
+++
robustmutexes/rtnptl/src/nptl/sysdeps/unix/sysv/linux/internaltypes.h
Fri Jun 11 08:40:58 2004
@@ -48,7 +48,21 @@
#define ATTR_FLAG_SCHED_SET 0x0020
#define ATTR_FLAG_POLICY_SET 0x0040
+/* Priority Protection Ceiling Mask. */
+#define PRIOCEILING_MASK 0x0007f800
+#define PRIOCEILING_OFFSET 11
+#define MIN_USER_RT_PRIO 1
+#define MAX_USER_RT_PRIO 100
+/* Bit set if fast-path mode. */
+#define FULOCK_FASTPATH_MODE 0x04000000
+/* Bit set if serial mode. */
+#define FULOCK_UNLOCK_TYPE_MASK 0x03000000
+#define FULOCK_UNLOCK_TYPE_OFFSET 24
+
+#define NON_MUTEX_KIND_MASK (0xf80000 |
FULOCK_FASTPATH_MODE \
+ | FULOCK_UNLOCK_TYPE_MASK
\
+ | PRIOCEILING_MASK)
/* Mutex attribute data structure. */
struct pthread_mutexattr
{
@@ -56,7 +70,14 @@
Bit 31 is set if the mutex is to be shared between processes.
- Bit 0 to 30 contain one of the PTHREAD_MUTEX_ values to identify
+ Flags for realtime mutex extension.
+ Bit 30 and 29 for mutex protocol attributes.
+ Bit 28 and 27 for mutex robustness attributes.
+ Bit 26 for fulock fast-path and KCO mode switching flag.
+ Bit 25 and 24 for fulock serialization switching flag.
+ Bit 11-19 to record priority ceiling value.
+
+ Bits left contain one of the PTHREAD_MUTEX_ values to identify
the type of the mutex. */
int mutexkind;
};
--- /dev/null Fri Jul 23 03:18:17 2004
+++
robustmutexes/rtnptl/src/nptl/sysdeps/unix/sysv/linux/lowlevelrtlock.c
Wed Jun 9 12:38:03 2004
@@ -0,0 +1,227 @@
+/*
+ * (C) 2003 Intel Corporation
+ * Boris Hu <boris.hu@intel.com>
+ *
+ * Distributed under the FSF's LGPL license, v2 or later. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <pthread.h>
+#include <pthreadP.h>
+#include <lowlevellock.h>
+#include <sys/time.h>
+#include <atomic.h>
+
+#include <linux/fulock.h>
+
+inline int
+__attribute__ ((always_inline))
+is_mutex_robust (const pthread_mutex_t *mutex)
+{
+ return (mutex->__data.__kind & ((FULOCK_FL_RM | FULOCK_FL_RM_SUN) >>
1));
+}
+
+
+inline int
+__attribute__ ((always_inline))
+is_mutexattr_robust (const struct pthread_mutexattr *attr)
+{
+ return (attr->mutexkind & ((FULOCK_FL_RM | FULOCK_FL_RM_SUN) >> 1));
+}
+
+
+inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_trylock (volatile int *vfulock, unsigned flags,
+ unsigned rtflags, unsigned tid)
+{
+ unsigned old_value;
+ int result;
+ INTERNAL_SYSCALL_DECL (err);
+
+restart:
+ if (flags & FULOCK_FL_KCO)
+ goto kco_mode;
+
+ result = EBUSY;
+ old_value = atomic_compare_and_exchange_val_acq (vfulock, tid,
VFULOCK_UNLOCKED);
+ if (old_value == VFULOCK_UNLOCKED) /* If it was unlocked, fulock
acquired */
+ result = 0;
+ else if (old_value == VFULOCK_NR)
+ result = ENOTRECOVERABLE;
+ else if ((old_value == VFULOCK_WP))
+ result = EBUSY;
+ else if (flags & FULOCK_FL_RM)
+ {
+ kco_mode:
+ result = INTERNAL_SYSCALL (ufulock_lock, err, 3, vfulock, flags,
0);
+ if (INTERNAL_SYSCALL_ERROR_P (result, err))
+ result = INTERNAL_SYSCALL_ERRNO (result, err);
+
+ switch (result)
+ {
+ case 0:
+ case EBUSY:
+ case ETIMEDOUT:
+ case EOWNERDEAD:
+ case ENOTRECOVERABLE:
+ return result;
+ default:
+ goto restart;
+ }
+ }
+ return result; /* Taken (waiters in kernel)! */
+}
+
+
+inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_timedlock (volatile int *vfulock, unsigned flags,
+ unsigned rtflags, unsigned pid,
+ const struct timeout *timeout)
+{
+ int result;
+ INTERNAL_SYSCALL_DECL (err);
+
+restart:
+ if (!(flags & FULOCK_FL_KCO)
+ && ! atomic_compare_and_exchange_bool_acq (vfulock, pid,
VFULOCK_UNLOCKED))
+ return 0;
+
+ //FIXME: should we respin it again? for pthread_mutex_lock has done
it.
+ // int cnt = 0;
+ // int max_cnt = MIN (MAX_ADAPTIVE_COUNT,
+ // mutex->__data.__spins * 2 + 10);
+ //if (cnt++ < max_cnt)
+ // goto restart;
+
+ result = INTERNAL_SYSCALL (ufulock_lock, err, 3, vfulock, flags,
timeout);
+
+ result = INTERNAL_SYSCALL_ERROR_P (result, err)
+ ? INTERNAL_SYSCALL_ERRNO (result, err) : result;
+
+ // mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8;
+
+ switch (result)
+ {
+ case 0:
+ case EBUSY:
+ case ETIMEDOUT:
+ case EOWNERDEAD:
+ case ENOTRECOVERABLE:
+ return result;
+ default:
+ goto restart;
+ }
+ return 0; /* Lock acquired. */
+}
+
+
+inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_lock (volatile int *vfulock, unsigned flags,
+ unsigned rtflags, unsigned tid)
+{
+ return __lll_rtmutex_timedlock (vfulock, flags, rtflags,
+ tid, (const void *) ~0);
+}
+
+
+inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_unlock (volatile int *vfulock, unsigned flags,
+ unsigned rtflags, unsigned tid)
+{
+ int result = EPERM;
+ unsigned old_value;
+ INTERNAL_SYSCALL_DECL (err);
+
+ if (flags & FULOCK_FL_KCO)
+ goto kco_mode;
+ while (1)
+ {
+ old_value = *vfulock;
+ if (old_value == VFULOCK_NR)
+ {
+ result = ENOTRECOVERABLE;
+ break;
+ }
+ else if (old_value >= VFULOCK_WP)
+ {
+ kco_mode:
+ result = INTERNAL_SYSCALL (ufulock_unlock, err, 3, vfulock,
flags,
+ (rtflags & FULOCK_UNLOCK_TYPE_MASK)
+ >> FULOCK_UNLOCK_TYPE_OFFSET);
+ if (INTERNAL_SYSCALL_ERROR_P (result, err)) {
+ result = INTERNAL_SYSCALL_ERRNO (result, err);
+ break;
+ }
+ break;
+ }
+ else if (! atomic_compare_and_exchange_bool_acq (vfulock,
VFULOCK_UNLOCKED,
+ old_value)) {
+ result = 0;
+ break;
+ }
+ }
+ return result;
+}
+
+
+inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_unlock_nocheck (volatile int *vfulock, unsigned flags,
+ unsigned rtflags)
+{
+ int result;
+ INTERNAL_SYSCALL_DECL (err);
+
+ result = INTERNAL_SYSCALL (ufulock_unlock, err, 3, vfulock, flags,
0);
+ return INTERNAL_SYSCALL_ERROR_P (result, err)
+ ? INTERNAL_SYSCALL_ERRNO (result, err)
+ : result;
+}
+
+
+inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_set_consistency (volatile int *vfulock,
+ unsigned flags, unsigned rtflags,
+ enum fulock_ctl consistency)
+{
+ int result;
+ INTERNAL_SYSCALL_DECL (err);
+
+ result = INTERNAL_SYSCALL (ufulock_ctl, err, 3, vfulock,
+ flags, consistency);
+ return INTERNAL_SYSCALL_ERROR_P (result, err)
+ ? INTERNAL_SYSCALL_ERRNO (result, err)
+ : result;
+}
+
+
+inline int
+__attribute__ ((always_inline))
+__lll_rtmutex_get_consistency (volatile int *vfulock, unsigned flags,
+ unsigned rtflags, int *state)
+{
+ int result;
+ INTERNAL_SYSCALL_DECL (err);
+
+ result = INTERNAL_SYSCALL (ufulock_ctl, err, 3, vfulock, flags, 0);
+ if (! INTERNAL_SYSCALL_ERROR_P (result, err))
+ *state = result;
+ return 0;
+}
+
+
+int
+__lll_rtmutex_ctl (volatile int *vfulock, unsigned flags, int ctl)
+{
+ int result;
+ INTERNAL_SYSCALL_DECL (err);
+
+ result = INLINE_SYSCALL (ufulock_ctl, 3, vfulock, flags, ctl);
+ return result;
+}s
Boris Hu (Hu Jiangtao)
Intel China Software Center
86-021-5257-4545#1277
iNET: 8-752-1277
************************************
There are my thoughts, not my employer's.
************************************
"gpg --recv-keys --keyserver wwwkeys.pgp.net 0FD7685F"
{0FD7685F:CFD6 6F5C A2CB 7881 725B CEA0 956F 9F14 0FD7 685F}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rtnptl-2.3.patch-3
Type: application/octet-stream
Size: 22186 bytes
Desc: rtnptl-2.3.patch-3
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20040724/cf8ebbc7/attachment.obj>
More information about the Libc-alpha
mailing list