New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use futex-based synchronization on Apple platforms #122408
base: master
Are you sure you want to change the base?
Conversation
|
||
// These syscalls appeared with macOS 10.12. | ||
weak! { | ||
pub fn __ulock_wait(u32, *mut c_void, u64, u32) -> c_int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mind explaining more what the thought process of these going undetected is? Seems like a risky chance that might require a hot fix if the MAS or iOS app store scanners see through this.
In reality I think this won't be enough and we need to call ulock
things via syscall directly instead. This means that the "fallback" Apple futex implementation is only going to be usable on macOS.
I know Electron apps on the MAS use direct syscalls to emulate private functions, so this is probably what Rust should do too on macOS with precedence:
#define SYS_ulock_wait 515
#define SYS_ulock_wake 516
#define SYS_ulock_wait2 544
For iOS, detect if the os_sync_
functions are available or fallback to the non-futex implementation :/ Calling a syscall
directly is forbidden per the iOS headers so std
can't do the same as macOS:
__WATCHOS_PROHIBITED __TVOS_PROHIBITED
__OS_AVAILABILITY_MSG(ios,deprecated=10.0,"syscall(2) is unsupported; "
"please switch to a supported interface. For SYS_kdebug_trace use kdebug_signpost().")
__OS_AVAILABILITY_MSG(macosx,deprecated=10.12,"syscall(2) is unsupported; "
"please switch to a supported interface. For SYS_kdebug_trace use kdebug_signpost().")
int syscall(int, ...);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a "spirit of the law" kind of situation. Apple understandably wants App Store software to continue working in newer versions, so they prohibit private API use, as they want to be able to remove or change that API at will. By only using the private API as fallback and not linking it directly, we fulfil this wish. If we directly linked the private API instead, we'd get dynamic linker errors if they remove it, so we can't do that.
On the other hand, we break the "letter of the law" as we are using private API. In my opinion, this is totally fine and justified, but of course, this is only my interpretation. It would be great if someone from Apple could look over this, just so that we know that they are aware of this. My past attempt at reaching out to them for this has been unsuccessful.
wait(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, addr, value, 0); | ||
} | ||
} else { | ||
panic!("your system is below the minimum supported version of Rust"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These panics also get to be deleted if raw syscalls are used :)
☔ The latest upstream changes (presumably #122423) made this pull request unmergeable. Please resolve the merge conflicts. |
Last week, Apple released macOS version 14.4, which introduced a public futex API called
os_sync_wait_on_address
(Apple has failed to include the documentation provided in the defining headeros/os_sync_wait_on_address.h
on its website). As the private API backing these functions has been around since macOS 10.12, our minimum supported version, it can be used as fallback without risking breakage in future versions.This PR thus switches over
Mutex
toos_unfair_lock
, which is movable and supports priority inheritance, and all other synchronization primitives (Condvar
,RwLock
,Once
and thread parking) to the futex-based ones also used on Linux and Windows.TODO: implement miri shims