Get threads working on all platforms

We now have a high-quality clone() implementation for creating
lightweight threads on Linux/Windows/FreeBSD/NetBSD/OpenBSD.
This commit is contained in:
Justine Tunney 2022-05-12 17:52:13 -07:00
parent 4e62cefa6e
commit fec396037a
43 changed files with 850 additions and 532 deletions

View file

@ -133,6 +133,8 @@ int getpgrp(void) nosideeffect;
int getpid(void);
int getppid(void);
int getpriority(int, unsigned);
int getresgid(uint32_t *, uint32_t *, uint32_t *);
int getresuid(uint32_t *, uint32_t *, uint32_t *);
int getrlimit(int, struct rlimit *);
int getrusage(int, struct rusage *);
int getsid(int) nosideeffect;
@ -163,6 +165,7 @@ int pause(void);
int personality(uint64_t);
int pipe(int[hasatleast 2]);
int pipe2(int[hasatleast 2], int);
int pledge(const char *, const char *);
int posix_fadvise(int, uint64_t, uint64_t, int);
int posix_madvise(void *, uint64_t, int);
int prctl(int, ...);
@ -186,8 +189,6 @@ int setpriority(int, unsigned, int);
int setregid(uint32_t, uint32_t);
int setresgid(uint32_t, uint32_t, uint32_t);
int setresuid(uint32_t, uint32_t, uint32_t);
int getresgid(uint32_t *, uint32_t *, uint32_t *);
int getresuid(uint32_t *, uint32_t *, uint32_t *);
int setreuid(uint32_t, uint32_t);
int setrlimit(int, const struct rlimit *);
int setsid(void);
@ -203,6 +204,8 @@ int symlinkat(const char *, int, const char *);
int sync_file_range(int, int64_t, int64_t, unsigned);
int sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
int sysinfo(struct sysinfo *);
int tgkill(int, int, int);
int tkill(int, int);
int touch(const char *, uint32_t);
int truncate(const char *, uint64_t);
int ttyname_r(int, char *, size_t);
@ -239,7 +242,6 @@ ssize_t write(int, const void *, size_t);
struct dirent *readdir(DIR *);
void rewinddir(DIR *);
void sync(void);
int pledge(const char *, const char *);
int clone(int (*)(void *), void *, size_t, int, void *, int *, void *, size_t,
int *);

View file

@ -158,6 +158,7 @@ i32 sys_fsync(i32) hidden;
i32 sys_ftruncate(i32, i64, i64) hidden;
i32 sys_futimes(i32, const struct timeval *) hidden;
i32 sys_futimesat(i32, const char *, const struct timeval *) hidden;
i32 sys_getcontext(void *) hidden;
i32 sys_getitimer(i32, struct itimerval *) hidden;
i32 sys_getpgid(i32) hidden;
i32 sys_getpgrp(void) hidden;
@ -212,6 +213,8 @@ i32 sys_symlinkat(const char *, i32, const char *) hidden;
i32 sys_sync(void) hidden;
i32 sys_sync_file_range(i32, i64, i64, u32) hidden;
i32 sys_sysinfo(struct sysinfo *) hidden;
i32 sys_tgkill(i32, i32, i32) hidden;
i32 sys_tkill(i32, i32, void *) hidden;
i32 sys_truncate(const char *, u64, u64) hidden;
i32 sys_uname(char *) hidden;
i32 sys_unlinkat(i32, const char *, i32) hidden;

View file

@ -50,8 +50,8 @@ privileged void *sys_mremap(void *p, size_t n, size_t m, int f, void *q) {
r10 = m;
r8 = (f & MREMAP_FIXED) ? MAP_FIXED : 0;
asm(CFLAG_ASM("syscall")
: CFLAG_CONSTRAINT(cf), "+a"(rax)
: "D"(p), "S"(n), "d"(q), "r"(r10), "r"(r8)
: CFLAG_CONSTRAINT(cf), "+a"(rax), "=d"(rdx)
: "D"(p), "S"(n), "2"(q), "r"(r10), "r"(r8)
: "rcx", "r9", "r11", "memory", "cc");
if (cf) errno = rax, rax = -1;
} else {

34
libc/calls/tgkill.c Normal file
View file

@ -0,0 +1,34 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
/**
* Kills thread group.
*
* @raises ENOSYS on non-Linux
* @see tkill()
*/
int tgkill(int tgid, int tid, int sig) {
int rc;
rc = sys_tgkill(tgid, tid, sig);
STRACE("tgkill(%d, %d, %G) → %d% m", tgid, tid, sig, rc);
return rc;
}

61
libc/calls/tkill.c Normal file
View file

@ -0,0 +1,61 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/dce.h"
#include "libc/intrin/kprintf.h"
#include "libc/nt/enum/threadaccess.h"
#include "libc/nt/runtime.h"
#include "libc/nt/thread.h"
#include "libc/sysv/errfuns.h"
static textwindows int sys_tkill_nt(int tid, int sig) {
int rc;
int64_t hand;
if ((hand = OpenThread(kNtThreadTerminate, false, tid))) {
if (TerminateThread(hand, 128 + sig)) {
rc = 0;
} else {
rc = __winerr();
}
CloseHandle(hand);
} else {
rc = esrch();
}
return rc;
}
/**
* Kills thread.
*
* @param tid is thread id
* @param sig does nothing on xnu
* @return 0 on success, or -1 w/ errno
*/
int tkill(int tid, int sig) {
int rc;
if (!IsWindows()) {
rc = sys_tkill(tid, sig, 0);
} else {
rc = sys_tkill_nt(tid, sig);
}
STRACE("tkill(%d, %G) → %d% m", tid, sig, rc);
return rc;
}