diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index e77e54a5..c8c117b9 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -10,6 +10,7 @@ static void dummy_0() weak_alias(dummy_0, __acquire_ptc); weak_alias(dummy_0, __release_ptc); weak_alias(dummy_0, __pthread_tsd_run_dtors); +weak_alias(dummy_0, __do_private_robust_list); _Noreturn void pthread_exit(void *result) { @@ -63,6 +64,8 @@ _Noreturn void pthread_exit(void *result) a_dec(&libc.bytelocale_cnt_minus_1); } + __do_private_robust_list(); + if (self->detached && self->map_base) { /* Detached threads must avoid the kernel clear_child_tid * feature, since the virtual address will have been diff --git a/src/thread/pthread_mutex_init.c b/src/thread/pthread_mutex_init.c index b83edd0f..acf45a74 100644 --- a/src/thread/pthread_mutex_init.c +++ b/src/thread/pthread_mutex_init.c @@ -4,6 +4,5 @@ int pthread_mutex_init(pthread_mutex_t *restrict m, const pthread_mutexattr_t *r { *m = (pthread_mutex_t){0}; if (a) m->_m_type = a->__attr; - if (m->_m_type & 4) m->_m_type |= 128U; return 0; } diff --git a/src/thread/pthread_mutexattr_setrobust.c b/src/thread/pthread_mutexattr_setrobust.c index dcfa4cf1..8948cbaf 100644 --- a/src/thread/pthread_mutexattr_setrobust.c +++ b/src/thread/pthread_mutexattr_setrobust.c @@ -1,4 +1,26 @@ #include "pthread_impl.h" +#include + +void __do_private_robust_list() +{ + pthread_t self = __pthread_self(); + void **p, **prev, **next; + pthread_mutex_t *m; + + for (prev=0, p=self->robust_list.head; p; p=next) { + next = *p; + m = (void *)((char *)p - offsetof(pthread_mutex_t, _m_next)); + if (!(m->_m_type & 128)) { + int waiters = m->_m_waiters; + if (prev) *prev = next; + else self->robust_list.head = next; + int cont = a_swap(&m->_m_lock, self->tid|0x40000000); + if (cont < 0 || waiters) __wake(&m->_m_lock, 1, 1); + } else { + prev = p; + } + } +} int pthread_mutexattr_setrobust(pthread_mutexattr_t *a, int robust) {