mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-12 05:59:10 +00:00
Make improvements
- Document redbean's argon2 module - Fix regressions in cthreads library - Make testlib work better with threads - Give the cthreads library lots of love - Remove some of the stdio assembly code - Implement getloadavg() across platforms - Code size optimizations for errnos, etc. - Only check for signals in main thread on Windows - Make errnos for dup2 / dup3 consistent with posix This change also fixes a bug in the argon2 module, where the NUL terminator was being included in the hash encoded ascii string. This shouldn't require any database migrations to folks who found this module and productionized it, since the argon2 library treats it as a c string.
This commit is contained in:
parent
cb67223051
commit
de5de19004
234 changed files with 1728 additions and 1993 deletions
|
@ -23,13 +23,16 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/nexgen32e/threaded.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/thread.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/clone.h"
|
||||
#include "libc/sysv/consts/futex.h"
|
||||
#include "libc/sysv/consts/nr.h"
|
||||
#include "libc/sysv/consts/nrlinux.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
@ -121,7 +124,7 @@ static textwindows int CloneWindows(int (*func)(void *), char *stk,
|
|||
wt->func = func;
|
||||
wt->arg = arg;
|
||||
wt->tls = flags & CLONE_SETTLS ? tls : 0;
|
||||
if ((h = CreateThread(0, 0, (void *)WinThreadEntry, wt, 0, &wt->utid))) {
|
||||
if ((h = CreateThread(0, 4096, (void *)WinThreadEntry, wt, 0, &wt->utid))) {
|
||||
CloseHandle(h);
|
||||
return wt->tid;
|
||||
} else {
|
||||
|
@ -134,8 +137,7 @@ static textwindows int CloneWindows(int (*func)(void *), char *stk,
|
|||
|
||||
void XnuThreadThunk(void *pthread, int machport, void *(*func)(void *),
|
||||
void *arg, intptr_t *stack, unsigned xnuflags);
|
||||
asm(".local\tXnuThreadThunk\n"
|
||||
"XnuThreadThunk:\n\t"
|
||||
asm("XnuThreadThunk:\n\t"
|
||||
"xor\t%ebp,%ebp\n\t"
|
||||
"mov\t%r8,%rsp\n\t"
|
||||
"and\t$-16,%rsp\n\t"
|
||||
|
@ -168,7 +170,7 @@ XnuThreadMain(void *pthread, int tid, int (*func)(void *arg), void *arg,
|
|||
// %r10 = uint32_t sem);
|
||||
asm volatile("movl\t$0,%0\n\t" // *wt->ztid = 0
|
||||
"xor\t%%r10d,%%r10d\n\t" // sem = 0
|
||||
"syscall\n\t" // _Exit1()
|
||||
"syscall\n\t" // __bsdthread_terminate()
|
||||
"ud2"
|
||||
: "=m"(*wt->ztid)
|
||||
: "a"(0x2000000 | 361), "D"(0), "S"(0), "d"(0)
|
||||
|
@ -218,7 +220,7 @@ static wontreturn void FreebsdThreadMain(void *p) {
|
|||
// we no longer use the stack after this point
|
||||
// void thr_exit(%rdi = long *state);
|
||||
asm volatile("movl\t$0,%0\n\t" // *wt->ztid = 0
|
||||
"syscall" // _Exit1()
|
||||
"syscall" // thr_exit()
|
||||
: "=m"(*wt->ztid)
|
||||
: "a"(431), "D"(0)
|
||||
: "rcx", "r11", "memory");
|
||||
|
@ -294,11 +296,14 @@ OpenbsdThreadMain(struct CloneArgs *wt) {
|
|||
// although ideally there should be a better solution.
|
||||
//
|
||||
// void __threxit(%rdi = int32_t *notdead);
|
||||
asm volatile("mov\t%3,%%rsp\n\t"
|
||||
"movl\t$0,%0\n\t" // *wt->ztid = 0
|
||||
"syscall" // _Exit1()
|
||||
asm volatile("mov\t%2,%%rsp\n\t"
|
||||
"movl\t$0,(%%rdi)\n\t" // *wt->ztid = 0
|
||||
"syscall\n\t" // futex()
|
||||
"mov\t$302,%%eax\n\t" // __threxit()
|
||||
"syscall"
|
||||
: "=m"(*wt->ztid)
|
||||
: "a"(302), "D"(0), "r"(wt->pstack)
|
||||
: "a"(83), "m"(wt->pstack), "D"(wt->ztid), "S"(FUTEX_WAKE),
|
||||
"d"(INT_MAX)
|
||||
: "rcx", "r11", "memory");
|
||||
unreachable;
|
||||
}
|
||||
|
@ -337,7 +342,7 @@ static wontreturn void NetbsdThreadMain(void *arg, int (*func)(void *arg),
|
|||
// we no longer use the stack after this point
|
||||
// %eax = int __lwp_exit(void);
|
||||
asm volatile("movl\t$0,%2\n\t" // *wt->ztid = 0
|
||||
"syscall\n\t" // _Exit1()
|
||||
"syscall\n\t" // __lwp_exit()
|
||||
"ud2"
|
||||
: "=a"(ax), "=d"(dx), "=m"(*ztid)
|
||||
: "0"(310)
|
||||
|
@ -504,7 +509,7 @@ int sys_clone_linux(int flags, char *stk, int *ptid, int *ctid, void *tls,
|
|||
*/
|
||||
int clone(int (*func)(void *), void *stk, size_t stksz, int flags, void *arg,
|
||||
int *ptid, void *tls, size_t tlssz, int *ctid) {
|
||||
int rc;
|
||||
int rc, maintid;
|
||||
struct CloneArgs *wt;
|
||||
|
||||
// transition program to threaded state
|
||||
|
@ -517,13 +522,14 @@ int clone(int (*func)(void *), void *stk, size_t stksz, int flags, void *arg,
|
|||
STRACE("clone() tls/non-tls mixed order");
|
||||
return einval();
|
||||
}
|
||||
maintid = gettid();
|
||||
__initialize_tls(tibdefault);
|
||||
*(int *)((char *)tibdefault + 0x38) = gettid();
|
||||
*(int *)((char *)tibdefault + 0x38) = maintid;
|
||||
*(int *)((char *)tibdefault + 0x3c) = __errno;
|
||||
__install_tls(tibdefault);
|
||||
__threaded = true;
|
||||
__threaded = maintid;
|
||||
} else if (flags & CLONE_THREAD) {
|
||||
__threaded = true;
|
||||
__threaded = gettid();
|
||||
}
|
||||
|
||||
if (IsAsan() &&
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
/*-*- 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 2021 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/assert.h"
|
||||
#include "libc/bits/popcnt.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/dll.h"
|
||||
#include "libc/nt/struct/systeminfo.h"
|
||||
#include "libc/nt/systeminfo.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
#define CTL_HW 6
|
||||
#define HW_NCPU 3
|
||||
#define HW_NCPUONLINE_OPENBSD 25
|
||||
#define HW_NCPUONLINE_NETBSD 16
|
||||
#define ALL_PROCESSOR_GROUPS 0xffff
|
||||
|
||||
static unsigned GetCpuCountLinux(void) {
|
||||
uint64_t s[16];
|
||||
unsigned i, c, n;
|
||||
if (!sched_getaffinity(0, sizeof(s), s)) {
|
||||
for (c = i = 0; i < ARRAYLEN(s); ++i) {
|
||||
c += popcnt(s[i]);
|
||||
}
|
||||
return c;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned GetCpuCountBsd(void) {
|
||||
size_t n;
|
||||
int c, cmd[2];
|
||||
n = sizeof(c);
|
||||
cmd[0] = CTL_HW;
|
||||
if (IsOpenbsd()) {
|
||||
cmd[1] = HW_NCPUONLINE_OPENBSD;
|
||||
} else if (IsNetbsd()) {
|
||||
cmd[1] = HW_NCPUONLINE_NETBSD;
|
||||
} else {
|
||||
cmd[1] = HW_NCPU;
|
||||
}
|
||||
if (!sysctl(cmd, 2, &c, &n, 0, 0)) {
|
||||
return c;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static textwindows unsigned GetCpuCountWindows(void) {
|
||||
struct NtSystemInfo si;
|
||||
uint32_t (*f)(uint16_t);
|
||||
if ((f = GetProcAddress(GetModuleHandle("KERNEL32"),
|
||||
"GetMaximumProcessorCount"))) {
|
||||
return f(ALL_PROCESSOR_GROUPS);
|
||||
} else {
|
||||
GetSystemInfo(&si);
|
||||
return si.dwNumberOfProcessors;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of CPUs in system.
|
||||
*
|
||||
* On Intel systems with HyperThreading this will return the number of
|
||||
* cores multiplied by two.
|
||||
*
|
||||
* @return cpu count or 0 if it couldn't be determined
|
||||
*/
|
||||
unsigned GetCpuCount(void) {
|
||||
if (!IsWindows()) {
|
||||
if (!IsBsd()) {
|
||||
return GetCpuCountLinux();
|
||||
} else {
|
||||
return GetCpuCountBsd();
|
||||
}
|
||||
} else {
|
||||
return GetCpuCountWindows();
|
||||
}
|
||||
}
|
|
@ -18,6 +18,13 @@ extern const char v_ntsubsystem[] __attribute__((__weak__));
|
|||
extern const uintptr_t __fini_array_end[] __attribute__((__weak__));
|
||||
extern const uintptr_t __fini_array_start[] __attribute__((__weak__));
|
||||
|
||||
extern unsigned char _tdata_start[];
|
||||
extern unsigned char _tdata_end[];
|
||||
extern unsigned char _tdata_size[];
|
||||
extern unsigned char _tbss_start[];
|
||||
extern unsigned char _tbss_end[];
|
||||
extern unsigned char _tls_size[];
|
||||
|
||||
void _init(void) hidden;
|
||||
void __restorewintty(void) hidden;
|
||||
void *__cxa_finalize(void *) hidden;
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
|
@ -84,6 +86,7 @@ static noasan inline bool OverlapsExistingMapping(char *p, size_t n) {
|
|||
}
|
||||
|
||||
static noasan bool ChooseMemoryInterval(int x, int n, int align, int *res) {
|
||||
// TODO: improve performance
|
||||
int i, start, end;
|
||||
assert(align > 0);
|
||||
if (_mmi.i) {
|
||||
|
@ -327,15 +330,7 @@ static noasan inline void *Mmap(void *addr, size_t size, int prot, int flags,
|
|||
return VIP(einval());
|
||||
}
|
||||
|
||||
// if size is a two power then automap will use it as alignment
|
||||
if (IS2POW(size)) {
|
||||
a = size >> 16;
|
||||
if (!a) {
|
||||
a = 1;
|
||||
}
|
||||
} else {
|
||||
a = 1;
|
||||
}
|
||||
a = max(1, rounddown2pow(size) >> 16);
|
||||
|
||||
f = (flags & ~MAP_FIXED_NOREPLACE) | MAP_FIXED;
|
||||
if (flags & MAP_FIXED) {
|
||||
|
|
|
@ -48,6 +48,8 @@ unsigned long getauxval(unsigned long);
|
|||
void *mapanon(size_t) attributeallocsize((1));
|
||||
int setjmp(jmp_buf) libcesque returnstwice paramsnonnull();
|
||||
void longjmp(jmp_buf, int) libcesque wontreturn paramsnonnull();
|
||||
axdx_t setlongerjmp(jmp_buf) libcesque returnstwice paramsnonnull();
|
||||
void longerjmp(jmp_buf, intptr_t) libcesque wontreturn paramsnonnull();
|
||||
int _setjmp(jmp_buf) libcesque returnstwice paramsnonnull();
|
||||
void _longjmp(jmp_buf, int) libcesque wontreturn paramsnonnull();
|
||||
void exit(int) wontreturn;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue