Thread implementation
Rationale
Darling uses Apple's original libpthread library. MacOS applications running under Darling therefore use the same exact threading library as on macOS.
Apple's libpthread manages threads through a collection of bsdthread*
system
calls, which are implemented by
Darling.
This way Apple's libpthread could operate absolutely independently on Linux.
However, there is a huge catch. Darling could set up threads on its own and
everything would be working fine, but only unless no calls to native Linux
libraries (e.g. PulseAudio) would be made. The problem would become obvious as
soon as a Linux library makes any thread-related operations on its
own - they would crash immediately. This includes many pthread_*
calls, but
thread-local storage access as well.
Wrapping native libpthread
In Darling, libsystem_kernel uses libelfloader to handle certain bsdthread*
system calls. libelfloader, in turn,
uses
native libpthread to start a thread. Once native libpthread sets up the thread,
the control is handed over to Apple's libpthread.
Apple's libpthread needs control over the stack, so we cannot use the stack provided and managed by native libpthread. Therefore we quickly switch to a different stack once we get control from the native libpthread library.