Overhaul process spawning

This commit is contained in:
Justine Tunney 2023-09-10 08:12:43 -07:00
parent 99dc1281f5
commit 26e254fb4d
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
96 changed files with 1848 additions and 1541 deletions

View file

@ -20,7 +20,6 @@
#include "libc/atomic.h"
#include "libc/calls/blocksigs.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/sigaltstack.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
@ -29,7 +28,7 @@
#include "libc/intrin/bits.h"
#include "libc/intrin/bsr.h"
#include "libc/intrin/dll.h"
#include "libc/intrin/popcnt.h"
#include "libc/intrin/kprintf.h"
#include "libc/log/internal.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
@ -60,64 +59,30 @@ static unsigned long roundup2pow(unsigned long x) {
}
void _pthread_free(struct PosixThread *pt) {
static atomic_uint freed;
if (pt->flags & PT_STATIC) return;
free(pt->tls);
if ((pt->flags & PT_OWNSTACK) && //
pt->attr.__stackaddr && //
pt->attr.__stackaddr != MAP_FAILED) {
npassert(!munmap(pt->attr.__stackaddr, pt->attr.__stacksize));
}
if (pt->altstack) {
free(pt->altstack);
unassert(!munmap(pt->attr.__stackaddr, pt->attr.__stacksize));
}
free(pt);
if (popcnt(atomic_fetch_add_explicit(&freed, 1, memory_order_acq_rel)) == 1) {
malloc_trim(0);
}
}
void pthread_kill_siblings_np(void) {
struct Dll *e, *e2;
struct PosixThread *pt, *self;
self = (struct PosixThread *)__get_tls()->tib_pthread;
pthread_spin_lock(&_pthread_lock);
for (e = dll_first(_pthread_list); e; e = e2) {
e2 = dll_next(_pthread_list, e);
pt = POSIXTHREAD_CONTAINER(e);
if (pt != self) {
pthread_kill((pthread_t)pt, SIGKILL);
dll_remove(&_pthread_list, e);
pthread_spin_unlock(&_pthread_lock);
_pthread_free(pt);
}
}
pthread_spin_unlock(&_pthread_lock);
}
static int PosixThread(void *arg, int tid) {
void *rc;
struct sigaltstack ss;
struct PosixThread *pt = arg;
unassert(__get_tls()->tib_tid > 0);
if (pt->altstack) {
ss.ss_flags = 0;
ss.ss_size = SIGSTKSZ;
ss.ss_sp = pt->altstack;
if (sigaltstack(&ss, 0)) {
notpossible;
}
}
if (pt->attr.__inheritsched == PTHREAD_EXPLICIT_SCHED) {
_pthread_reschedule(pt);
}
// set long jump handler so pthread_exit can bring control back here
if (!setjmp(pt->exiter)) {
__get_tls()->tib_pthread = (pthread_t)pt;
npassert(!sigprocmask(SIG_SETMASK, (sigset_t *)pt->attr.__sigmask, 0));
unassert(!sigprocmask(SIG_SETMASK, (sigset_t *)pt->attr.__sigmask, 0));
rc = pt->start(pt->arg);
// ensure pthread_cleanup_pop(), and pthread_exit() popped cleanup
npassert(!pt->cleanup);
unassert(!pt->cleanup);
// calling pthread_exit() will either jump back here, or call exit
pthread_exit(rc);
}
@ -251,11 +216,6 @@ static errno_t pthread_create_impl(pthread_t *thread,
}
}
// setup signal handler stack
if (_wantcrashreports && !IsWindows()) {
pt->altstack = malloc(SIGSTKSZ);
}
// set initial status
if (!pt->attr.__havesigmask) {
pt->attr.__havesigmask = true;