aboutsummaryrefslogtreecommitdiff
path: root/nptl/pthread_create.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2006-03-28 04:25:17 +0000
committerUlrich Drepper <drepper@redhat.com>2006-03-28 04:25:17 +0000
commit0f6699ea0554a667de301d46fcfe1baf0d53d094 (patch)
treec9360cea0ccc7c79d4235f43a661f51ffda5492f /nptl/pthread_create.c
parent5b20043897accf32d33ae775af7413098cd0cec2 (diff)
downloadglibc-0f6699ea0554a667de301d46fcfe1baf0d53d094.zip
glibc-0f6699ea0554a667de301d46fcfe1baf0d53d094.tar.gz
glibc-0f6699ea0554a667de301d46fcfe1baf0d53d094.tar.bz2
* sysdeps/unix/sysv/linux/kernel-features.h: Add
__ASSUME_SET_ROBUST_LIST.
Diffstat (limited to 'nptl/pthread_create.c')
-rw-r--r--nptl/pthread_create.c46
1 files changed, 29 insertions, 17 deletions
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index f3d90ec..71365a1 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -229,6 +229,19 @@ start_thread (void *arg)
/* Initialize resolver state pointer. */
__resp = &pd->res;
+#ifdef __NR_set_robust_list
+# ifndef __ASSUME_SET_ROBUST_LIST
+ if (__set_robust_list_avail >= 0)
+# endif
+ {
+ INTERNAL_SYSCALL_DECL (err);
+ /* This call should never fail because the initial call in init.c
+ succeeded. */
+ INTERNAL_SYSCALL (set_robust_list, err, 2, &pd->robust_head,
+ sizeof (struct robust_list_head));
+ }
+#endif
+
/* This is where the try/finally block should be created. For
compilers without that support we do use setjmp. */
struct pthread_unwind_buf unwind_buf;
@@ -310,35 +323,34 @@ start_thread (void *arg)
the breakpoint reports TD_THR_RUN state rather than TD_THR_ZOMBIE. */
atomic_bit_set (&pd->cancelhandling, EXITING_BIT);
+#ifndef __ASSUME_SET_ROBUST_LIST
/* If this thread has any robust mutexes locked, handle them now. */
-#if __WORDSIZE == 64
- __pthread_list_t *robust = pd->robust_list.__next;
-#else
+# if __WORDSIZE == 64
+ void *robust = pd->robust_head.list;
+# else
__pthread_slist_t *robust = pd->robust_list.__next;
-#endif
- if (__builtin_expect (robust != &pd->robust_list, 0))
+# endif
+/* We let the kernel do the notification if it is able to do so. */
+ if (__set_robust_list_avail < 0
+ && __builtin_expect (robust != &pd->robust_head, 0))
{
do
{
struct __pthread_mutex_s *this = (struct __pthread_mutex_s *)
- ((char *) robust - offsetof (struct __pthread_mutex_s, __list));
- robust = robust->__next;
+ ((char *) robust - offsetof (struct __pthread_mutex_s,
+ __list.__next));
+ robust = *((void **) robust);
- this->__list.__next = NULL;
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
+# ifdef __PTHREAD_MUTEX_HAVE_PREV
this->__list.__prev = NULL;
-#endif
+# endif
+ this->__list.__next = NULL;
lll_robust_mutex_dead (this->__lock);
}
- while (robust != &pd->robust_list);
-
- /* Clean up so that the thread descriptor can be reused. */
- pd->robust_list.__next = &pd->robust_list;
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
- pd->robust_list.__prev = &pd->robust_list;
-#endif
+ while (robust != &pd->robust_head);
}
+#endif
/* If the thread is detached free the TCB. */
if (IS_DETACHED (pd))