mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Get rid of kmalloc()
This changes *NSYNC to allocate waiters on the stack so our locks don't need to depend on dynamic memory. This make our runtiem simpler, and it also fixes bugs with thread cancellation support.
This commit is contained in:
parent
77a7873057
commit
a359de7893
57 changed files with 405 additions and 472 deletions
|
@ -71,7 +71,7 @@ int execve(const char *prog, char *const argv[], char *const envp[]) {
|
|||
rc = _weaken(sys_pledge_linux)(__execpromises, __pledge_mode);
|
||||
}
|
||||
if (!rc) {
|
||||
if (_weaken(__zipos_parseuri) &&
|
||||
if (0 && _weaken(__zipos_parseuri) &&
|
||||
(_weaken(__zipos_parseuri)(prog, &uri) != -1)) {
|
||||
rc = _weaken(__zipos_open)(&uri, O_RDONLY | O_CLOEXEC);
|
||||
if (rc != -1) {
|
||||
|
|
|
@ -25,12 +25,13 @@
|
|||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/calls/wincrash.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kmalloc.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/leaky.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/backtrace.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/createfile.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/filelockflags.h"
|
||||
|
@ -72,7 +73,7 @@ static textwindows struct FileLock *NewFileLock(void) {
|
|||
fl = g_locks.free;
|
||||
g_locks.free = fl->next;
|
||||
} else {
|
||||
fl = kmalloc(sizeof(*fl));
|
||||
unassert((fl = _weaken(malloc)(sizeof(*fl))));
|
||||
}
|
||||
bzero(fl, sizeof(*fl));
|
||||
fl->next = g_locks.list;
|
||||
|
@ -80,6 +81,8 @@ static textwindows struct FileLock *NewFileLock(void) {
|
|||
return fl;
|
||||
}
|
||||
|
||||
IGNORE_LEAKS(NewFileLock)
|
||||
|
||||
static textwindows void FreeFileLock(struct FileLock *fl) {
|
||||
fl->next = g_locks.free;
|
||||
g_locks.free = fl;
|
||||
|
@ -129,6 +132,10 @@ static textwindows int sys_fcntl_nt_lock(struct Fd *f, int fd, int cmd,
|
|||
int64_t pos, off, len, end;
|
||||
struct FileLock *fl, *ft, **flp;
|
||||
|
||||
if (!_weaken(malloc)) {
|
||||
return enomem();
|
||||
}
|
||||
|
||||
l = (struct flock *)arg;
|
||||
len = l->l_len;
|
||||
off = l->l_start;
|
||||
|
|
|
@ -87,8 +87,6 @@ textwindows int ntspawn(
|
|||
block = NULL;
|
||||
_init_sigchld();
|
||||
if (__mkntpath(prog, prog16) == -1) return -1;
|
||||
// we can't call malloc() because we're higher in the topological order
|
||||
// we can't call kmalloc() because fork() calls this when kmalloc is locked
|
||||
if ((handle = CreateFileMapping(-1, 0, pushpop(kNtPageReadwrite), 0,
|
||||
sizeof(*block), 0)) &&
|
||||
(block = MapViewOfFileEx(handle, kNtFileMapRead | kNtFileMapWrite, 0, 0,
|
||||
|
|
|
@ -87,6 +87,7 @@ i32 sys_sem_close(i64);
|
|||
i32 sys_sem_destroy(i64);
|
||||
i32 sys_sem_getvalue(i64, u32 *);
|
||||
i32 sys_sem_init(u32, i64 *);
|
||||
i32 sys_sem_destroy(i64);
|
||||
i32 sys_sem_open(const char *, int, u32, i64 *);
|
||||
i32 sys_sem_post(i64);
|
||||
i32 sys_sem_trywait(i64);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "libc/calls/termios.internal.h"
|
||||
#include "libc/calls/ttydefaults.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/nomultics.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
|
@ -261,6 +262,7 @@ textwindows int tcsetattr_nt(int fd, int opt, const struct termios *tio) {
|
|||
__attribute__((__constructor__)) static void tcsetattr_nt_init(void) {
|
||||
if (!getenv("TERM")) {
|
||||
setenv("TERM", "xterm-256color", true);
|
||||
errno = 0; // ignore malloc not linked
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -98,16 +98,43 @@ static dontinline textwindows int __tkill_nt(int tid, int sig,
|
|||
}
|
||||
}
|
||||
|
||||
static int __tkill_m1(int tid, int sig, struct CosmoTib *tib) {
|
||||
struct PosixThread *pt = (struct PosixThread *)__get_tls()->tib_pthread;
|
||||
return __syslib->pthread_kill(pt->next, sig);
|
||||
static int __tkill_posix(int tid, int sig, struct CosmoTib *tib) {
|
||||
|
||||
// avoid lock when killing self
|
||||
int me;
|
||||
struct PosixThread *pt;
|
||||
pt = (struct PosixThread *)__get_tls()->tib_pthread;
|
||||
me = atomic_load_explicit(&__get_tls()->tib_tid, memory_order_relaxed);
|
||||
if (tid == me && (!tib || tib == __get_tls())) {
|
||||
return __syslib->pthread_kill(pt->next, sig);
|
||||
}
|
||||
|
||||
// otherwise look for matching thread
|
||||
struct Dll *e;
|
||||
pthread_spin_lock(&_pthread_lock);
|
||||
for (e = dll_first(_pthread_list); e; e = dll_next(_pthread_list, e)) {
|
||||
enum PosixThreadStatus status;
|
||||
struct PosixThread *pt = POSIXTHREAD_CONTAINER(e);
|
||||
int rhs = atomic_load_explicit(&pt->tib->tib_tid, memory_order_acquire);
|
||||
if (rhs <= 0 || tid != rhs) continue;
|
||||
if (tib && tib != pt->tib) continue;
|
||||
status = atomic_load_explicit(&pt->status, memory_order_acquire);
|
||||
pthread_spin_unlock(&_pthread_lock);
|
||||
if (status < kPosixThreadTerminated) {
|
||||
return __syslib->pthread_kill(pt->next, sig);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
pthread_spin_unlock(&_pthread_lock);
|
||||
return esrch();
|
||||
}
|
||||
|
||||
// OpenBSD has an optional `tib` parameter for extra safety.
|
||||
int __tkill(int tid, int sig, void *tib) {
|
||||
int rc;
|
||||
if (IsXnuSilicon()) {
|
||||
return __tkill_m1(tid, sig, tib);
|
||||
return __tkill_posix(tid, sig, tib);
|
||||
} else if (IsLinux() || IsXnu() || IsFreebsd() || IsOpenbsd() || IsNetbsd()) {
|
||||
rc = sys_tkill(tid, sig, tib);
|
||||
} else if (IsWindows()) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue