mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-02 09:18:31 +00:00
Make more improvements to threads and mappings
- NetBSD should now have faster synchronization - POSIX barriers may now be shared across processes - An edge case with memory map tracking has been fixed - Grand Central Dispatch is no longer used on MacOS ARM64 - POSIX mutexes in normal mode now use futexes across processes
This commit is contained in:
parent
2187d6d2dd
commit
e398f3887c
20 changed files with 566 additions and 171 deletions
7
third_party/nsync/common.c
vendored
7
third_party/nsync/common.c
vendored
|
@ -37,6 +37,7 @@
|
|||
#include "third_party/nsync/atomic.internal.h"
|
||||
#include "third_party/nsync/common.internal.h"
|
||||
#include "third_party/nsync/mu_semaphore.h"
|
||||
#include "third_party/nsync/mu_semaphore.internal.h"
|
||||
#include "third_party/nsync/wait_s.internal.h"
|
||||
__static_yoink("nsync_notice");
|
||||
|
||||
|
@ -147,9 +148,9 @@ static void free_waiters_push (waiter *w) {
|
|||
|
||||
static void free_waiters_populate (void) {
|
||||
int n;
|
||||
if (IsNetbsd () || IsXnuSilicon ()) {
|
||||
// netbsd needs one file descriptor per semaphore (!!)
|
||||
// tim cook wants us to use his grand central dispatch
|
||||
if (IsNetbsd () || (NSYNC_USE_GRAND_CENTRAL && IsXnuSilicon ())) {
|
||||
// netbsd needs a real file descriptor per semaphore
|
||||
// tim cook wants us to use his lol central dispatch
|
||||
n = 1;
|
||||
} else {
|
||||
n = getpagesize() / sizeof(waiter);
|
||||
|
|
5
third_party/nsync/futex.c
vendored
5
third_party/nsync/futex.c
vendored
|
@ -52,6 +52,7 @@
|
|||
#include "third_party/nsync/atomic.h"
|
||||
#include "third_party/nsync/common.internal.h"
|
||||
#include "third_party/nsync/futex.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "third_party/nsync/time.h"
|
||||
|
||||
#define FUTEX_WAIT_BITS_ FUTEX_BITSET_MATCH_ANY
|
||||
|
@ -138,7 +139,7 @@ static int nsync_futex_polyfill_ (atomic_int *w, int expect, struct timespec *ab
|
|||
}
|
||||
if (_weaken (pthread_testcancel_np) &&
|
||||
_weaken (pthread_testcancel_np) ()) {
|
||||
return -ETIMEDOUT;
|
||||
return -ECANCELED;
|
||||
}
|
||||
if (abstime && timespec_cmp (timespec_real (), *abstime) >= 0) {
|
||||
return -ETIMEDOUT;
|
||||
|
@ -163,7 +164,7 @@ static int nsync_futex_wait_win32_ (atomic_int *w, int expect, char pshare,
|
|||
|
||||
for (;;) {
|
||||
now = timespec_real ();
|
||||
if (timespec_cmp (now, deadline) > 0) {
|
||||
if (timespec_cmp (now, deadline) >= 0) {
|
||||
return etimedout();
|
||||
}
|
||||
wait = timespec_sub (deadline, now);
|
||||
|
|
13
third_party/nsync/mu_semaphore.c
vendored
13
third_party/nsync/mu_semaphore.c
vendored
|
@ -21,14 +21,9 @@
|
|||
#include "third_party/nsync/mu_semaphore.internal.h"
|
||||
__static_yoink("nsync_notice");
|
||||
|
||||
/* Apple's ulock (part by Cosmo futexes) is an internal API, but:
|
||||
1. Unlike GCD it's cancellable, i.e. can be EINTR'd by signals
|
||||
2. We currently always use ulock anyway for joining threads */
|
||||
#define PREFER_GCD_OVER_ULOCK 1
|
||||
|
||||
/* Initialize *s; the initial value is 0. */
|
||||
bool nsync_mu_semaphore_init (nsync_semaphore *s) {
|
||||
if (PREFER_GCD_OVER_ULOCK && IsXnuSilicon ()) {
|
||||
if (NSYNC_USE_GRAND_CENTRAL && IsXnuSilicon ()) {
|
||||
return nsync_mu_semaphore_init_gcd (s);
|
||||
} else if (IsNetbsd ()) {
|
||||
return nsync_mu_semaphore_init_sem (s);
|
||||
|
@ -44,7 +39,7 @@ bool nsync_mu_semaphore_init (nsync_semaphore *s) {
|
|||
errno_t nsync_mu_semaphore_p (nsync_semaphore *s) {
|
||||
errno_t err;
|
||||
BEGIN_CANCELATION_POINT;
|
||||
if (PREFER_GCD_OVER_ULOCK && IsXnuSilicon ()) {
|
||||
if (NSYNC_USE_GRAND_CENTRAL && IsXnuSilicon ()) {
|
||||
err = nsync_mu_semaphore_p_gcd (s);
|
||||
} else if (IsNetbsd ()) {
|
||||
err = nsync_mu_semaphore_p_sem (s);
|
||||
|
@ -62,7 +57,7 @@ errno_t nsync_mu_semaphore_p (nsync_semaphore *s) {
|
|||
errno_t nsync_mu_semaphore_p_with_deadline (nsync_semaphore *s, nsync_time abs_deadline) {
|
||||
errno_t err;
|
||||
BEGIN_CANCELATION_POINT;
|
||||
if (PREFER_GCD_OVER_ULOCK && IsXnuSilicon ()) {
|
||||
if (NSYNC_USE_GRAND_CENTRAL && IsXnuSilicon ()) {
|
||||
err = nsync_mu_semaphore_p_with_deadline_gcd (s, abs_deadline);
|
||||
} else if (IsNetbsd ()) {
|
||||
err = nsync_mu_semaphore_p_with_deadline_sem (s, abs_deadline);
|
||||
|
@ -75,7 +70,7 @@ errno_t nsync_mu_semaphore_p_with_deadline (nsync_semaphore *s, nsync_time abs_d
|
|||
|
||||
/* Ensure that the count of *s is at least 1. */
|
||||
void nsync_mu_semaphore_v (nsync_semaphore *s) {
|
||||
if (PREFER_GCD_OVER_ULOCK && IsXnuSilicon ()) {
|
||||
if (NSYNC_USE_GRAND_CENTRAL && IsXnuSilicon ()) {
|
||||
return nsync_mu_semaphore_v_gcd (s);
|
||||
} else if (IsNetbsd ()) {
|
||||
return nsync_mu_semaphore_v_sem (s);
|
||||
|
|
14
third_party/nsync/mu_semaphore.internal.h
vendored
14
third_party/nsync/mu_semaphore.internal.h
vendored
|
@ -4,6 +4,20 @@
|
|||
#include "third_party/nsync/time.h"
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
/* XNU ulock (used by cosmo futexes) is an internal API, however:
|
||||
|
||||
1. Unlike GCD it's cancelable i.e. can be EINTR'd by signals
|
||||
2. We have no choice but to use ulock for joining threads
|
||||
3. Grand Central Dispatch requires a busy loop workaround
|
||||
4. ulock makes our mutexes use 20% more system time (meh)
|
||||
5. ulock makes our mutexes use 40% less wall time (good)
|
||||
6. ulock makes our mutexes use 64% less user time (woop)
|
||||
|
||||
ulock is an outstanding system call that must be used.
|
||||
gcd is not an acceptable alternative to ulock. */
|
||||
|
||||
#define NSYNC_USE_GRAND_CENTRAL 0
|
||||
|
||||
bool nsync_mu_semaphore_init_futex(nsync_semaphore *);
|
||||
errno_t nsync_mu_semaphore_p_futex(nsync_semaphore *);
|
||||
errno_t nsync_mu_semaphore_p_with_deadline_futex(nsync_semaphore *, nsync_time);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue