Implement thread cancellation for aarch64

This commit is contained in:
Justine Tunney 2023-09-07 08:29:16 -07:00
parent dcda6f7d8d
commit 032b1f3449
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
54 changed files with 297 additions and 167 deletions

View file

@ -155,9 +155,11 @@ SANITIZER = \
-fsanitize=address
NO_MAGIC = \
-ffreestanding \
-fno-stack-protector \
-fwrapv \
-fno-sanitize=all
-fno-sanitize=all \
-fpatchable-function-entry=0,0
OLD_CODE = \
-fno-strict-aliasing \

View file

@ -186,6 +186,7 @@ void *Worker(void *id) {
do {
// parse the incoming http message
InitHttpMessage(&msg, kHttpRequest);
// wait for http message (non-fragmented required)
// we're not terrible concerned when errors happen here
unassert(!pthread_setcancelstate(PTHREAD_CANCEL_MASKED, 0));
if ((got = read(client, inbuf, sizeof(inbuf))) <= 0) break;
@ -198,9 +199,8 @@ void *Worker(void *id) {
#if LOGGING
// log the incoming http message
unsigned clientip = ntohl(clientaddr.sin_addr.s_addr);
kprintf("\r\e[K%6P get some %d.%d.%d.%d:%d %#.*s\n",
(clientip & 0xff000000) >> 030, (clientip & 0x00ff0000) >> 020,
(clientip & 0x0000ff00) >> 010, (clientip & 0x000000ff) >> 000,
kprintf("\r\e[K%6P get some %hhu.%hhu.%hhu.%hhu:%hu %#.*s\n",
clientip >> 24, clientip >> 16, clientip >> 8, clientip,
ntohs(clientaddr.sin_port), msg.uri.b - msg.uri.a,
inbuf + msg.uri.a);
SomethingHappened();
@ -314,10 +314,8 @@ int main(int argc, char *argv[]) {
// Cosmo's GetHostIps() API is much easier than ioctl(SIOCGIFCONF)
uint32_t *hostips;
for (hostips = gc(GetHostIps()), i = 0; hostips[i]; ++i) {
kprintf("listening on http://%d.%d.%d.%d:%d\n",
(hostips[i] & 0xff000000) >> 030, (hostips[i] & 0x00ff0000) >> 020,
(hostips[i] & 0x0000ff00) >> 010, (hostips[i] & 0x000000ff) >> 000,
PORT);
kprintf("listening on http://%hhu.%hhu.%hhu.%hhu:%hu\n", hostips[i] >> 24,
hostips[i] >> 16, hostips[i] >> 8, hostips[i], PORT);
}
// you can pass the number of threads you want as the first command arg
@ -414,7 +412,7 @@ int main(int argc, char *argv[]) {
while (!a_termsig) {
PrintStatus();
unassert(!pthread_cond_wait(&statuscond, &statuslock));
usleep(20);
usleep(10 * 1000);
}
unassert(!pthread_mutex_unlock(&statuslock));

View file

@ -121,6 +121,7 @@ _start:
mov x0,sp
// setup the stack
mov x28,#0
mov x29,#0
mov x30,#0
ldr x1,=ape_stack_round

View file

@ -81,15 +81,15 @@ void AppendResourceReport(char **b, struct rusage *ru, const char *nl) {
ticks = ceill((long double)(utime + stime) / (1000000.L / CLK_TCK));
if (ru->ru_idrss) {
AppendMetric(st, "needed ", lroundl(ru->ru_idrss / ticks),
" memory on average");
}
if (ru->ru_isrss) {
AppendMetric(st, "needed ", lroundl(ru->ru_isrss / ticks),
" stack on average");
"kb private on average");
}
if (ru->ru_ixrss) {
AppendMetric(st, "needed ", lroundl(ru->ru_ixrss / ticks),
" shared on average");
"kb shared on average");
}
if (ru->ru_isrss) {
AppendMetric(st, "needed ", lroundl(ru->ru_isrss / ticks),
"kb stack on average");
}
}
if (ru->ru_minflt || ru->ru_majflt) {

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall __sys_accept,0x81e81ea1d281e82b,202,30,globl,hidden
.scall __sys_accept,0x81e81ea1d281e82b,2250,30,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall __sys_accept4,0xfff85da1dffff920,242,4095,globl,hidden
.scall __sys_accept4,0xfff85da1dffff920,2290,4095,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall __sys_clock_nanosleep,0x9ddfff8f4ffff8e6,115,4095,globl,hidden
.scall __sys_clock_nanosleep,0x9ddfff8f4ffff8e6,2163,4095,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall __sys_connect,0x862862862286282a,203,98,globl,hidden
.scall __sys_connect,0x862862862286282a,2251,98,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall __sys_fcntl_cp,0x85c85c85c285c848,25,92,globl,hidden
.scall __sys_fcntl_cp,0x85c85c85c285c848,2073,92,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall __sys_openat,0x9d49419f329cf901,56,463,globl,hidden
.scall __sys_openat,0x9d49419f329cf901,2104,463,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall __sys_wait4,0x9c180b807280783d,260,7,globl,hidden
.scall __sys_wait4,0x9c180b807280783d,2308,7,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_copy_file_range,0xffffffa39ffff946,285,4095,globl,hidden
.scall sys_copy_file_range,0xffffffa39ffff946,2333,4095,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_epoll_pwait,0xfffffffffffff919,22,4095,globl,hidden
.scall sys_epoll_pwait,0xfffffffffffff919,2070,4095,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_fdatasync,0x8f185fa2628bb84b,83,187,globl,hidden
.scall sys_fdatasync,0x8f185fa2628bb84b,2131,187,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_flock,0x8838838832883849,32,131,globl,hidden
.scall sys_flock,0x8838838832883849,2080,131,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_fstatfs,0x89e840a2c295a88a,44,346,globl,hidden
.scall sys_fstatfs,0x89e840a2c295a88a,2092,346,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_fsync,0x85f85f85f285f84a,82,95,globl,hidden
.scall sys_fsync,0x85f85f85f285f84a,2130,95,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_ftruncate,0x8c98a89e028c984d,46,201,globl,hidden
.scall sys_ftruncate,0x8c98a89e028c984d,2094,201,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_futex_cp,0x8a68539c6ffff8ca,98,4095,globl,hidden
.scall sys_futex_cp,0x8a68539c6ffff8ca,2146,4095,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_ioctl_cp,0x8368368362836810,29,54,globl,hidden
.scall sys_ioctl_cp,0x8368368362836810,2077,54,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_msgrcv,0x8e38e38e32905846,188,261,globl
.scall sys_msgrcv,0x8e38e38e32905846,2236,261,globl

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_msgsnd,0x8e28e28e22904845,189,260,globl
.scall sys_msgsnd,0x8e28e28e22904845,2237,260,globl

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_msync,0x915900841284181a,227,65,globl,hidden
.scall sys_msync,0x915900841284181a,2275,65,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_nanosleep,0x9ae85b8f0ffff823,101,4095,globl,hidden
.scall sys_nanosleep,0x9ae85b8f0ffff823,2149,4095,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_ppoll,0xfff86da21ffff90f,73,4095,globl,hidden
.scall sys_ppoll,0xfff86da21ffff90f,2121,4095,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_pread,0x8ad8a99db2899811,67,153,globl,hidden
.scall sys_pread,0x8ad8a99db2899811,2115,153,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_preadv,0x9218ab9212a1c927,69,540,globl,hidden
.scall sys_preadv,0x9218ab9212a1c927,2117,540,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_pselect,0x9b486ea0a298a90e,72,394,globl,hidden
.scall sys_pselect,0x9b486ea0a298a90e,2120,394,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_pwrite,0x8ae8aa9dc289a812,68,154,globl,hidden
.scall sys_pwrite,0x8ae8aa9dc289a812,2116,154,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_pwritev,0x9228ac9222a1d928,70,541,globl,hidden
.scall sys_pwritev,0x9228ac9222a1d928,2118,541,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_read,0x8038038032803800,63,3,globl,hidden
.scall sys_read,0x8038038032803800,2111,3,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_readv,0x8788788782878813,65,120,globl,hidden
.scall sys_readv,0x8788788782878813,2113,120,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_recvfrom,0x81d81d81d281d82d,207,29,globl,hidden
.scall sys_recvfrom,0x81d81d81d281d82d,2255,29,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_recvmsg,0x81b81b81b281b82f,212,27,globl,hidden
.scall sys_recvmsg,0x81b81b81b281b82f,2260,27,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_sendmsg,0x81c81c81c281c82e,211,28,globl,hidden
.scall sys_sendmsg,0x81c81c81c281c82e,2259,28,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_sendto,0x885885885288582c,206,133,globl,hidden
.scall sys_sendto,0x885885885288582c,2254,133,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_sigsuspend,0x92686f955286f882,133,111,globl,hidden
.scall sys_sigsuspend,0x92686f955286f882,2181,111,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_sigtimedwait,0x9affff959ffff880,137,4095,globl,hidden
.scall sys_sigtimedwait,0x9affff959ffff880,2185,4095,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_statfs,0x89d83fa2b2959889,43,345,globl,hidden
.scall sys_statfs,0x89d83fa2b2959889,2091,345,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_truncate,0x8c88a79df28c884c,45,200,globl,hidden
.scall sys_truncate,0x8c88a79df28c884c,2093,200,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_write,0x8048048042804801,64,4,globl,hidden
.scall sys_write,0x8048048042804801,2112,4,globl,hidden

View file

@ -1,2 +1,2 @@
#include "libc/sysv/macros.internal.h"
.scall sys_writev,0x8798798792879814,66,121,globl,hidden
.scall sys_writev,0x8798798792879814,2114,121,globl,hidden

View file

@ -35,62 +35,12 @@
.endif
.endfn \name,\kw1,\kw2
#elif defined(__aarch64__)
.ifc \arm_linux,4095
.ifc \arm_xnu,4095
// return enosys();
.ftrace1
\name: .ftrace2
b enosys
mov x8,#\arm_linux
mov x16,#\arm_xnu
b systemfive
.endfn \name,\kw1,\kw2
.else
// return IsXnu() ? syscall(x16, ...) : syscall(x8, ...);
.ftrace1
\name: .ftrace2
adrp x9,__hostos
ldr w9,[x9,#:lo12:__hostos]
tbz x9,#3,1f // !IsXnu()
mov x16,#\arm_xnu // apple ordinal
mov x9,#0 // clear carry flag
adds x9,x9,#0 // clear carry flag
svc #0 // issue system call
bcs 1f
b _sysret
1: neg x0,x0
b _sysret
.hidden _sysret
.endfn \name,\kw1,\kw2
.endif
.else
.ifc \arm_xnu,4095
// return IsLinux() ? syscall(x8, ...) : enosys();
.ftrace1
\name: .ftrace2
adrp x9,__hostos
ldr w9,[x9,#:lo12:__hostos]
tbz x9,#0,1f // !IsLinux()
mov x8,#\arm_linux // systemd ordinal
svc #0 // issue system call
mov x1,#\arm_linux
b _sysret
.hidden _sysret
1: b enosys
.endfn \name,\kw1,\kw2
.else
.ftrace1
\name: .ftrace2
mov x16,#\arm_xnu // apple ordinal
mov x8,#\arm_linux // systemd ordinal
mov x9,#0 // clear carry flag
adds x9,x9,#0 // clear carry flag
svc #0 // issue system call
bcs 1f
b _sysret
1: neg x0,x0
b _sysret
.hidden _sysret
.endfn \name,\kw1,\kw2
.endif
.endif
#else
#error "architecture unsupported"
#endif

View file

@ -34,30 +34,30 @@ dir=libc/sysv/calls
# 9.1+│ │ │ │ │ │
# Symbol ┌┴┐┌┴┐┌┴┐│┬┴┐┌┴┐ Arm64 Directives & Commentary
scall sys_exit 0x00100100120010e7 0x05e globl hidden # a.k.a. exit_group
scall sys_read 0x8038038032803800 0x03f globl hidden
scall sys_write 0x8048048042804801 0x040 globl hidden
scall sys_read 0x8038038032803800 0x83f globl hidden
scall sys_write 0x8048048042804801 0x840 globl hidden
scall sys_close 0x0060060062006003 0x039 globl hidden
scall __sys_stat 0x1b7026fff2152004 0x04f globl hidden # FreeBSD 11→12 fumble; use sys_fstatat(); blocked on Android
scall __sys_fstat 0x1b80352272153005 0x050 globl hidden # needs __stat2linux()
scall __sys_lstat 0x1b90280282154006 0xfff globl hidden # needs __stat2linux(); blocked on Android
scall __sys_poll 0x8d18fc8d128e6807 0xfff globl hidden
scall sys_ppoll 0xfff86da21ffff90f 0x049 globl hidden # consider INTON/INTOFF tutorial in examples/unbourne.c
scall sys_ppoll 0xfff86da21ffff90f 0x849 globl hidden # consider INTON/INTOFF tutorial in examples/unbourne.c
scall sys_lseek 0x0c70a61de20c7008 0x03e globl hidden # netbsd:evilpad, OpenBSD 7.3+
scall __sys_mmap 0x0c50311dd20c5009 0x0de globl hidden # netbsd:pad, OpenBSD 7.3+
scall sys_msync 0x915900841284181a 0x0e3 globl hidden
scall sys_msync 0x915900841284181a 0x8e3 globl hidden
scall sys_mprotect 0x04a04a04a204a00a 0x0e2 globl hidden
scall __sys_munmap 0x049049049204900b 0x0d7 globl hidden
scall sys_sigaction 0x15402e1a0202e00d 0x086 globl hidden # rt_sigaction on Lunix; __sigaction_sigtramp() on NetBSD
scall __sys_sigprocmask 0x125030154214900e 0x087 globl hidden # a.k.a. rt_sigprocmask, openbsd:byvalue, a.k.a. pthread_sigmask
scall sys_ioctl 0x0360360362036010 0x01d globl hidden
scall sys_ioctl_cp 0x8368368362836810 0x01d globl hidden # intended for TCSBRK
scall sys_pread 0x8ad8a99db2899811 0x043 globl hidden # a.k.a. pread64; netbsd:pad, OpenBSD 7.3+
scall sys_pwrite 0x8ae8aa9dc289a812 0x044 globl hidden # a.k.a. pwrite64; netbsd:pad, OpenBSD 7.3+
scall sys_readv 0x8788788782878813 0x041 globl hidden
scall sys_writev 0x8798798792879814 0x042 globl hidden
scall sys_ioctl_cp 0x8368368362836810 0x81d globl hidden # intended for TCSBRK
scall sys_pread 0x8ad8a99db2899811 0x843 globl hidden # a.k.a. pread64; netbsd:pad, OpenBSD 7.3+
scall sys_pwrite 0x8ae8aa9dc289a812 0x844 globl hidden # a.k.a. pwrite64; netbsd:pad, OpenBSD 7.3+
scall sys_readv 0x8788788782878813 0x841 globl hidden
scall sys_writev 0x8798798792879814 0x842 globl hidden
scall __sys_pipe 0x02a10721e202a016 0x03b globl hidden # NOTE: pipe2() on FreeBSD and Linux Aarch64; XNU is pipe(void)→eax:edx
scall sys_select 0x9a184785d285d817 0xfff globl hidden
scall sys_pselect 0x9b486ea0a298a90e 0x048 globl hidden # pselect6() on gnu/systemd
scall sys_pselect 0x9b486ea0a298a90e 0x848 globl hidden # pselect6() on gnu/systemd
scall sys_sched_yield 0x15e12a14bf25d018 0x07c globl hidden # select() on XNU (previously swtch() but removed in 12.4)
scall __sys_mremap 0x19bffffffffff019 0x0d8 globl hidden
scall sys_mincore 0x04e04e04e204e01b 0x0e8 globl hidden
@ -68,20 +68,20 @@ scall sys_shmctl 0x1bb128200210701f 0x0c3 globl # no wrapper
scall sys_dup 0x0290290292029020 0x017 globl hidden
scall sys_dup2 0x05a05a05a205a021 0x018 globl hidden # dup3() on linux aarch64 (doesn't behave same if oldfd==newfd)
scall sys_pause 0xfffffffffffff022 0xfff globl hidden
scall sys_nanosleep 0x9ae85b8f0ffff823 0x065 globl hidden
scall __sys_clock_nanosleep 0x9ddfff8f4ffff8e6 0x073 globl hidden
scall sys_nanosleep 0x9ae85b8f0ffff823 0x865 globl hidden
scall __sys_clock_nanosleep 0x9ddfff8f4ffff8e6 0x873 globl hidden
scall sys_getitimer 0x1aa0460562056024 0x066 globl hidden
scall sys_setitimer 0x1a90450532053026 0x067 globl hidden
scall sys_alarm 0xfffffffffffff025 0xfff globl hidden
scall sys_getpid 0x0140140142014027 0x0ac globl hidden # netbsd returns ppid in edx
scall sys_sendfile 0xffffff1892151028 0x047 globl hidden # Linux vs. XNU/BSD ABIs very different
scall __sys_socket 0x18a0610612061029 0x0c6 globl hidden
scall __sys_connect 0x862862862286282a 0x0cb globl hidden
scall __sys_accept 0x81e81ea1d281e82b 0x0ca globl hidden # accept4 on freebsd
scall sys_sendto 0x885885885288582c 0x0ce globl hidden
scall sys_recvfrom 0x81d81d81d281d82d 0x0cf globl hidden
scall sys_sendmsg 0x81c81c81c281c82e 0x0d3 globl hidden
scall sys_recvmsg 0x81b81b81b281b82f 0x0d4 globl hidden
scall __sys_connect 0x862862862286282a 0x8cb globl hidden
scall __sys_accept 0x81e81ea1d281e82b 0x8ca globl hidden # accept4 on freebsd
scall sys_sendto 0x885885885288582c 0x8ce globl hidden
scall sys_recvfrom 0x81d81d81d281d82d 0x8cf globl hidden
scall sys_sendmsg 0x81c81c81c281c82e 0x8d3 globl hidden
scall sys_recvmsg 0x81b81b81b281b82f 0x8d4 globl hidden
scall sys_shutdown 0x0860860862086030 0x0d2 globl hidden
scall __sys_bind 0x0680680682068031 0x0c8 globl hidden
scall sys_listen 0x06a06a06a206a032 0x0c9 globl hidden
@ -94,14 +94,14 @@ scall __sys_fork 0x0020020022002039 0xfff globl hidden # xnu needs eax&=~-edx b
#scall vfork 0x042042042204203a 0xfff globl # this syscall is from the moon so we implement it by hand in libc/runtime/vfork.S; probably removed from XNU in 12.5
scall sys_posix_spawn 0x1daffffff20f4fff 0xfff globl hidden # good luck figuring out how xnu defines this
scall __sys_execve 0x03b03b03b203b03b 0x0dd globl hidden
scall __sys_wait4 0x9c180b807280783d 0x104 globl hidden
scall __sys_wait4 0x9c180b807280783d 0x904 globl hidden
scall sys_kill 0x02507a025202503e 0x081 globl hidden # kill(pid, sig, 1) b/c xnu
scall sys_killpg 0x092fff092fffffff 0xfff globl hidden
scall sys_clone 0x11fffffffffff038 0x0dc globl hidden
scall sys_tkill 0x13e0771b121480c8 0x082 globl hidden # thr_kill() on FreeBSD; _lwp_kill() on NetBSD; thrkill() on OpenBSD where arg3 should be 0 or tcb; __pthread_kill() on XNU
scall sys_tgkill 0xffffff1e1ffff0ea 0x083 globl hidden # thr_kill2() on FreeBSD
scall sys_futex 0x0a60531c6ffff0ca 0x062 globl hidden # raises SIGSYS on NetBSD; _umtx_op() on FreeBSD
scall sys_futex_cp 0x8a68539c6ffff8ca 0x062 globl hidden # intended for futex wait ops
scall sys_futex_cp 0x8a68539c6ffff8ca 0x862 globl hidden # intended for futex wait ops
scall sys_set_robust_list 0x0a7ffffffffff111 0x063 globl # no wrapper
scall sys_get_robust_list 0x0a8ffffffffff112 0x064 globl # no wrapper
scall sys_uname 0x0a4fff0a4ffff03f 0x0a0 globl hidden
@ -110,16 +110,16 @@ scall sys_semop 0x0de1220de2100041 0x0c1 globl # no wrapper
scall sys_semctl 0xfff1271fe20fe042 0x0bf globl # no wrapper
scall sys_shmdt 0x0e60e60e62108043 0x0c5 globl # no wrapper
scall sys_msgget 0x0e10e10e12103044 0x0ba globl # no wrapper
scall sys_msgsnd 0x8e28e28e22904845 0x0bd globl # no wrapper
scall sys_msgrcv 0x8e38e38e32905846 0x0bc globl # no wrapper
scall sys_msgsnd 0x8e28e28e22904845 0x8bd globl # no wrapper
scall sys_msgrcv 0x8e38e38e32905846 0x8bc globl # no wrapper
scall sys_msgctl 0x1bc1291ff2102047 0x0bb globl # no wrapper
scall __sys_fcntl 0x05c05c05c205c048 0x019 globl hidden
scall __sys_fcntl_cp 0x85c85c85c285c848 0x019 globl hidden # intended for F_SETLKW and F_OFD_SETLKW
scall sys_flock 0x8838838832883849 0x020 globl hidden
scall sys_fsync 0x85f85f85f285f84a 0x052 globl hidden
scall sys_fdatasync 0x8f185fa2628bb84b 0x053 globl hidden # fsync() on openbsd
scall sys_truncate 0x8c88a79df28c884c 0x02d globl hidden # netbsd:pad, OpenBSD 7.3+
scall sys_ftruncate 0x8c98a89e028c984d 0x02e globl hidden # netbsd:pad, OpenBSD 7.3+
scall __sys_fcntl_cp 0x85c85c85c285c848 0x819 globl hidden # intended for F_SETLKW and F_OFD_SETLKW
scall sys_flock 0x8838838832883849 0x820 globl hidden
scall sys_fsync 0x85f85f85f285f84a 0x852 globl hidden
scall sys_fdatasync 0x8f185fa2628bb84b 0x853 globl hidden # fsync() on openbsd
scall sys_truncate 0x8c88a79df28c884c 0x82d globl hidden # netbsd:pad, OpenBSD 7.3+
scall sys_ftruncate 0x8c98a89e028c984d 0x82e globl hidden # netbsd:pad, OpenBSD 7.3+
scall sys_getcwd 0x128130146ffff04f 0x011 globl hidden
scall sys_chdir 0x00c00c00c200c050 0x031 globl hidden
scall sys_fchdir 0x00d00d00d200d051 0x032 globl hidden
@ -154,14 +154,14 @@ scall sys_setresgid 0xfff11c138ffff077 0x095 globl hidden # polyfilled for xnu
scall sys_getresuid 0xfff119168ffff076 0x094 globl hidden # semantics aren't well-defined
scall sys_getresgid 0xfff11b169ffff078 0x096 globl hidden # semantics aren't well-defined
scall sys_sigpending 0x124034157203407f 0x088 globl hidden # a.k.a. rt_sigpending on linux
scall sys_sigsuspend 0x92686f955286f882 0x085 globl hidden # a.k.a. rt_sigsuspend on Linux; openbsd:byvalue, sigsuspend_nocancel on XNU
scall sys_sigsuspend 0x92686f955286f882 0x885 globl hidden # a.k.a. rt_sigsuspend on Linux; openbsd:byvalue, sigsuspend_nocancel on XNU
scall sys_sigaltstack 0x1191200352035083 0x084 globl hidden
scall sys_mknod 0x1c200e00e200e085 0xfff globl hidden
scall sys_mknodat 0x1cc14022fffff103 0x021 globl # no wrapper; FreeBSD 12+
scall sys_mkfifo 0x0840840842084fff 0xfff globl hidden
scall sys_mkfifoat 0x1cb13f1f1fffffff 0xfff globl # no wrapper
scall sys_statfs 0x89d83fa2b2959889 0x02b globl hidden
scall sys_fstatfs 0x89e840a2c295a88a 0x02c globl hidden
scall sys_statfs 0x89d83fa2b2959889 0x82b globl hidden
scall sys_fstatfs 0x89e840a2c295a88a 0x82c globl hidden
scall sys_getpriority 0x064064064206408c 0x08d globl hidden
scall sys_setpriority 0x060060060206008d 0x08c globl hidden # modern nice()
scall sys_mlock 0x0cb0cb0cb20cb095 0x0e4 globl # no wrapper
@ -182,7 +182,7 @@ scall sys_setfsuid 0xfffffffffffff07a 0x097 globl hidden
scall sys_setfsgid 0xfffffffffffff07b 0x098 globl hidden
scall sys_capget 0xfffffffffffff07d 0x05a globl # no wrapper
scall sys_capset 0xfffffffffffff07e 0x05b globl # no wrapper
scall sys_sigtimedwait 0x9affff959ffff880 0x089 globl hidden
scall sys_sigtimedwait 0x9affff959ffff880 0x889 globl hidden
scall sys_sigqueue 0xffffff1c8fffffff 0xfff globl hidden
scall sys_sigqueueinfo 0x0f5ffffffffff081 0x08a globl hidden # a.k.a. rt_sigqueueinfo on linux
scall sys_personality 0xfffffffffffff087 0x05c globl # no wrapper
@ -272,7 +272,7 @@ scall sys_ioprio_get 0xfffffffffffff0fc 0x01f globl
scall sys_inotify_init 0xfffffffffffff0fd 0xfff globl # no wrapper
scall sys_inotify_add_watch 0xfffffffffffff0fe 0xfff globl # no wrapper
scall sys_inotify_rm_watch 0xfffffffffffff0ff 0xfff globl # no wrapper
scall __sys_openat 0x9d49419f329cf901 0x038 globl hidden # Linux 2.6.16+ (c. 2007)
scall __sys_openat 0x9d49419f329cf901 0x838 globl hidden # Linux 2.6.16+ (c. 2007)
scall __sys_openat_nc 0x1d41411f321d0101 0x038 globl hidden # openat_nocancel() on xnu
scall sys_mkdirat 0x1cd13e1f021db102 0x022 globl hidden
scall sys_fchownat 0x1d013b1eb21d4104 0x036 globl hidden # @asyncsignalsafe
@ -296,15 +296,15 @@ scall sys_vmsplice 0xfffffffffffff116 0x04b globl hidden
scall sys_migrate_pages 0xfffffffffffff100 0x0ee globl # no wrapper; numa numa yay
scall sys_move_pages 0xfffffffffffff117 0x0ef globl # no wrapper; NOTE: We view Red Hat versions as "epochs" for all distros.
#──────────────────────RHEL 5.0 LIMIT──────────────────────────────── # ←┬─ last distro with gplv2 licensed compiler c. 2007
scall sys_preadv 0x9218ab9212a1c927 0x045 globl hidden # ├─ last distro with system v shell script init
scall sys_pwritev 0x9228ac9222a1d928 0x046 globl hidden # ├─ rob landley unleashes busybox gpl lawsuits
scall sys_preadv 0x9218ab9212a1c927 0x845 globl hidden # ├─ last distro with system v shell script init
scall sys_pwritev 0x9228ac9222a1d928 0x846 globl hidden # ├─ rob landley unleashes busybox gpl lawsuits
scall __sys_utimensat 0x1d3054223ffff118 0x058 globl hidden # ├─ python modules need this due to pep513
scall sys_fallocate 0xfffffffffffff91d 0x02f globl # ├─ end of life 2020-11-30 (extended)
scall sys_posix_fallocate 0x9dffffa12fffffff 0xfff globl hidden # └─ cosmopolitan supports rhel5+
scall __sys_accept4 0xfff85da1dffff920 0x0f2 globl hidden # Linux 2.6.28+
scall __sys_accept4 0xfff85da1dffff920 0x8f2 globl hidden # Linux 2.6.28+
scall __sys_dup3 0x1c6066fffffff124 0x018 globl hidden # Linux 2.6.27+
scall __sys_pipe2 0x1c506521effff125 0x03b globl hidden # Linux 2.6.27+
scall sys_epoll_pwait 0xfffffffffffff919 0x016 globl hidden
scall sys_epoll_pwait 0xfffffffffffff919 0x816 globl hidden
scall sys_epoll_create1 0xfffffffffffff123 0x014 globl hidden
scall sys_perf_event_open 0xfffffffffffff12a 0x0f1 globl # no wrapper
scall sys_inotify_init1 0xfffffffffffff126 0x01a globl # no wrapper
@ -345,7 +345,7 @@ scall sys_execveat 0xfffffffffffff142 0x119 globl # no wrapper
scall sys_userfaultfd 0xfffffffffffff143 0x11a globl # no wrapper; Linux 4.3+ (c. 2015)
scall sys_membarrier 0xfffffffffffff144 0x11b globl # no wrapper; Linux 4.3+ (c. 2015)
scall sys_mlock2 0xfffffffffffff145 0x11c globl # no wrapper; Linux 4.5+ (c. 2016)
scall sys_copy_file_range 0xffffffa39ffff946 0x11d globl hidden # Linux 4.5+ (c. 2016), FreeBSD 13+
scall sys_copy_file_range 0xffffffa39ffff946 0x91d globl hidden # Linux 4.5+ (c. 2016), FreeBSD 13+
scall sys_preadv2 0xfffffffffffff147 0x11e globl # no wrapper
scall sys_pwritev2 0xfffffffffffff148 0x11f globl # no wrapper
scall sys_pkey_mprotect 0xfffffffffffff149 0x120 globl # no wrapper

157
libc/sysv/sysv.c Normal file
View file

@ -0,0 +1,157 @@
/*-*- 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 2023 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/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/weaken.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/tls.h"
#ifndef __x86_64__
// todo(jart): dismal llvm
register long x0 asm("x0");
register long x1 asm("x1");
register long x2 asm("x2");
register long x3 asm("x3");
register long x4 asm("x4");
register long x5 asm("x5");
register long sysv_ordinal asm("x8");
register long xnu_ordinal asm("x16");
register long cosmo_tls_register asm("x28");
void report_cancellation_point(void);
dontinline long systemfive_cancel(void) {
return _pthread_cancel_sys();
}
// special region of executable memory where cancellation is safe
dontinline long systemfive_cancellable(void) {
// check (1) this is a cancellation point
// plus (2) cancellations aren't disabled
struct PosixThread *pth = 0;
struct CosmoTib *tib = __get_tls();
if (cosmo_tls_register && //
_weaken(_pthread_cancel_sys) && //
!(tib->tib_flags & PT_NOCANCEL) && //
(pth = (struct PosixThread *)tib->tib_pthread)) {
// check if cancellation is already pending
if (atomic_load_explicit(&pth->cancelled, memory_order_acquire)) {
return systemfive_cancel();
}
#if IsModeDbg()
if (!(tib->tib_flags & PT_INCANCEL)) {
if (_weaken(report_cancellation_point)) {
_weaken(report_cancellation_point)();
}
__builtin_trap();
}
#endif
}
// invoke cancellable system call
// this works for both linux and bsd
asm volatile("mov\tx9,0\n\t" // clear carry flag
"adds\tx9,x9,0\n\t" // clear carry flag
"svc\t0\n"
"systemfive_cancellable_end:\n\t"
".globl\tsystemfive_cancellable_end\n\t"
"bcs\t1f\n\t"
"b\t2f\n1:\t"
"neg\tx0,x0\n2:"
: /* global output */
: /* global inputs */
: "x9", "memory");
// if it succeeded then we're done
if (x0 < -4095ul) {
return x0;
}
// check if i/o call was interrupted by sigthr
if (pth && x0 == -EINTR &&
atomic_load_explicit(&pth->cancelled, memory_order_acquire)) {
return systemfive_cancel();
}
// otherwise go down error path
return _sysret(x0);
}
/**
* System Five System Call Support.
*
* This supports POSIX thread cancellation only when the caller flips a
* bit in TLS storage that indicates we're inside a cancellation point.
*
* @param x0 is first argument
* @param x1 is second argument
* @param x2 is third argument
* @param x3 is fourth argument
* @param x4 is fifth argument
* @param x5 is sixth argument
* @param sysv_ordinal is linux ordinal
* @param xnu_ordinal is xnu ordinal
* @return x0
*/
long systemfive(void) {
// handle special cases
if (IsLinux()) {
if (sysv_ordinal == 0xfff) {
return _sysret(-ENOSYS);
}
if (sysv_ordinal & 0x800) {
sysv_ordinal &= ~0x800;
return systemfive_cancellable();
}
}
if (IsXnu()) {
if (xnu_ordinal == 0xfff) {
return _sysret(-ENOSYS);
}
if (xnu_ordinal & 0x800) {
xnu_ordinal &= ~0x800;
return systemfive_cancellable();
}
}
// invoke non-blocking system call
// this works for both linux and bsd
asm volatile("mov\tx9,0\n\t" // clear carry flag
"adds\tx9,x9,0\n\t" // clear carry flag
"svc\t0\n\t"
"bcs\t1f\n\t"
"b\t2f\n1:\t"
"neg\tx0,x0\n2:"
: /* global output */
: /* global inputs */
: "x9", "memory");
// check result
if (x0 < -4095ul) {
return x0;
} else {
return _sysret(x0);
}
}
#endif /* __x86_64__ */

View file

@ -41,6 +41,7 @@ LIBC_SYSV_A_FILES := \
libc/sysv/syscall.S \
libc/sysv/systemfive.S \
libc/sysv/sysret.c \
libc/sysv/sysv.c \
libc/sysv/errno.c \
libc/sysv/errfun.S \
libc/sysv/errfun2.c \
@ -73,6 +74,7 @@ $(LIBC_SYSV_A).pkg: \
$(LIBC_SYSV_A_OBJS) \
$(foreach x,$(LIBC_SYSV_A_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/libc/sysv/sysv.o \
o/$(MODE)/libc/sysv/errno.o \
o/$(MODE)/libc/sysv/sysret.o \
o/$(MODE)/libc/sysv/errfun2.o \
@ -80,6 +82,22 @@ o/$(MODE)/libc/sysv/sysret.o: private \
CFLAGS += \
$(NO_MAGIC)
ifeq ($(ARCH),aarch64)
o/$(MODE)/libc/sysv/sysv.o: private \
CFLAGS += \
-ffixed-x0 \
-ffixed-x1 \
-ffixed-x2 \
-ffixed-x3 \
-ffixed-x4 \
-ffixed-x5 \
-ffixed-x8 \
-ffixed-x16 \
-fomit-frame-pointer \
-foptimize-sibling-calls \
-Os
endif
#───────────────────────────────────────────────────────────────────────────────
LIBC_SYSV_CALLS = \

View file

@ -97,8 +97,8 @@ void _pthread_free(struct PosixThread *);
void _pthread_onfork_prepare(void);
void _pthread_onfork_parent(void);
void _pthread_onfork_child(void);
long _pthread_cancel_sys(void);
void _pthread_ungarbage(void);
int _pthread_cancel_sys(void);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -21,11 +21,13 @@
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/siginfo.h"
#include "libc/calls/struct/sigset.h"
#include "libc/calls/struct/ucontext.internal.h"
#include "libc/calls/syscall_support-sysv.internal.h"
#include "libc/calls/ucontext.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/kprintf.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sa.h"
@ -34,14 +36,13 @@
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
#ifdef __x86_64__
int systemfive_cancel(void);
extern const char systemfive_cancellable[];
extern const char systemfive_cancellable_end[];
int _pthread_cancel_sys(void) {
long _pthread_cancel_sys(void) {
struct PosixThread *pt;
pt = (struct PosixThread *)__get_tls()->tib_pthread;
if (!(pt->flags & (PT_NOCANCEL | PT_MASKED)) || (pt->flags & PT_ASYNC)) {
@ -60,9 +61,9 @@ static void OnSigThr(int sig, siginfo_t *si, void *ctx) {
!(pt->flags & PT_NOCANCEL) &&
atomic_load_explicit(&pt->cancelled, memory_order_acquire)) {
sigaddset(&uc->uc_sigmask, sig);
if (systemfive_cancellable <= (char *)uc->uc_mcontext.rip &&
(char *)uc->uc_mcontext.rip < systemfive_cancellable_end) {
uc->uc_mcontext.rip = (intptr_t)systemfive_cancel;
if (systemfive_cancellable <= (char *)uc->uc_mcontext.PC &&
(char *)uc->uc_mcontext.PC < systemfive_cancellable_end) {
uc->uc_mcontext.PC = (intptr_t)systemfive_cancel;
} else if (pt->flags & PT_ASYNC) {
pthread_exit(PTHREAD_CANCELED);
} else {
@ -302,8 +303,6 @@ errno_t pthread_cancel(pthread_t thread) {
return rc;
}
#endif /* __x86_64__ */
/**
* Creates cancellation point in calling thread.
*

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/atomic.h"
#include "libc/calls/blocksigs.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/sigaltstack.h"
@ -28,6 +29,7 @@
#include "libc/intrin/bits.h"
#include "libc/intrin/bsr.h"
#include "libc/intrin/dll.h"
#include "libc/intrin/popcnt.h"
#include "libc/log/internal.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
@ -58,6 +60,7 @@ 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) && //
@ -69,6 +72,9 @@ void _pthread_free(struct PosixThread *pt) {
free(pt->altstack);
}
free(pt);
if (popcnt(atomic_fetch_add_explicit(&freed, 1, memory_order_acq_rel)) == 1) {
malloc_trim(0);
}
}
void pthread_kill_siblings_np(void) {

View file

@ -16,19 +16,18 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/atomic.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/dll.h"
#include "libc/runtime/runtime.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
#include "third_party/dlmalloc/dlmalloc.h"
/**
* Releases memory of detached threads that have terminated.
*/
void pthread_decimate_np(void) {
bool empty;
struct Dll *e;
struct PosixThread *pt;
enum PosixThreadStatus status;
@ -46,9 +45,5 @@ StartOver:
goto StartOver;
}
}
empty = dll_is_empty(_pthread_list);
pthread_spin_unlock(&_pthread_lock);
if (empty) {
dlmalloc_trim(0);
}
}

View file

@ -34,7 +34,6 @@ LIBC_THREAD_A_DIRECTDEPS = \
LIBC_STR \
LIBC_SYSV \
LIBC_SYSV_CALLS \
THIRD_PARTY_DLMALLOC \
THIRD_PARTY_NSYNC \
THIRD_PARTY_NSYNC_MEM

View file

@ -44,9 +44,15 @@ extern unsigned __tls_index;
#ifdef __x86_64__
extern bool __tls_enabled;
#define __tls_enabled_set(x) __tls_enabled = x
#else
#define __tls_enabled true
#elif defined(__aarch64__)
#define __tls_enabled \
({ \
register struct CosmoTib *_t asm("x28"); \
!!_t; \
})
#define __tls_enabled_set(x) (void)0
#else
#error "unsupported architecture"
#endif
void __require_tls(void);

View file

@ -21,6 +21,7 @@
#include "libc/calls/calls.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/kprintf.h"
#include "libc/mem/gc.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/nexgen32e.h"
@ -29,7 +30,6 @@
#include "libc/testlib/testlib.h"
#include "libc/thread/thread.h"
#include "libc/thread/thread2.h"
#ifdef __x86_64__
int pfds[2];
pthread_cond_t cv;
@ -229,12 +229,14 @@ void *CpuBoundWorker(void *arg) {
(void)wontleak2;
ASSERT_EQ(0, pthread_setspecific(key, (void *)31337));
ASSERT_EQ(0, pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0));
#ifdef __x86_64__
for (;;) {
#ifdef __x86_64__
TortureStack();
#else
CheckStackIsAligned();
#endif
is_in_infinite_loop = true;
}
#endif
pthread_cleanup_pop(1);
free(wouldleak);
return 0;
@ -282,5 +284,3 @@ TEST(pthread_cancel, self_asynchronous_takesImmediateEffect) {
ASSERT_SYS(0, 0, close(pfds[1]));
ASSERT_SYS(0, 0, close(pfds[0]));
}
#endif /* __x86_64__ */

View file

@ -204,7 +204,6 @@
"__vector_size__"
"__ms_abi__"
"__sysv_abi__"
"systemfive"
"__mode__"
"__seg_fs"
"__seg_gs"))