diff --git a/srcpkgs/musl/patches/fix-pi-mutex-cond-1.patch b/srcpkgs/musl/patches/fix-pi-mutex-cond-1.patch new file mode 100644 index 00000000000..39af72b0c5f --- /dev/null +++ b/srcpkgs/musl/patches/fix-pi-mutex-cond-1.patch @@ -0,0 +1,56 @@ +From 2d0bbe6c788938d1332609c014eeebc1dff966ac Mon Sep 17 00:00:00 2001 +From: Rich Felker +Date: Mon, 26 Oct 2020 15:56:25 -0400 +Subject: fix pthread_cond_wait paired with with priority-inheritance mutex + +pthread_cond_wait arranged for requeued waiters to wake when the mutex +is unlocked by temporarily adjusting the mutex's waiter count. commit +54ca677983d47529bab8752315ac1a2b49888870 broke this when introducing +PI mutexes by repurposing the waiter count field of the mutex +structure. since then, for PI mutexes, the waiter count adjustment was +misinterpreted by the mutex locking code as indicating that the mutex +is non a non-recoverable state. + +it would be possible to special-case PI mutexes here, but instead just +drop all adjustment of the waiters count, and instead use the lock +word waiters bit for all mutex types. since the mutex is either held +by the caller or in unrecoverable state at the time the bit is set, it +will necessarily still be set at the time of any subsequent valid +unlock operation, and this will produce the desired effect of waking +the next waiter. + +if waiter counts are entirely dropped at some point in the future this +code should still work without modification. +--- + src/thread/pthread_cond_timedwait.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +(limited to 'src/thread/pthread_cond_timedwait.c') + +diff --git a/src/thread/pthread_cond_timedwait.c b/src/thread/pthread_cond_timedwait.c +index d1501240..f5f37af1 100644 +--- a/src/thread/pthread_cond_timedwait.c ++++ b/src/thread/pthread_cond_timedwait.c +@@ -146,14 +146,13 @@ relock: + + if (oldstate == WAITING) goto done; + +- if (!node.next) a_inc(&m->_m_waiters); +- + /* Unlock the barrier that's holding back the next waiter, and + * either wake it or requeue it to the mutex. */ +- if (node.prev) +- unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & 128); +- else +- a_dec(&m->_m_waiters); ++ if (node.prev) { ++ int val = m->_m_lock; ++ if (val>0) a_cas(&m->_m_lock, val, val|0x80000000); ++ unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & (8|128)); ++ } + + /* Since a signal was consumed, cancellation is not permitted. */ + if (e == ECANCELED) e = 0; +-- +cgit v1.2.1 + diff --git a/srcpkgs/musl/patches/fix-pi-mutex-cond-2.patch b/srcpkgs/musl/patches/fix-pi-mutex-cond-2.patch new file mode 100644 index 00000000000..b356e38b61f --- /dev/null +++ b/srcpkgs/musl/patches/fix-pi-mutex-cond-2.patch @@ -0,0 +1,48 @@ +From 27b2fc9d6db956359727a66c262f1e69995660aa Mon Sep 17 00:00:00 2001 +From: Rich Felker +Date: Fri, 30 Oct 2020 11:21:06 -0400 +Subject: fix missing-wake regression in pthread_cond_wait + +the reasoning in commit 2d0bbe6c788938d1332609c014eeebc1dff966ac was +not entirely correct. while it's true that setting the waiters flag +ensures that the next unlock will perform a wake, it's possible that +the wake is consumed by a mutex waiter that has no relationship with +the condvar wait queue being processed, which then takes the mutex. +when that thread subsequently unlocks, it sees no waiters, and leaves +the rest of the condvar queue stuck. + +bring back the waiter count adjustment, but skip it for PI mutexes, +for which a successful lock-after-waiting always sets the waiters bit. +if future changes are made to bring this same waiters-bit contract to +all lock types, this can be reverted. +--- + src/thread/pthread_cond_timedwait.c | 5 +++++ + 1 file changed, 5 insertions(+) + +(limited to 'src/thread/pthread_cond_timedwait.c') + +diff --git a/src/thread/pthread_cond_timedwait.c b/src/thread/pthread_cond_timedwait.c +index f5f37af1..a0cd4904 100644 +--- a/src/thread/pthread_cond_timedwait.c ++++ b/src/thread/pthread_cond_timedwait.c +@@ -146,12 +146,17 @@ relock: + + if (oldstate == WAITING) goto done; + ++ if (!node.next && !(m->_m_type & 8)) ++ a_inc(&m->_m_waiters); ++ + /* Unlock the barrier that's holding back the next waiter, and + * either wake it or requeue it to the mutex. */ + if (node.prev) { + int val = m->_m_lock; + if (val>0) a_cas(&m->_m_lock, val, val|0x80000000); + unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & (8|128)); ++ } else if (!!(m->_m_type & 8)) { ++ a_dec(&m->_m_waiters); + } + + /* Since a signal was consumed, cancellation is not permitted. */ +-- +cgit v1.2.1 + diff --git a/srcpkgs/musl/patches/fix-pi-mutex-cond-3.patch b/srcpkgs/musl/patches/fix-pi-mutex-cond-3.patch new file mode 100644 index 00000000000..2cc943f26f6 --- /dev/null +++ b/srcpkgs/musl/patches/fix-pi-mutex-cond-3.patch @@ -0,0 +1,28 @@ +From d91a6cf6e369a79587c5665fce9635e5634ca201 Mon Sep 17 00:00:00 2001 +From: Rich Felker +Date: Fri, 30 Oct 2020 16:50:08 -0400 +Subject: fix erroneous pthread_cond_wait mutex waiter count logic due to typo + +introduced in commit 27b2fc9d6db956359727a66c262f1e69995660aa. +--- + src/thread/pthread_cond_timedwait.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +(limited to 'src/thread/pthread_cond_timedwait.c') + +diff --git a/src/thread/pthread_cond_timedwait.c b/src/thread/pthread_cond_timedwait.c +index a0cd4904..6b761455 100644 +--- a/src/thread/pthread_cond_timedwait.c ++++ b/src/thread/pthread_cond_timedwait.c +@@ -155,7 +155,7 @@ relock: + int val = m->_m_lock; + if (val>0) a_cas(&m->_m_lock, val, val|0x80000000); + unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & (8|128)); +- } else if (!!(m->_m_type & 8)) { ++ } else if (!(m->_m_type & 8)) { + a_dec(&m->_m_waiters); + } + +-- +cgit v1.2.1 + diff --git a/srcpkgs/musl/template b/srcpkgs/musl/template index a429ccaf999..d30c99a563a 100644 --- a/srcpkgs/musl/template +++ b/srcpkgs/musl/template @@ -2,7 +2,7 @@ pkgname=musl reverts="1.2.0_1" version=1.1.24 -revision=8 +revision=9 archs="*-musl" bootstrap=yes build_style=gnu-configure