Fix non-robust mutex ENOTRECOVERABLE false positive
For non-robust mutexes, never check mutex_owner_id_is_live or return ENOTRECOVERABLE when the owner appears dead. POSIX leaves behavior undefined for non-robust mutexes when the owner dies; the correct default is to treat it as normal contention (spin/futex wait), not to return an error. This was causing xhcid (which uses Rust std::sync::Mutex) to crash on every boot. Also add stdint.h to sched.h sys_includes for cpu_set_t uint64_t.
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
# - "[SS|TSP] The <sched.h> header shall define the time_t type as described in <sys/types.h>."
|
# - "[SS|TSP] The <sched.h> header shall define the time_t type as described in <sys/types.h>."
|
||||||
# - "The <sched.h> header shall define the timespec structure as described in <time.h>."
|
# - "The <sched.h> header shall define the timespec structure as described in <time.h>."
|
||||||
# - "Inclusion of the <sched.h> header may make visible all symbols from the <time.h> header."
|
# - "Inclusion of the <sched.h> header may make visible all symbols from the <time.h> header."
|
||||||
sys_includes = ["sys/types.h"]
|
sys_includes = ["sys/types.h", "stdint.h"]
|
||||||
include_guard = "_RELIBC_SCHED_H"
|
include_guard = "_RELIBC_SCHED_H"
|
||||||
after_includes = """
|
after_includes = """
|
||||||
#include <bits/timespec.h> // for timespec
|
#include <bits/timespec.h> // for timespec
|
||||||
|
|||||||
@@ -136,11 +136,7 @@ impl RlctMutex {
|
|||||||
Err(thread) => {
|
Err(thread) => {
|
||||||
let owner = thread & INDEX_MASK;
|
let owner = thread & INDEX_MASK;
|
||||||
|
|
||||||
if !crate::pthread::mutex_owner_id_is_live(owner) {
|
if self.robust && !crate::pthread::mutex_owner_id_is_live(owner) {
|
||||||
if !self.robust {
|
|
||||||
return Err(Errno(ENOTRECOVERABLE));
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_value = (thread & WAITING_BIT) | FUTEX_OWNER_DIED | this_thread;
|
let new_value = (thread & WAITING_BIT) | FUTEX_OWNER_DIED | this_thread;
|
||||||
match self.inner.compare_exchange(
|
match self.inner.compare_exchange(
|
||||||
thread,
|
thread,
|
||||||
@@ -234,15 +230,7 @@ impl RlctMutex {
|
|||||||
return Err(Errno(EDEADLK));
|
return Err(Errno(EDEADLK));
|
||||||
}
|
}
|
||||||
|
|
||||||
if current & FUTEX_OWNER_DIED != 0 && owner == 0 {
|
if self.robust && (current & FUTEX_OWNER_DIED != 0 || (owner != 0 && !crate::pthread::mutex_owner_id_is_live(owner))) {
|
||||||
return Err(Errno(ENOTRECOVERABLE));
|
|
||||||
}
|
|
||||||
|
|
||||||
if current & FUTEX_OWNER_DIED != 0 || (owner != 0 && !crate::pthread::mutex_owner_id_is_live(owner)) {
|
|
||||||
if !self.robust {
|
|
||||||
return Err(Errno(ENOTRECOVERABLE));
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_value = (current & WAITING_BIT) | FUTEX_OWNER_DIED | this_thread;
|
let new_value = (current & WAITING_BIT) | FUTEX_OWNER_DIED | this_thread;
|
||||||
match self.inner.compare_exchange(
|
match self.inner.compare_exchange(
|
||||||
current,
|
current,
|
||||||
|
|||||||
Reference in New Issue
Block a user