mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Make improvements
- Improve compatibility with Blink virtual machine - Add non-POSIX APIs for joining threads and signal masks - Never ever use anything except 32-bit integers for atomics - Add some `#undef` statements to workaround `ctags` problems
This commit is contained in:
parent
b46ac13504
commit
f2af97711b
114 changed files with 902 additions and 363 deletions
|
@ -715,7 +715,7 @@ ASSERT(IS2POW(ape_stack_memsz),
|
|||
"ape_stack_memsz must be a two power");
|
||||
|
||||
ASSERT(ape_stack_vaddr % ape_stack_memsz == 0,
|
||||
"ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000040000 - ape_stack_memsz);");
|
||||
"ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000040000 & -ape_stack_memsz);");
|
||||
|
||||
ASSERT(ALIGNOF(.tdata) <= TLS_ALIGNMENT && ALIGNOF(.tbss) <= TLS_ALIGNMENT,
|
||||
"_Thread_local _Alignof can't exceed TLS_ALIGNMENT");
|
||||
|
|
|
@ -240,6 +240,8 @@ static bool ShouldUseSpinNanosleep(int clock, int flags,
|
|||
errno_t clock_nanosleep(int clock, int flags, const struct timespec *req,
|
||||
struct timespec *rem) {
|
||||
int rc;
|
||||
LOCKTRACE("clock_nanosleep(%s, %s, %s) → ...", DescribeClockName(clock),
|
||||
DescribeSleepFlags(flags), DescribeTimespec(0, req));
|
||||
if (IsMetal()) {
|
||||
rc = ENOSYS;
|
||||
} else if (!req || (IsAsan() && (!__asan_is_valid_timespec(req) ||
|
||||
|
@ -259,7 +261,7 @@ errno_t clock_nanosleep(int clock, int flags, const struct timespec *req,
|
|||
if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
|
||||
STRACE("clock_nanosleep(%s, %s, %s, [%s]) → %s", DescribeClockName(clock),
|
||||
DescribeSleepFlags(flags), DescribeTimespec(0, req),
|
||||
DescribeTimespec(rc, rem), DescribeErrnoResult(rc));
|
||||
DescribeTimespec(rc, rem), DescribeErrno(rc));
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int sys_fexecve(int, char *const[], char *const[]);
|
||||
|
||||
/**
|
||||
* Executes binary executable at file descriptor.
|
||||
*
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "libc/errno.h"
|
||||
#include "libc/intrin/promises.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/nexgen32e/vendor.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -238,8 +239,10 @@
|
|||
int pledge(const char *promises, const char *execpromises) {
|
||||
int e, rc;
|
||||
unsigned long ipromises, iexecpromises;
|
||||
if (!ParsePromises(promises, &ipromises) &&
|
||||
!ParsePromises(execpromises, &iexecpromises)) {
|
||||
if (IsGenuineCosmo()) {
|
||||
rc = 0; // blink doesn't support seccomp
|
||||
} else if (!ParsePromises(promises, &ipromises) &&
|
||||
!ParsePromises(execpromises, &iexecpromises)) {
|
||||
if (IsLinux()) {
|
||||
// copy exec and execnative from promises to execpromises
|
||||
iexecpromises = ~(~iexecpromises | (~ipromises & (1ul << PROMISE_EXEC)));
|
||||
|
|
|
@ -37,6 +37,7 @@ i32 sys_dup(i32) _Hide;
|
|||
i32 sys_dup2(i32, i32) _Hide;
|
||||
i32 sys_dup3(i32, i32, i32) _Hide;
|
||||
i32 sys_execve(const char *, char *const[], char *const[]) _Hide;
|
||||
i32 sys_execveat(i32, const char *, char *const[], char *const[], i32) _Hide;
|
||||
i32 sys_faccessat(i32, const char *, i32, u32) _Hide;
|
||||
i32 sys_faccessat2(i32, const char *, i32, u32) _Hide;
|
||||
i32 sys_fadvise(i32, i64, i64, i32) _Hide;
|
||||
|
@ -47,6 +48,7 @@ i32 sys_fchown(i64, u32, u32) _Hide;
|
|||
i32 sys_fchownat(i32, const char *, u32, u32, u32) _Hide;
|
||||
i32 sys_fcntl(i32, i32, u64, i32 (*)(i32, i32, ...)) _Hide;
|
||||
i32 sys_fdatasync(i32) _Hide;
|
||||
i32 sys_fexecve(i32, char *const[], char *const[]) _Hide;
|
||||
i32 sys_flock(i32, i32) _Hide;
|
||||
i32 sys_fork(void) _Hide;
|
||||
i32 sys_fsync(i32) _Hide;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "libc/fmt/conv.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nexgen32e/vendor.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
|
@ -353,7 +354,9 @@ int sys_unveil_linux(const char *path, const char *permissions) {
|
|||
int unveil(const char *path, const char *permissions) {
|
||||
int e, rc;
|
||||
e = errno;
|
||||
if (IsLinux()) {
|
||||
if (IsGenuineCosmo()) {
|
||||
rc = 0; // blink doesn't support landlock
|
||||
} else if (IsLinux()) {
|
||||
rc = sys_unveil_linux(path, permissions);
|
||||
} else {
|
||||
rc = sys_unveil(path, permissions);
|
||||
|
|
|
@ -159,7 +159,7 @@ static struct AsanMorgue {
|
|||
|
||||
static bool __asan_once(void) {
|
||||
bool want = false;
|
||||
static _Atomic(bool) once;
|
||||
static atomic_int once;
|
||||
return atomic_compare_exchange_strong_explicit(
|
||||
&once, &want, true, memory_order_relaxed, memory_order_relaxed);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
|
||||
const char *(DescribeArchPrctlCode)(char buf[12], int x) {
|
||||
#ifdef DescribeArchPrctlCode
|
||||
#undef DescribeArchPrctlCode
|
||||
#endif
|
||||
|
||||
const char *DescribeArchPrctlCode(char buf[12], int x) {
|
||||
if (x == ARCH_SET_FS) return "ARCH_SET_FS";
|
||||
if (x == ARCH_GET_FS) return "ARCH_GET_FS";
|
||||
if (x == ARCH_SET_GS) return "ARCH_SET_GS";
|
||||
|
|
|
@ -20,11 +20,15 @@
|
|||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/nexgen32e/stackframe.h"
|
||||
|
||||
#ifdef DescribeBacktrace
|
||||
#undef DescribeBacktrace
|
||||
#endif
|
||||
|
||||
#define N 64
|
||||
|
||||
#define append(...) o += ksnprintf(buf + o, N - o, __VA_ARGS__)
|
||||
|
||||
const char *(DescribeBacktrace)(char buf[N], struct StackFrame *fr) {
|
||||
const char *DescribeBacktrace(char buf[N], struct StackFrame *fr) {
|
||||
int o = 0;
|
||||
bool gotsome = false;
|
||||
while (fr) {
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/cap.h"
|
||||
|
||||
#ifdef DescribeCapability
|
||||
#undef DescribeCapability
|
||||
#endif
|
||||
|
||||
static const struct thatispacked {
|
||||
unsigned char x;
|
||||
const char *s;
|
||||
|
@ -69,7 +73,7 @@ static const struct thatispacked {
|
|||
{CAP_CHECKPOINT_RESTORE, "CHECKPOINT_RESTORE"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeCapability)(char buf[32], int x) {
|
||||
const char *DescribeCapability(char buf[32], int x) {
|
||||
int i;
|
||||
for (i = 0; i < ARRAYLEN(kCapabilityName); ++i) {
|
||||
if (kCapabilityName[i].x == x) {
|
||||
|
|
|
@ -19,9 +19,13 @@
|
|||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
|
||||
#ifdef DescribeClockName
|
||||
#undef DescribeClockName
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Describes clock_gettime() clock argument.
|
||||
*/
|
||||
const char *(DescribeClockName)(char buf[32], int x) {
|
||||
const char *DescribeClockName(char buf[32], int x) {
|
||||
return DescribeMagnum(buf, kClockNames, "CLOCK_", x);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
|
||||
const char *(DescribeDirfd)(char buf[12], int dirfd) {
|
||||
#ifdef DescribeDirfd
|
||||
#undef DescribeDirfd
|
||||
#endif
|
||||
|
||||
const char *DescribeDirfd(char buf[12], int dirfd) {
|
||||
if (dirfd == AT_FDCWD) return "AT_FDCWD";
|
||||
FormatInt32(buf, dirfd);
|
||||
return buf;
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
#include "libc/nt/enum/processaccess.h"
|
||||
#include "libc/sysv/consts/dn.h"
|
||||
|
||||
#ifdef DescribeDnotifyFlags
|
||||
#undef DescribeDnotifyFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kDnotifyFlags[] = {
|
||||
{DN_ACCESS, "ACCESS"}, //
|
||||
{DN_MODIFY, "MODIFY"}, //
|
||||
|
@ -31,7 +35,7 @@ static const struct DescribeFlags kDnotifyFlags[] = {
|
|||
{DN_MULTISHOT, "MULTISHOT"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeDnotifyFlags)(char buf[80], int x) {
|
||||
const char *DescribeDnotifyFlags(char buf[80], int x) {
|
||||
return DescribeFlags(buf, 80, kDnotifyFlags, ARRAYLEN(kDnotifyFlags), "DN_",
|
||||
x);
|
||||
}
|
||||
|
|
|
@ -20,12 +20,22 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
const char *(DescribeErrnoResult)(char buf[12], int ax) {
|
||||
#ifdef DescribeErrno
|
||||
#undef DescribeErrno
|
||||
#endif
|
||||
|
||||
const char *DescribeErrno(char buf[20], int ax) {
|
||||
char *p = buf;
|
||||
const char *s;
|
||||
if (ax > -4095u && (s = _strerrno(-ax))) {
|
||||
if (ax < 0) {
|
||||
*p++ = '-';
|
||||
ax = -ax;
|
||||
}
|
||||
if ((s = _strerrno(ax))) {
|
||||
stpcpy(p, s);
|
||||
return s;
|
||||
} else {
|
||||
FormatInt32(buf, ax);
|
||||
FormatInt32(p, ax);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,11 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
const char *(DescribeFcntlCmd)(char buf[20], int x) {
|
||||
#ifdef DescribeFcntlCmd
|
||||
#undef DescribeFcntlCmd
|
||||
#endif
|
||||
|
||||
const char *DescribeFcntlCmd(char buf[20], int x) {
|
||||
const char *s;
|
||||
if (x >= 0 && (s = GetMagnumStr(kFcntlCmds, x))) {
|
||||
buf[0] = 'F';
|
||||
|
|
|
@ -17,8 +17,7 @@ const char *DescribeCapability(char[32], int);
|
|||
const char *DescribeClockName(char[32], int);
|
||||
const char *DescribeDirfd(char[12], int);
|
||||
const char *DescribeDnotifyFlags(char[80], int);
|
||||
const char *DescribeErrno(char[12], int);
|
||||
const char *DescribeErrnoResult(char[12], int);
|
||||
const char *DescribeErrno(char[20], int);
|
||||
const char *DescribeFcntlCmd(char[20], int);
|
||||
const char *DescribeFlockType(char[12], int);
|
||||
const char *DescribeFrame(char[32], int);
|
||||
|
@ -71,8 +70,7 @@ const char *DescribeWhichPrio(char[12], int);
|
|||
#define DescribeClockName(x) DescribeClockName(alloca(32), x)
|
||||
#define DescribeDirfd(x) DescribeDirfd(alloca(12), x)
|
||||
#define DescribeDnotifyFlags(x) DescribeDnotifyFlags(alloca(80), x)
|
||||
#define DescribeErrno(x) DescribeErrno(alloca(12), x)
|
||||
#define DescribeErrnoResult(x) DescribeErrnoResult(alloca(12), x)
|
||||
#define DescribeErrno(x) DescribeErrno(alloca(20), x)
|
||||
#define DescribeFcntlCmd(x) DescribeFcntlCmd(alloca(20), x)
|
||||
#define DescribeFlockType(x) DescribeFlockType(alloca(12), x)
|
||||
#define DescribeFrame(x) DescribeFrame(alloca(32), x)
|
||||
|
|
|
@ -24,11 +24,15 @@
|
|||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/sysv/consts/f.h"
|
||||
|
||||
#ifdef DescribeFlock
|
||||
#undef DescribeFlock
|
||||
#endif
|
||||
|
||||
#define N 300
|
||||
|
||||
#define append(...) o += ksnprintf(buf + o, N - o, __VA_ARGS__)
|
||||
|
||||
const char *(DescribeFlock)(char buf[N], int cmd, const struct flock *l) {
|
||||
const char *DescribeFlock(char buf[N], int cmd, const struct flock *l) {
|
||||
int o = 0;
|
||||
|
||||
if (!l) return "NULL";
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/sysv/consts/f.h"
|
||||
|
||||
const char *(DescribeFlockType)(char buf[12], int x) {
|
||||
#ifdef DescribeFlockType
|
||||
#undef DescribeFlockType
|
||||
#endif
|
||||
|
||||
const char *DescribeFlockType(char buf[12], int x) {
|
||||
if (x == F_RDLCK) return "F_RDLCK";
|
||||
if (x == F_WRLCK) return "F_WRLCK";
|
||||
if (x == F_UNLCK) return "F_UNLCK";
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/winargs.internal.h"
|
||||
|
||||
#ifdef DescribeFrame
|
||||
#undef DescribeFrame
|
||||
#endif
|
||||
|
||||
#define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16)
|
||||
#define UNSHADOW(x) ((int64_t)(MAX(0, (x)-0x7fff8000)) << 3)
|
||||
#define FRAME(x) ((int)((x) >> 16))
|
||||
|
@ -74,7 +78,7 @@ static const char *GetFrameName(int x) {
|
|||
}
|
||||
}
|
||||
|
||||
const char *(DescribeFrame)(char buf[32], int x) {
|
||||
const char *DescribeFrame(char buf[32], int x) {
|
||||
char *p;
|
||||
if (IsShadowFrame(x)) {
|
||||
ksnprintf(buf, 32, "%s %s %.8x", GetFrameName(x),
|
||||
|
|
|
@ -21,7 +21,11 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/futex.h"
|
||||
|
||||
const char *(DescribeFutexOp)(char buf[64], int x) {
|
||||
#ifdef DescribeFutexOp
|
||||
#undef DescribeFutexOp
|
||||
#endif
|
||||
|
||||
const char *DescribeFutexOp(char buf[64], int x) {
|
||||
|
||||
bool priv = false;
|
||||
if (x & FUTEX_PRIVATE_FLAG) {
|
||||
|
|
|
@ -24,10 +24,14 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#ifdef DescribeGidList
|
||||
#undef DescribeGidList
|
||||
#endif
|
||||
|
||||
#define N 128
|
||||
|
||||
const char *(DescribeGidList)(char buf[N], int rc, int size,
|
||||
const uint32_t list[]) {
|
||||
const char *DescribeGidList(char buf[N], int rc, int size,
|
||||
const uint32_t list[]) {
|
||||
if ((rc == -1) || (size < 0)) return "n/a";
|
||||
if (!size) return "{}";
|
||||
if (!list) return "NULL";
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
|
||||
const char *(DescribeHow)(char buf[12], int how) {
|
||||
#ifdef DescribeHow
|
||||
#undef DescribeHow
|
||||
#endif
|
||||
|
||||
const char *DescribeHow(char buf[12], int how) {
|
||||
if (how == SIG_BLOCK) return "SIG_BLOCK";
|
||||
if (how == SIG_UNBLOCK) return "SIG_UNBLOCK";
|
||||
if (how == SIG_SETMASK) return "SIG_SETMASK";
|
||||
|
|
|
@ -24,12 +24,16 @@
|
|||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
#ifdef DescribeIovec
|
||||
#undef DescribeIovec
|
||||
#endif
|
||||
|
||||
#define N 300
|
||||
|
||||
#define append(...) o += ksnprintf(buf + o, N - o, __VA_ARGS__)
|
||||
|
||||
const char *(DescribeIovec)(char buf[N], ssize_t rc, const struct iovec *iov,
|
||||
int iovlen) {
|
||||
const char *DescribeIovec(char buf[N], ssize_t rc, const struct iovec *iov,
|
||||
int iovlen) {
|
||||
const char *d;
|
||||
int i, j, o = 0;
|
||||
|
||||
|
|
|
@ -22,7 +22,11 @@
|
|||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
|
||||
const char *(DescribeMapFlags)(char buf[64], int x) {
|
||||
#ifdef DescribeMapFlags
|
||||
#undef DescribeMapFlags
|
||||
#endif
|
||||
|
||||
const char *DescribeMapFlags(char buf[64], int x) {
|
||||
const struct DescribeFlags kMapFlags[] = {
|
||||
{MAP_STACK, "STACK"}, // order matters
|
||||
{MAP_PRIVATE, "PRIVATE"}, //
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
|
||||
#ifdef DescribeMapping
|
||||
#undef DescribeMapping
|
||||
#endif
|
||||
|
||||
static char DescribeMapType(int flags) {
|
||||
switch (flags & MAP_TYPE) {
|
||||
case MAP_FILE:
|
||||
|
@ -44,7 +48,7 @@ char *DescribeProt(char p[4], int prot) {
|
|||
return p;
|
||||
}
|
||||
|
||||
const char *(DescribeMapping)(char p[8], int prot, int flags) {
|
||||
const char *DescribeMapping(char p[8], int prot, int flags) {
|
||||
/* asan runtime depends on this function */
|
||||
DescribeProt(p, prot);
|
||||
p[3] = DescribeMapType(flags);
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/consolemodeflags.h"
|
||||
|
||||
#ifdef DescribeNtConsoleInFlags
|
||||
#undef DescribeNtConsoleInFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kConsoleModeInputFlags[] = {
|
||||
{kNtEnableProcessedInput, "ProcessedInput"}, //
|
||||
{kNtEnableLineInput, "LineInput"}, //
|
||||
|
@ -33,7 +37,7 @@ static const struct DescribeFlags kConsoleModeInputFlags[] = {
|
|||
{kNtEnableVirtualTerminalInput, "VirtualTerminalInput"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeNtConsoleInFlags)(char buf[256], uint32_t x) {
|
||||
const char *DescribeNtConsoleInFlags(char buf[256], uint32_t x) {
|
||||
return DescribeFlags(buf, 256, kConsoleModeInputFlags,
|
||||
ARRAYLEN(kConsoleModeInputFlags), "kNtEnable", x);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/consolemodeflags.h"
|
||||
|
||||
#ifdef DescribeNtConsoleOutFlags
|
||||
#undef DescribeNtConsoleOutFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kConsoleModeOutputFlags[] = {
|
||||
{kNtEnableProcessedOutput, "EnableProcessedOutput"}, //
|
||||
{kNtEnableWrapAtEolOutput, "EnableWrapAtEolOutput"}, //
|
||||
|
@ -28,7 +32,7 @@ static const struct DescribeFlags kConsoleModeOutputFlags[] = {
|
|||
{kNtEnableLvbGridWorldwide, "EnableLvbGridWorldwide"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeNtConsoleOutFlags)(char buf[128], uint32_t x) {
|
||||
const char *DescribeNtConsoleOutFlags(char buf[128], uint32_t x) {
|
||||
return DescribeFlags(buf, 128, kConsoleModeOutputFlags,
|
||||
ARRAYLEN(kConsoleModeOutputFlags), "kNt", x);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
#include "libc/nt/enum/accessmask.h"
|
||||
#include "libc/nt/enum/filesharemode.h"
|
||||
|
||||
#ifdef DescribeNtFileAccessFlags
|
||||
#undef DescribeNtFileAccessFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kFileAccessflags[] = {
|
||||
{kNtFileAllAccess, "FileAllAccess"}, // order matters
|
||||
{kNtFileGenericRead, "FileGenericRead"}, // order matters
|
||||
|
@ -63,7 +67,7 @@ static const struct DescribeFlags kFileAccessflags[] = {
|
|||
{kNtTokenAdjustSessionid, "TokenAdjustSessionid"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeNtFileAccessFlags)(char buf[512], uint32_t x) {
|
||||
const char *DescribeNtFileAccessFlags(char buf[512], uint32_t x) {
|
||||
return DescribeFlags(buf, 512, kFileAccessflags, ARRAYLEN(kFileAccessflags),
|
||||
"kNt", x);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
#ifdef DescribeNtFileFlagAttr
|
||||
#undef DescribeNtFileFlagAttr
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kFileFlags[] = {
|
||||
{kNtFileAttributeReadonly, "AttributeReadonly"}, //
|
||||
{kNtFileAttributeHidden, "AttributeHidden"}, //
|
||||
|
@ -50,7 +54,7 @@ static const struct DescribeFlags kFileFlags[] = {
|
|||
{kNtFileFlagFirstPipeInstance, "FlagFirstPipeInstance"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeNtFileFlagAttr)(char buf[256], uint32_t x) {
|
||||
const char *DescribeNtFileFlagAttr(char buf[256], uint32_t x) {
|
||||
if (x == -1u) return "-1u";
|
||||
return DescribeFlags(buf, 256, kFileFlags, ARRAYLEN(kFileFlags), "kNtFile",
|
||||
x);
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/filemapflags.h"
|
||||
|
||||
#ifdef DescribeNtFileMapFlags
|
||||
#undef DescribeNtFileMapFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kFileMapFlags[] = {
|
||||
{kNtFileMapCopy, "Copy"}, //
|
||||
{kNtFileMapWrite, "Write"}, //
|
||||
|
@ -30,7 +34,7 @@ static const struct DescribeFlags kFileMapFlags[] = {
|
|||
{kNtFileMapLargePages, "LargePages"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeNtFileMapFlags)(char buf[64], uint32_t x) {
|
||||
const char *DescribeNtFileMapFlags(char buf[64], uint32_t x) {
|
||||
return DescribeFlags(buf, 64, kFileMapFlags, ARRAYLEN(kFileMapFlags),
|
||||
"kNtFileMap", x);
|
||||
}
|
||||
|
|
|
@ -20,13 +20,17 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/filesharemode.h"
|
||||
|
||||
#ifdef DescribeNtFileShareFlags
|
||||
#undef DescribeNtFileShareFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kFileShareflags[] = {
|
||||
{kNtFileShareRead, "Read"}, //
|
||||
{kNtFileShareWrite, "Write"}, //
|
||||
{kNtFileShareDelete, "Delete"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeNtFileShareFlags)(char buf[64], uint32_t x) {
|
||||
const char *DescribeNtFileShareFlags(char buf[64], uint32_t x) {
|
||||
return DescribeFlags(buf, 64, kFileShareflags, ARRAYLEN(kFileShareflags),
|
||||
"kNtFileShare", x);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
#include "libc/nt/enum/filetype.h"
|
||||
#include "libc/sysv/consts/mremap.h"
|
||||
|
||||
#ifdef DescribeNtFiletypeFlags
|
||||
#undef DescribeNtFiletypeFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kFiletypeFlags[] = {
|
||||
{kNtFileTypeRemote, "Remote"}, //
|
||||
{kNtFileTypePipe, "Pipe"}, // order matters
|
||||
|
@ -28,7 +32,7 @@ static const struct DescribeFlags kFiletypeFlags[] = {
|
|||
{kNtFileTypeChar, "Char"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeNtFiletypeFlags)(char buf[64], uint32_t x) {
|
||||
const char *DescribeNtFiletypeFlags(char buf[64], uint32_t x) {
|
||||
return DescribeFlags(buf, 64, kFiletypeFlags, ARRAYLEN(kFiletypeFlags),
|
||||
"kNtFileType", x);
|
||||
}
|
||||
|
|
|
@ -20,12 +20,16 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/filelockflags.h"
|
||||
|
||||
#ifdef DescribeNtLockFileFlags
|
||||
#undef DescribeNtLockFileFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kNtLockFileFlags[] = {
|
||||
{kNtLockfileFailImmediately, "FailImmediately"}, //
|
||||
{kNtLockfileExclusiveLock, "ExclusiveLock"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeNtLockFileFlags)(char buf[64], uint32_t x) {
|
||||
const char *DescribeNtLockFileFlags(char buf[64], uint32_t x) {
|
||||
return DescribeFlags(buf, 64, kNtLockFileFlags, ARRAYLEN(kNtLockFileFlags),
|
||||
"kNtLockfile", x);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/movefileexflags.h"
|
||||
|
||||
#ifdef DescribeNtMovFileInpFlags
|
||||
#undef DescribeNtMovFileInpFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kMoveFileInputFlags[] = {
|
||||
{kNtMovefileReplaceExisting, "ReplaceExisting"}, //
|
||||
{kNtMovefileCopyAllowed, "CopyAllowed"}, //
|
||||
|
@ -29,7 +33,7 @@ static const struct DescribeFlags kMoveFileInputFlags[] = {
|
|||
{kNtMovefileFailIfNotTrackable, "FailIfNotTrackable"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeNtMovFileInpFlags)(char buf[256], uint32_t x) {
|
||||
const char *DescribeNtMovFileInpFlags(char buf[256], uint32_t x) {
|
||||
return DescribeFlags(buf, 256, kMoveFileInputFlags,
|
||||
ARRAYLEN(kMoveFileInputFlags), "kNtMovefile", x);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/pageflags.h"
|
||||
|
||||
#ifdef DescribeNtPageFlags
|
||||
#undef DescribeNtPageFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kPageFlags[] = {
|
||||
{kNtPageNoaccess, "PageNoaccess"}, //
|
||||
{kNtPageReadonly, "PageReadonly"}, //
|
||||
|
@ -41,6 +45,6 @@ static const struct DescribeFlags kPageFlags[] = {
|
|||
{kNtSecWritecombine, "SecWritecombine"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeNtPageFlags)(char buf[64], uint32_t x) {
|
||||
const char *DescribeNtPageFlags(char buf[64], uint32_t x) {
|
||||
return DescribeFlags(buf, 64, kPageFlags, ARRAYLEN(kPageFlags), "kNt", x);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
#include "libc/nt/enum/filemapflags.h"
|
||||
#include "libc/nt/ipc.h"
|
||||
|
||||
#ifdef DescribeNtPipeModeFlags
|
||||
#undef DescribeNtPipeModeFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kPipeModeFlags[] = {
|
||||
{kNtPipeNowait, "Nowait"}, // 0x0000000001
|
||||
{kNtPipeReadmodeMessage, "ReadmodeMessage"}, // 0x0000000002
|
||||
|
@ -32,7 +36,7 @@ static const struct DescribeFlags kPipeModeFlags[] = {
|
|||
//{kNtPipeTypeByte, "TypeByte"}, // 0x00000000
|
||||
};
|
||||
|
||||
const char *(DescribeNtPipeModeFlags)(char buf[64], uint32_t x) {
|
||||
const char *DescribeNtPipeModeFlags(char buf[64], uint32_t x) {
|
||||
return DescribeFlags(buf, 64, kPipeModeFlags, ARRAYLEN(kPipeModeFlags),
|
||||
"kNtPipe", x);
|
||||
}
|
||||
|
|
|
@ -21,13 +21,17 @@
|
|||
#include "libc/nt/enum/filemapflags.h"
|
||||
#include "libc/nt/ipc.h"
|
||||
|
||||
#ifdef DescribeNtPipeOpenFlags
|
||||
#undef DescribeNtPipeOpenFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kPipeOpenFlags[] = {
|
||||
{kNtPipeAccessDuplex, "Duplex"}, // 0x00000003
|
||||
{kNtPipeAccessOutbound, "Outbound"}, // 0x00000002
|
||||
{kNtPipeAccessInbound, "Inbound"}, // 0x00000001
|
||||
};
|
||||
|
||||
const char *(DescribeNtPipeOpenFlags)(char buf[64], uint32_t x) {
|
||||
const char *DescribeNtPipeOpenFlags(char buf[64], uint32_t x) {
|
||||
return DescribeFlags(buf, 64, kPipeOpenFlags, ARRAYLEN(kPipeOpenFlags),
|
||||
"kNtPipeAccess", x);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/processaccess.h"
|
||||
|
||||
#ifdef DescribeNtProcAccessFlags
|
||||
#undef DescribeNtProcAccessFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kProcessAccessflags[] = {
|
||||
{kNtProcessAllAccess, "AllAccess"}, //
|
||||
{kNtProcessCreateProcess, "CreateProcess"}, //
|
||||
|
@ -37,7 +41,7 @@ static const struct DescribeFlags kProcessAccessflags[] = {
|
|||
{kNtProcessSynchronize, "Synchronize"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeNtProcAccessFlags)(char buf[256], uint32_t x) {
|
||||
const char *DescribeNtProcAccessFlags(char buf[256], uint32_t x) {
|
||||
return DescribeFlags(buf, 256, kProcessAccessflags,
|
||||
ARRAYLEN(kProcessAccessflags), "kNtProcess", x);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
#include "libc/nt/enum/startf.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
|
||||
#ifdef DescribeNtStartFlags
|
||||
#undef DescribeNtStartFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kNtStartFlags[] = {
|
||||
{kNtStartfUseshowwindow, "Useshowwindow"}, //
|
||||
{kNtStartfUsesize, "Usesize"}, //
|
||||
|
@ -38,7 +42,7 @@ static const struct DescribeFlags kNtStartFlags[] = {
|
|||
{kNtStartfUntrustedsource, "Untrustedsource"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeNtStartFlags)(char buf[128], uint32_t x) {
|
||||
const char *DescribeNtStartFlags(char buf[128], uint32_t x) {
|
||||
return DescribeFlags(buf, 128, kNtStartFlags, ARRAYLEN(kNtStartFlags),
|
||||
"kNtStartf", x);
|
||||
}
|
||||
|
|
|
@ -20,12 +20,16 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/symboliclink.h"
|
||||
|
||||
#ifdef DescribeNtSymlinkFlags
|
||||
#undef DescribeNtSymlinkFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kSymbolicLinkflags[] = {
|
||||
{kNtSymbolicLinkFlagDirectory, "Directory"}, //
|
||||
{kNtSymbolicLinkFlagAllowUnprivilegedCreate, "AllowUnprivilegedCreate"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeNtSymlinkFlags)(char buf[64], uint32_t x) {
|
||||
const char *DescribeNtSymlinkFlags(char buf[64], uint32_t x) {
|
||||
return DescribeFlags(buf, 64, kSymbolicLinkflags,
|
||||
ARRAYLEN(kSymbolicLinkflags), "kNtSymbolicLinkFlag", x);
|
||||
}
|
||||
|
|
|
@ -23,12 +23,16 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
|
||||
#ifdef DescribeOpenFlags
|
||||
#undef DescribeOpenFlags
|
||||
#endif
|
||||
|
||||
#define N (PAGESIZE / 2 / sizeof(struct DescribeFlags))
|
||||
|
||||
/**
|
||||
* Describes clock_gettime() clock argument.
|
||||
*/
|
||||
const char *(DescribeOpenFlags)(char buf[128], int x) {
|
||||
const char *DescribeOpenFlags(char buf[128], int x) {
|
||||
char *s;
|
||||
int i, n;
|
||||
struct DescribeFlags d[N];
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
#include "libc/nt/enum/filesharemode.h"
|
||||
#include "libc/sysv/consts/personality.h"
|
||||
|
||||
#ifdef DescribePersonalityFlags
|
||||
#undef DescribePersonalityFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kPersonalityFlags[] = {
|
||||
{ADDR_COMPAT_LAYOUT, "ADDR_COMPAT_LAYOUT"}, //
|
||||
{READ_IMPLIES_EXEC, "READ_IMPLIES_EXEC"}, //
|
||||
|
@ -36,7 +40,7 @@ static const struct DescribeFlags kPersonalityFlags[] = {
|
|||
{UNAME26, "UNAME26"}, //
|
||||
};
|
||||
|
||||
const char *(DescribePersonalityFlags)(char buf[128], int x) {
|
||||
const char *DescribePersonalityFlags(char buf[128], int x) {
|
||||
return DescribeFlags(buf, 128, kPersonalityFlags, ARRAYLEN(kPersonalityFlags),
|
||||
"", x);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,11 @@
|
|||
#include "libc/nt/enum/filemapflags.h"
|
||||
#include "libc/sysv/consts/poll.h"
|
||||
|
||||
const char *(DescribePollFlags)(char buf[64], int x) {
|
||||
#ifdef DescribePollFlags
|
||||
#undef DescribePollFlags
|
||||
#endif
|
||||
|
||||
const char *DescribePollFlags(char buf[64], int x) {
|
||||
const struct DescribeFlags kPollFlags[] = {
|
||||
{POLLIN, "IN"}, // order matters
|
||||
{POLLOUT, "OUT"}, // order matters
|
||||
|
|
|
@ -20,12 +20,16 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
|
||||
#ifdef DescribeProtFlags
|
||||
#undef DescribeProtFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kProtFlags[] = {
|
||||
{PROT_READ, "READ"}, //
|
||||
{PROT_WRITE, "WRITE"}, //
|
||||
{PROT_EXEC, "EXEC"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeProtFlags)(char buf[48], int x) {
|
||||
const char *DescribeProtFlags(char buf[48], int x) {
|
||||
return DescribeFlags(buf, 48, kProtFlags, ARRAYLEN(kProtFlags), "PROT_", x);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sysv/consts/ptrace.h"
|
||||
|
||||
const char *(DescribePtrace)(char buf[12], int x) {
|
||||
#ifdef DescribePtrace
|
||||
#undef DescribePtrace
|
||||
#endif
|
||||
|
||||
const char *DescribePtrace(char buf[12], int x) {
|
||||
if (x == -1) return "-1";
|
||||
if (x == PTRACE_TRACEME) return "PTRACE_TRACEME";
|
||||
if (x == PTRACE_PEEKDATA) return "PTRACE_PEEKDATA";
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sysv/consts/ptrace.h"
|
||||
|
||||
const char *(DescribePtraceEvent)(char buf[32], int x) {
|
||||
#ifdef DescribePtraceEvent
|
||||
#undef DescribePtraceEvent
|
||||
#endif
|
||||
|
||||
const char *DescribePtraceEvent(char buf[32], int x) {
|
||||
if (x == PTRACE_EVENT_FORK) return "PTRACE_EVENT_FORK";
|
||||
if (x == PTRACE_EVENT_VFORK) return "PTRACE_EVENT_VFORK";
|
||||
if (x == PTRACE_EVENT_CLONE) return "PTRACE_EVENT_CLONE";
|
||||
|
|
|
@ -20,12 +20,16 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/sysv/consts/mremap.h"
|
||||
|
||||
#ifdef DescribeRemapFlags
|
||||
#undef DescribeRemapFlags
|
||||
#endif
|
||||
|
||||
static const struct DescribeFlags kRemapFlags[] = {
|
||||
{MREMAP_MAYMOVE, "MAYMOVE"}, //
|
||||
{MREMAP_FIXED, "FIXED"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeRemapFlags)(char buf[48], int x) {
|
||||
const char *DescribeRemapFlags(char buf[48], int x) {
|
||||
return DescribeFlags(buf, 48, kRemapFlags, ARRAYLEN(kRemapFlags), "MREMAP_",
|
||||
x);
|
||||
}
|
||||
|
|
|
@ -19,10 +19,14 @@
|
|||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
|
||||
#ifdef DescribeRlimitName
|
||||
#undef DescribeRlimitName
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Describes setrlimit() / getrlimit() argument.
|
||||
*/
|
||||
const char *(DescribeRlimitName)(char buf[20], int x) {
|
||||
const char *DescribeRlimitName(char buf[20], int x) {
|
||||
if (x == 127) return "n/a";
|
||||
return DescribeMagnum(buf, kRlimitNames, "RLIMIT_", x);
|
||||
}
|
||||
|
|
|
@ -21,10 +21,14 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#ifdef DescribeSchedParam
|
||||
#undef DescribeSchedParam
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Describes clock_gettime() clock argument.
|
||||
*/
|
||||
const char *(DescribeSchedParam)(char buf[32], const struct sched_param *x) {
|
||||
const char *DescribeSchedParam(char buf[32], const struct sched_param *x) {
|
||||
char *p;
|
||||
if (!x) return "0";
|
||||
p = buf;
|
||||
|
|
|
@ -23,10 +23,14 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sched.h"
|
||||
|
||||
#ifdef DescribeSchedPolicy
|
||||
#undef DescribeSchedPolicy
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Describes clock_gettime() clock argument.
|
||||
*/
|
||||
const char *(DescribeSchedPolicy)(char buf[48], int x) {
|
||||
const char *DescribeSchedPolicy(char buf[48], int x) {
|
||||
char *p = buf;
|
||||
if (x == -1) {
|
||||
goto DoNumber;
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
#include "libc/sysv/consts/sicode.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
|
||||
#ifdef DescribeSiCode
|
||||
#undef DescribeSiCode
|
||||
#endif
|
||||
|
||||
static bool IsSiUser(int si_code) {
|
||||
if (!IsOpenbsd()) {
|
||||
return si_code == SI_USER;
|
||||
|
@ -38,7 +42,7 @@ static void NameIt(char p[17], const char *s, int si_code) {
|
|||
/**
|
||||
* Returns symbolic name for siginfo::si_code value.
|
||||
*/
|
||||
const char *(DescribeSiCode)(char b[17], int sig, int si_code) {
|
||||
const char *DescribeSiCode(char b[17], int sig, int si_code) {
|
||||
NameIt(b, "SI_", si_code);
|
||||
if (si_code == SI_QUEUE) {
|
||||
strcpy(b + 3, "QUEUE"); /* sent by sigqueue(2) */
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
#include "libc/mem/alloca.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
|
||||
#ifdef DescribeSigaction
|
||||
#undef DescribeSigaction
|
||||
#endif
|
||||
|
||||
static const char *DescribeSigHandler(char buf[64], void f(int)) {
|
||||
if (f == SIG_ERR) return "SIG_ERR";
|
||||
if (f == SIG_DFL) return "SIG_DFL";
|
||||
|
@ -54,8 +58,7 @@ static const char *DescribeSigFlags(char buf[64], int x) {
|
|||
|
||||
#define append(...) o += ksnprintf(buf + o, N - o, __VA_ARGS__)
|
||||
|
||||
const char *(DescribeSigaction)(char buf[N], int rc,
|
||||
const struct sigaction *sa) {
|
||||
const char *DescribeSigaction(char buf[N], int rc, const struct sigaction *sa) {
|
||||
int o = 0;
|
||||
char b64[64];
|
||||
|
||||
|
|
|
@ -22,8 +22,12 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
|
||||
const char *(DescribeSigaltstk)(char buf[128], int rc,
|
||||
const struct sigaltstack *ss) {
|
||||
#ifdef DescribeSigaltstk
|
||||
#undef DescribeSigaltstk
|
||||
#endif
|
||||
|
||||
const char *DescribeSigaltstk(char buf[128], int rc,
|
||||
const struct sigaltstack *ss) {
|
||||
if (rc == -1) return "n/a";
|
||||
if (!ss) return "NULL";
|
||||
if ((!IsAsan() && kisdangerous(ss)) ||
|
||||
|
|
|
@ -26,11 +26,15 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
|
||||
#ifdef DescribeSiginfo
|
||||
#undef DescribeSiginfo
|
||||
#endif
|
||||
|
||||
#define N 300
|
||||
|
||||
#define append(...) i += ksnprintf(buf + i, N - i, __VA_ARGS__)
|
||||
|
||||
const char *(DescribeSiginfo)(char buf[N], int rc, const siginfo_t *si) {
|
||||
const char *DescribeSiginfo(char buf[N], int rc, const siginfo_t *si) {
|
||||
int i = 0;
|
||||
|
||||
if (rc == -1) return "n/a";
|
||||
|
|
|
@ -26,11 +26,15 @@
|
|||
#include "libc/sysv/consts/limits.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
|
||||
#ifdef DescribeSigset
|
||||
#undef DescribeSigset
|
||||
#endif
|
||||
|
||||
#define N 128
|
||||
|
||||
#define append(...) o += ksnprintf(buf + o, N - o, __VA_ARGS__)
|
||||
|
||||
const char *(DescribeSigset)(char buf[N], int rc, const sigset_t *ss) {
|
||||
const char *DescribeSigset(char buf[N], int rc, const sigset_t *ss) {
|
||||
bool gotsome;
|
||||
const char *s;
|
||||
int sig, o = 0;
|
||||
|
|
|
@ -21,10 +21,14 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sysv/consts/timer.h"
|
||||
|
||||
#ifdef DescribeSleepFlags
|
||||
#undef DescribeSleepFlags
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Describes clock_nanosleep() flags argument.
|
||||
*/
|
||||
const char *(DescribeSleepFlags)(char buf[16], int x) {
|
||||
const char *DescribeSleepFlags(char buf[16], int x) {
|
||||
switch (x) {
|
||||
case 0:
|
||||
return "0";
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
|
||||
const char *(DescribeSocketFamily)(char buf[12], int family) {
|
||||
#ifdef DescribeSocketFamily
|
||||
#undef DescribeSocketFamily
|
||||
#endif
|
||||
|
||||
const char *DescribeSocketFamily(char buf[12], int family) {
|
||||
if (family == AF_UNIX) return "AF_UNIX";
|
||||
if (family == AF_INET) return "AF_INET";
|
||||
if (family == AF_INET6) return "AF_INET6";
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sysv/consts/ipproto.h"
|
||||
|
||||
const char *(DescribeSocketProtocol)(char buf[12], int family) {
|
||||
#ifdef DescribeSocketProtocol
|
||||
#undef DescribeSocketProtocol
|
||||
#endif
|
||||
|
||||
const char *DescribeSocketProtocol(char buf[12], int family) {
|
||||
if (family == IPPROTO_IP) return "IPPROTO_IP";
|
||||
if (family == IPPROTO_ICMP) return "IPPROTO_ICMP";
|
||||
if (family == IPPROTO_TCP) return "IPPROTO_TCP";
|
||||
|
|
|
@ -21,7 +21,11 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
|
||||
const char *(DescribeSocketType)(char buf[64], int type) {
|
||||
#ifdef DescribeSocketType
|
||||
#undef DescribeSocketType
|
||||
#endif
|
||||
|
||||
const char *DescribeSocketType(char buf[64], int type) {
|
||||
int x;
|
||||
char *p;
|
||||
p = buf;
|
||||
|
|
|
@ -20,10 +20,14 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
|
||||
#ifdef DescribeSockLevel
|
||||
#undef DescribeSockLevel
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Describes setsockopt() level arguments.
|
||||
*/
|
||||
const char *(DescribeSockLevel)(char buf[12], int x) {
|
||||
const char *DescribeSockLevel(char buf[12], int x) {
|
||||
if (x == SOL_IP) return "SOL_IP";
|
||||
if (x == SOL_TCP) return "SOL_TCP";
|
||||
if (x == SOL_UDP) return "SOL_UDP";
|
||||
|
|
|
@ -22,10 +22,14 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
|
||||
#ifdef DescribeSockOptname
|
||||
#undef DescribeSockOptname
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Describes setsockopt() optname arguments.
|
||||
*/
|
||||
const char *(DescribeSockOptname)(char buf[32], int l, int x) {
|
||||
const char *DescribeSockOptname(char buf[32], int l, int x) {
|
||||
int i;
|
||||
char *s, *p;
|
||||
const struct MagnumStr *ms;
|
||||
|
|
|
@ -22,11 +22,15 @@
|
|||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
|
||||
#ifdef DescribeStat
|
||||
#undef DescribeStat
|
||||
#endif
|
||||
|
||||
#define N 300
|
||||
|
||||
#define append(...) o += ksnprintf(buf + o, N - o, __VA_ARGS__)
|
||||
|
||||
const char *(DescribeStat)(char buf[N], int rc, const struct stat *st) {
|
||||
const char *DescribeStat(char buf[N], int rc, const struct stat *st) {
|
||||
int o = 0;
|
||||
|
||||
if (rc == -1) return "n/a";
|
||||
|
|
|
@ -24,11 +24,15 @@
|
|||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/sysv/consts/st.h"
|
||||
|
||||
#ifdef DescribeStatfs
|
||||
#undef DescribeStatfs
|
||||
#endif
|
||||
|
||||
#define N 300
|
||||
|
||||
#define append(...) i += ksnprintf(buf + i, N - i, __VA_ARGS__)
|
||||
|
||||
const char *(DescribeStatfs)(char buf[N], int rc, const struct statfs *f) {
|
||||
const char *DescribeStatfs(char buf[N], int rc, const struct statfs *f) {
|
||||
int i = 0;
|
||||
char ibuf[21];
|
||||
int64_t flags;
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
const char *(DescribeStdioState)(char buf[12], int x) {
|
||||
#ifdef DescribeStdioState
|
||||
#undef DescribeStdioState
|
||||
#endif
|
||||
|
||||
const char *DescribeStdioState(char buf[12], int x) {
|
||||
if (!x) return "";
|
||||
if (x == -1) return "EOF";
|
||||
if (x > 0) return _strerrno(x);
|
||||
|
|
|
@ -21,11 +21,15 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
|
||||
#ifdef DescribeStringList
|
||||
#undef DescribeStringList
|
||||
#endif
|
||||
|
||||
#define N 300
|
||||
|
||||
#define append(...) o += ksnprintf(buf + o, N - o, __VA_ARGS__)
|
||||
|
||||
const char *(DescribeStringList)(char buf[N], char *const list[]) {
|
||||
const char *DescribeStringList(char buf[N], char *const list[]) {
|
||||
int i, o = 0;
|
||||
|
||||
if (!list) return "NULL";
|
||||
|
|
|
@ -23,8 +23,11 @@
|
|||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
const char *(DescribeTimespec)(char buf[45], int rc,
|
||||
const struct timespec *ts) {
|
||||
#ifdef DescribeTimespec
|
||||
#undef DescribeTimespec
|
||||
#endif
|
||||
|
||||
const char *DescribeTimespec(char buf[45], int rc, const struct timespec *ts) {
|
||||
if (rc == -1) return "n/a";
|
||||
if (!ts) return "NULL";
|
||||
if ((!IsAsan() && kisdangerous(ts)) ||
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
|
||||
const char *(DescribeWhence)(char buf[12], int whence) {
|
||||
#ifdef DescribeWhence
|
||||
#undef DescribeWhence
|
||||
#endif
|
||||
|
||||
const char *DescribeWhence(char buf[12], int whence) {
|
||||
if (whence == SEEK_SET) return "SEEK_SET";
|
||||
if (whence == SEEK_CUR) return "SEEK_CUR";
|
||||
if (whence == SEEK_END) return "SEEK_END";
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sysv/consts/prio.h"
|
||||
|
||||
const char *(DescribeWhichPrio)(char buf[12], int x) {
|
||||
#ifdef DescribeWhichPrio
|
||||
#undef DescribeWhichPrio
|
||||
#endif
|
||||
|
||||
const char *DescribeWhichPrio(char buf[12], int x) {
|
||||
if (x == PRIO_PROCESS) return "PRIO_PROCESS";
|
||||
if (x == PRIO_PGRP) return "PRIO_PGRP";
|
||||
if (x == PRIO_USER) return "PRIO_USER";
|
||||
|
|
|
@ -20,11 +20,19 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/thread/thread.h"
|
||||
|
||||
void(__fds_lock)(void) {
|
||||
#ifdef __fds_lock
|
||||
#undef __fds_lock
|
||||
#endif
|
||||
|
||||
#ifdef __fds_unlock
|
||||
#undef __fds_unlock
|
||||
#endif
|
||||
|
||||
void __fds_lock(void) {
|
||||
pthread_mutex_lock(&__fds_lock_obj);
|
||||
}
|
||||
|
||||
void(__fds_unlock)(void) {
|
||||
void __fds_unlock(void) {
|
||||
pthread_mutex_unlock(&__fds_lock_obj);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,14 +20,22 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/thread/thread.h"
|
||||
|
||||
#ifdef __mmi_lock
|
||||
#undef __mmi_lock
|
||||
#endif
|
||||
|
||||
#ifdef __mmi_unlock
|
||||
#undef __mmi_unlock
|
||||
#endif
|
||||
|
||||
// this lock currently needs to be (1) recursive and (2) not nsync
|
||||
|
||||
extern pthread_mutex_t __mmi_lock_obj;
|
||||
|
||||
void(__mmi_lock)(void) {
|
||||
void __mmi_lock(void) {
|
||||
pthread_mutex_lock(&__mmi_lock_obj);
|
||||
}
|
||||
|
||||
void(__mmi_unlock)(void) {
|
||||
void __mmi_unlock(void) {
|
||||
pthread_mutex_unlock(&__mmi_lock_obj);
|
||||
}
|
||||
|
|
|
@ -18,13 +18,17 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/psrad.h"
|
||||
|
||||
#ifdef psradv
|
||||
#undef psradv
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Divides shorts by two powers.
|
||||
*
|
||||
* @note arithmetic shift right will sign extend negatives
|
||||
* @mayalias
|
||||
*/
|
||||
void(psradv)(int32_t a[4], const int32_t b[4], const uint64_t c[2]) {
|
||||
void psradv(int32_t a[4], const int32_t b[4], const uint64_t c[2]) {
|
||||
unsigned i;
|
||||
unsigned char k;
|
||||
k = c[0] > 31 ? 31 : c[0];
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#ifdef psubusb
|
||||
#undef psubusb
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Subtracts unsigned 8-bit integers w/ saturation.
|
||||
*
|
||||
|
@ -29,7 +33,7 @@
|
|||
* @param 𝑐 [r/o] supplies second input vector
|
||||
* @mayalias
|
||||
*/
|
||||
void(psubusb)(uint8_t a[16], const uint8_t b[16], const uint8_t c[16]) {
|
||||
void psubusb(uint8_t a[16], const uint8_t b[16], const uint8_t c[16]) {
|
||||
unsigned i;
|
||||
uint8_t r[16];
|
||||
for (i = 0; i < 16; ++i) {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
void(psubw)(int16_t[8], const int16_t[8], const int16_t[8]);
|
||||
void psubw(int16_t[8], const int16_t[8], const int16_t[8]);
|
||||
|
||||
#define psubw(A, B, C) \
|
||||
INTRIN_SSEVEX_X_X_X_(psubw, SSE2, "psubw", INTRIN_NONCOMMUTATIVE, A, B, C)
|
||||
|
|
|
@ -21,7 +21,11 @@
|
|||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
||||
void _pthread_cleanup_pop(struct _pthread_cleanup_buffer *cb, int execute) {
|
||||
#ifdef pthread_cleanup_pop
|
||||
#undef pthread_cleanup_pop
|
||||
#endif
|
||||
|
||||
void pthread_cleanup_pop(struct _pthread_cleanup_buffer *cb, int execute) {
|
||||
struct PosixThread *pt;
|
||||
if (__tls_enabled && (pt = (struct PosixThread *)__get_tls()->tib_pthread)) {
|
||||
_unassert(cb == pt->cleanup);
|
||||
|
|
|
@ -20,8 +20,12 @@
|
|||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
||||
void _pthread_cleanup_push(struct _pthread_cleanup_buffer *cb,
|
||||
void (*routine)(void *), void *arg) {
|
||||
#ifdef pthread_cleanup_push
|
||||
#undef pthread_cleanup_push
|
||||
#endif
|
||||
|
||||
void pthread_cleanup_push(struct _pthread_cleanup_buffer *cb,
|
||||
void (*routine)(void *), void *arg) {
|
||||
struct PosixThread *pt;
|
||||
cb->__routine = routine;
|
||||
cb->__arg = arg;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/thread/thread.h"
|
||||
|
||||
#ifdef pthread_spin_lock
|
||||
|
@ -44,10 +45,22 @@
|
|||
*/
|
||||
errno_t pthread_spin_lock(pthread_spinlock_t *spin) {
|
||||
int x;
|
||||
#if defined(SYSDEBUG) && _LOCKTRACE
|
||||
for (;;) {
|
||||
x = atomic_exchange_explicit(&spin->_lock, 1, memory_order_acquire);
|
||||
if (!x) {
|
||||
LOCKTRACE("pthread_spin_lock(%t)", spin);
|
||||
break;
|
||||
}
|
||||
_unassert(x == 1);
|
||||
LOCKTRACE("pthread_spin_lock(%t) trying...", spin);
|
||||
}
|
||||
#else
|
||||
for (;;) {
|
||||
x = atomic_exchange_explicit(&spin->_lock, 1, memory_order_acquire);
|
||||
if (!x) break;
|
||||
_unassert(x == 1);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/thread/thread.h"
|
||||
|
||||
#ifdef pthread_spin_unlock
|
||||
|
@ -33,6 +34,7 @@
|
|||
* @see pthread_spin_lock
|
||||
*/
|
||||
errno_t pthread_spin_unlock(pthread_spinlock_t *spin) {
|
||||
LOCKTRACE("pthread_spin_unlock(%t)", spin);
|
||||
atomic_store_explicit(&spin->_lock, 0, memory_order_release);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -297,12 +297,12 @@ static wontreturn relegated noinstrument void __minicrash(int sig,
|
|||
* @vforksafe
|
||||
*/
|
||||
relegated void __oncrash(int sig, struct siginfo *si, ucontext_t *ctx) {
|
||||
bool bZero;
|
||||
int bZero;
|
||||
intptr_t rip;
|
||||
int me, owner;
|
||||
int gdbpid, err;
|
||||
static atomic_int once;
|
||||
static atomic_bool once2;
|
||||
static atomic_int once2;
|
||||
STRACE("__oncrash rip %x", ctx->uc_mcontext.rip);
|
||||
ftrace_enabled(-1);
|
||||
strace_enabled(-1);
|
||||
|
|
|
@ -608,7 +608,7 @@ errno_t clone(void *func, void *stk, size_t stksz, int flags, void *arg,
|
|||
}
|
||||
|
||||
STRACE("clone(%t, %p, %'zu, %#x, %p, %p, %p, %p) → %s", func, stk, stksz,
|
||||
flags, arg, ptid, tls, ctid, DescribeErrnoResult(rc));
|
||||
flags, arg, ptid, tls, ctid, DescribeErrno(rc));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -92,9 +92,9 @@ int posix_spawn(int *pid, const char *path,
|
|||
posix_spawnattr_getsigmask(attrp, &sigmask);
|
||||
sigprocmask(SIG_SETMASK, &sigmask, 0);
|
||||
}
|
||||
if (flags & POSIX_SPAWN_RESETIDS) {
|
||||
setuid(getuid());
|
||||
setgid(getgid());
|
||||
if ((flags & POSIX_SPAWN_RESETIDS) &&
|
||||
(setgid(getgid()) || setuid(getuid()))) {
|
||||
_Exit(127);
|
||||
}
|
||||
if (flags & POSIX_SPAWN_SETSIGDEF) {
|
||||
for (s = 1; s < 32; s++) {
|
||||
|
|
|
@ -135,6 +135,7 @@ static void FixIrregularFds(void) {
|
|||
}
|
||||
if (IsGenuineCosmo()) {
|
||||
// TODO(jart): Fix Blinkenlights poll() / close()
|
||||
free(pfds);
|
||||
return;
|
||||
}
|
||||
if (poll(pfds, maxfds, 0) != -1) {
|
||||
|
|
|
@ -78,7 +78,6 @@ struct PosixThread {
|
|||
nsync_dll_element_ list; // list of threads
|
||||
jmp_buf exiter; // for pthread_exit
|
||||
pthread_attr_t attr;
|
||||
sigset_t sigmask;
|
||||
struct _pthread_cleanup_buffer *cleanup;
|
||||
};
|
||||
|
||||
|
|
|
@ -16,10 +16,22 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/blockcancel.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/clock_gettime.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/thread/thread2.h"
|
||||
|
||||
/**
|
||||
* Gets signal mask on thread attributes object.
|
||||
*
|
||||
* @param attr is the thread attributes object
|
||||
* @param sigmask will receive the output signal mask on success, or
|
||||
* null if a simple presence check is desired
|
||||
* @return 0 on success, errno on error, or `PTHREAD_ATTR_NO_SIGMASK_NP`
|
||||
* if there wasn't any signal mask present in `attr`
|
||||
*/
|
||||
errno_t pthread_attr_getsigmask_np(const pthread_attr_t *attr,
|
||||
sigset_t *sigmask) {
|
||||
_Static_assert(sizeof(attr->__sigmask) == sizeof(*sigmask), "");
|
||||
if (!attr->__havesigmask) return PTHREAD_ATTR_NO_SIGMASK_NP;
|
||||
if (sigmask) memcpy(sigmask, attr->__sigmask, sizeof(*sigmask));
|
||||
return 0;
|
||||
}
|
|
@ -42,7 +42,6 @@
|
|||
*/
|
||||
errno_t pthread_attr_setschedparam(pthread_attr_t *attr,
|
||||
const struct sched_param *param) {
|
||||
if (!param) return EINVAL;
|
||||
attr->__schedparam = param->sched_priority;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -16,13 +16,25 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/thread/thread2.h"
|
||||
|
||||
const char *(DescribeErrno)(char buf[12], int x) {
|
||||
const char *s;
|
||||
if ((s = _strerrno(x))) return s;
|
||||
FormatInt32(buf, x);
|
||||
return buf;
|
||||
/**
|
||||
* Sets signal mask on thread attributes object.
|
||||
*
|
||||
* @param attr is the thread attributes object
|
||||
* @param sigmask will be copied into attributes, or if it's null, then
|
||||
* the existing signal mask presence on the object will be cleared
|
||||
* @return 0 on success, or errno on error
|
||||
*/
|
||||
errno_t pthread_attr_setsigmask_np(pthread_attr_t *attr,
|
||||
const sigset_t *sigmask) {
|
||||
_Static_assert(sizeof(attr->__sigmask) == sizeof(*sigmask), "");
|
||||
if (sigmask) {
|
||||
attr->__havesigmask = true;
|
||||
memcpy(attr->__sigmask, sigmask, sizeof(*sigmask));
|
||||
} else {
|
||||
attr->__havesigmask = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -32,9 +32,11 @@
|
|||
#include "libc/runtime/clone.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/clone.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/consts/ss.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
#include "libc/thread/spawn.h"
|
||||
|
@ -84,7 +86,7 @@ static int PosixThread(void *arg, int tid) {
|
|||
// set long jump handler so pthread_exit can bring control back here
|
||||
if (!setjmp(pt->exiter)) {
|
||||
__get_tls()->tib_pthread = (pthread_t)pt;
|
||||
_sigsetmask(pt->sigmask);
|
||||
_npassert(!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);
|
||||
|
@ -224,6 +226,10 @@ static errno_t pthread_create_impl(pthread_t *thread,
|
|||
}
|
||||
|
||||
// set initial status
|
||||
if (!pt->attr.__havesigmask) {
|
||||
pt->attr.__havesigmask = true;
|
||||
memcpy(pt->attr.__sigmask, &oldsigs, sizeof(oldsigs));
|
||||
}
|
||||
switch (pt->attr.__detachstate) {
|
||||
case PTHREAD_CREATE_JOINABLE:
|
||||
atomic_store_explicit(&pt->status, kPosixThreadJoinable,
|
||||
|
@ -246,7 +252,6 @@ static errno_t pthread_create_impl(pthread_t *thread,
|
|||
pthread_spin_unlock(&_pthread_lock);
|
||||
|
||||
// launch PosixThread(pt) in new thread
|
||||
pt->sigmask = oldsigs;
|
||||
if ((rc = clone(PosixThread, pt->attr.__stackaddr,
|
||||
pt->attr.__stacksize - (IsOpenbsd() ? 16 : 0),
|
||||
CLONE_VM | CLONE_THREAD | CLONE_FS | CLONE_FILES |
|
||||
|
@ -260,9 +265,7 @@ static errno_t pthread_create_impl(pthread_t *thread,
|
|||
return rc;
|
||||
}
|
||||
|
||||
if (thread) {
|
||||
*thread = (pthread_t)pt;
|
||||
}
|
||||
*thread = (pthread_t)pt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,6 @@ errno_t pthread_getaffinity_np(pthread_t thread, size_t size,
|
|||
}
|
||||
|
||||
STRACE("pthread_getaffinity_np(%d, %'zu, %p) → %s", tid, size, bitset,
|
||||
DescribeErrnoResult(rc));
|
||||
DescribeErrno(rc));
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -16,13 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#include "libc/thread/wait0.internal.h"
|
||||
#include "libc/thread/thread2.h"
|
||||
|
||||
/**
|
||||
* Waits for thread to terminate.
|
||||
|
@ -44,24 +38,5 @@
|
|||
* @threadsafe
|
||||
*/
|
||||
errno_t pthread_join(pthread_t thread, void **value_ptr) {
|
||||
errno_t rc;
|
||||
struct PosixThread *pt;
|
||||
enum PosixThreadStatus status;
|
||||
pt = (struct PosixThread *)thread;
|
||||
status = atomic_load_explicit(&pt->status, memory_order_acquire);
|
||||
// "The behavior is undefined if the value specified by the thread
|
||||
// argument to pthread_join() does not refer to a joinable thread."
|
||||
// ──Quoth POSIX.1-2017
|
||||
_unassert(status == kPosixThreadJoinable || status == kPosixThreadTerminated);
|
||||
if (!(rc = _wait0(&pt->tib->tib_tid))) {
|
||||
pthread_spin_lock(&_pthread_lock);
|
||||
_pthread_list = nsync_dll_remove_(_pthread_list, &pt->list);
|
||||
pthread_spin_unlock(&_pthread_lock);
|
||||
if (value_ptr) {
|
||||
*value_ptr = pt->rc;
|
||||
}
|
||||
_pthread_free(pt);
|
||||
pthread_decimate_np();
|
||||
}
|
||||
return 0;
|
||||
return pthread_timedjoin_np(thread, value_ptr, 0);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
/**
|
||||
* Returns true if calling thread is the only thread.
|
||||
*/
|
||||
bool pthread_orphan_np(void) {
|
||||
int pthread_orphan_np(void) {
|
||||
bool res;
|
||||
pthread_spin_lock(&_pthread_lock);
|
||||
res = _pthread_list == _pthread_list->prev &&
|
||||
|
|
|
@ -74,6 +74,6 @@ errno_t pthread_setaffinity_np(pthread_t thread, size_t size,
|
|||
}
|
||||
}
|
||||
STRACE("pthread_setaffinity_np(%d, %'zu, %p) → %s", tid, size, bitset,
|
||||
DescribeErrnoResult(rc));
|
||||
DescribeErrno(rc));
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
errno_t pthread_setschedparam(pthread_t thread, int policy,
|
||||
const struct sched_param *param) {
|
||||
struct PosixThread *pt = (struct PosixThread *)thread;
|
||||
if (!param) return EINVAL;
|
||||
pt->attr.__schedpolicy = policy;
|
||||
pt->attr.__schedparam = param->sched_priority;
|
||||
return _pthread_reschedule(pt);
|
||||
|
|
72
libc/thread/pthread_timedjoin_np.c
Normal file
72
libc/thread/pthread_timedjoin_np.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*-*- 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/assert.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
#include "libc/thread/thread2.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#include "libc/thread/wait0.internal.h"
|
||||
|
||||
/**
|
||||
* Waits for thread to terminate.
|
||||
*
|
||||
* Multiple threads joining the same thread is undefined behavior. If a
|
||||
* deferred or masked cancellation happens to the calling thread either
|
||||
* before or during the waiting process then the target thread will not
|
||||
* be joined. Calling pthread_join() on a non-joinable thread, e.g. one
|
||||
* that's been detached, is undefined behavior. If a thread attempts to
|
||||
* join itself, then the behavior is undefined.
|
||||
*
|
||||
* @param value_ptr if non-null will receive pthread_exit() argument
|
||||
* if the thread called pthread_exit(), or `PTHREAD_CANCELED` if
|
||||
* pthread_cancel() destroyed the thread instead
|
||||
* @param abstime specifies an absolute deadline or the timestamp of
|
||||
* when we'll stop waiting; if this is null we will wait forever
|
||||
* @return 0 on success, or errno on error
|
||||
* @raise ECANCELED if calling thread was cancelled in masked mode
|
||||
* @raise EBUSY if `abstime` deadline elapsed
|
||||
* @cancellationpoint
|
||||
* @returnserrno
|
||||
* @threadsafe
|
||||
*/
|
||||
errno_t pthread_timedjoin_np(pthread_t thread, void **value_ptr,
|
||||
struct timespec *abstime) {
|
||||
errno_t rc;
|
||||
struct PosixThread *pt;
|
||||
enum PosixThreadStatus status;
|
||||
pt = (struct PosixThread *)thread;
|
||||
status = atomic_load_explicit(&pt->status, memory_order_acquire);
|
||||
// "The behavior is undefined if the value specified by the thread
|
||||
// argument to pthread_join() does not refer to a joinable thread."
|
||||
// ──Quoth POSIX.1-2017
|
||||
_unassert(status == kPosixThreadJoinable || status == kPosixThreadTerminated);
|
||||
if (!(rc = _wait0(&pt->tib->tib_tid, abstime))) {
|
||||
pthread_spin_lock(&_pthread_lock);
|
||||
_pthread_list = nsync_dll_remove_(_pthread_list, &pt->list);
|
||||
pthread_spin_unlock(&_pthread_lock);
|
||||
if (value_ptr) {
|
||||
*value_ptr = pt->rc;
|
||||
}
|
||||
_pthread_free(pt);
|
||||
pthread_decimate_np();
|
||||
}
|
||||
return 0;
|
||||
}
|
42
libc/thread/pthread_tryjoin_np.c
Normal file
42
libc/thread/pthread_tryjoin_np.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*-*- 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/thread/thread2.h"
|
||||
|
||||
/**
|
||||
* Joins thread if it's already terminated.
|
||||
*
|
||||
* Multiple threads joining the same thread is undefined behavior. If a
|
||||
* deferred or masked cancellation happens to the calling thread either
|
||||
* before or during the waiting process then the target thread will not
|
||||
* be joined. Calling pthread_join() on a non-joinable thread, e.g. one
|
||||
* that's been detached, is undefined behavior. If a thread attempts to
|
||||
* join itself, then the behavior is undefined.
|
||||
*
|
||||
* @param value_ptr if non-null will receive pthread_exit() argument
|
||||
* if the thread called pthread_exit(), or `PTHREAD_CANCELED` if
|
||||
* pthread_cancel() destroyed the thread instead
|
||||
* @return 0 on success, or errno on error
|
||||
* @raise ECANCELED if calling thread was cancelled in masked mode
|
||||
* @cancellationpoint
|
||||
* @returnserrno
|
||||
* @threadsafe
|
||||
*/
|
||||
errno_t pthread_tryjoin_np(pthread_t thread, void **value_ptr) {
|
||||
return pthread_timedjoin_np(thread, value_ptr, ×pec_zero);
|
||||
}
|
|
@ -34,7 +34,7 @@
|
|||
int sem_post(sem_t *sem) {
|
||||
int rc, old, wakeups;
|
||||
_unassert(sem->sem_pshared || sem->sem_pid == getpid());
|
||||
old = atomic_fetch_add_explicit(&sem->sem_value, 1, memory_order_relaxed);
|
||||
old = atomic_fetch_add_explicit(&sem->sem_value, 1, memory_order_acq_rel);
|
||||
_unassert(old > INT_MIN);
|
||||
if (old >= 0) {
|
||||
wakeups = nsync_futex_wake_(&sem->sem_value, 1, sem->sem_pshared);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
@ -148,7 +149,7 @@ int _join(struct spawn *th) {
|
|||
int rc;
|
||||
if (th->tib) {
|
||||
// wait for ctid to become zero
|
||||
_wait0(&th->tib->tib_tid);
|
||||
_npassert(!_wait0(&th->tib->tib_tid, 0));
|
||||
// free thread memory
|
||||
free(th->tls);
|
||||
rc = munmap(th->stk, GetStackSize());
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#define PTHREAD_SCOPE_SYSTEM 0
|
||||
#define PTHREAD_SCOPE_PROCESS 1
|
||||
|
||||
#define PTHREAD_ATTR_NO_SIGMASK_NP -1
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
|
@ -58,7 +60,7 @@ typedef struct pthread_once_s {
|
|||
} pthread_once_t;
|
||||
|
||||
typedef struct pthread_spinlock_s {
|
||||
_Atomic(char) _lock;
|
||||
_Atomic(int) _lock;
|
||||
} pthread_spinlock_t;
|
||||
|
||||
typedef struct pthread_mutex_s {
|
||||
|
@ -91,11 +93,13 @@ typedef struct pthread_barrier_s {
|
|||
typedef struct pthread_attr_s {
|
||||
char __detachstate;
|
||||
char __inheritsched;
|
||||
char __havesigmask;
|
||||
int __schedparam;
|
||||
int __schedpolicy;
|
||||
int __contentionscope;
|
||||
unsigned __guardsize;
|
||||
unsigned __stacksize;
|
||||
uint32_t __sigmask[4];
|
||||
char *__stackaddr;
|
||||
} pthread_attr_t;
|
||||
|
||||
|
@ -106,108 +110,109 @@ struct _pthread_cleanup_buffer {
|
|||
struct _pthread_cleanup_buffer *__prev;
|
||||
};
|
||||
|
||||
int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *),
|
||||
void *);
|
||||
/* clang-format off */
|
||||
|
||||
int pthread_yield(void);
|
||||
bool pthread_orphan_np(void);
|
||||
void pthread_testcancel(void);
|
||||
void pthread_decimate_np(void);
|
||||
int pthread_testcancel_np(void);
|
||||
void pthread_exit(void *) wontreturn;
|
||||
pthread_t pthread_self(void) pureconst;
|
||||
int pthread_print_np(int, const char *, ...);
|
||||
pthread_id_np_t pthread_getthreadid_np(void);
|
||||
int pthread_getunique_np(pthread_t, pthread_id_np_t *);
|
||||
int pthread_setname_np(pthread_t, const char *);
|
||||
int pthread_getname_np(pthread_t, char *, size_t);
|
||||
int pthread_getattr_np(pthread_t, pthread_attr_t *);
|
||||
int pthread_attr_init(pthread_attr_t *);
|
||||
int pthread_attr_destroy(pthread_attr_t *);
|
||||
int pthread_attr_getdetachstate(const pthread_attr_t *, int *);
|
||||
int pthread_attr_setdetachstate(pthread_attr_t *, int);
|
||||
int pthread_attr_getguardsize(const pthread_attr_t *, size_t *);
|
||||
int pthread_attr_setguardsize(pthread_attr_t *, size_t);
|
||||
int pthread_attr_getinheritsched(const pthread_attr_t *, int *);
|
||||
int pthread_attr_setinheritsched(pthread_attr_t *, int);
|
||||
int pthread_attr_getschedpolicy(const pthread_attr_t *, int *);
|
||||
int pthread_attr_setschedpolicy(pthread_attr_t *, int);
|
||||
int pthread_attr_getscope(const pthread_attr_t *, int *);
|
||||
int pthread_attr_setscope(pthread_attr_t *, int);
|
||||
int pthread_attr_getstack(const pthread_attr_t *, void **, size_t *);
|
||||
int pthread_attr_setstack(pthread_attr_t *, void *, size_t);
|
||||
int pthread_attr_getstacksize(const pthread_attr_t *, size_t *);
|
||||
int pthread_attr_setstacksize(pthread_attr_t *, size_t);
|
||||
int pthread_detach(pthread_t);
|
||||
int pthread_kill(pthread_t, int);
|
||||
int pthread_cancel(pthread_t);
|
||||
int pthread_setcanceltype(int, int *);
|
||||
int pthread_setcancelstate(int, int *);
|
||||
int pthread_setschedprio(pthread_t, int);
|
||||
int pthread_join(pthread_t, void **);
|
||||
int pthread_equal(pthread_t, pthread_t);
|
||||
int pthread_once(pthread_once_t *, void (*)(void));
|
||||
int pthread_spin_init(pthread_spinlock_t *, int);
|
||||
int pthread_spin_destroy(pthread_spinlock_t *);
|
||||
int pthread_spin_lock(pthread_spinlock_t *);
|
||||
int pthread_spin_unlock(pthread_spinlock_t *);
|
||||
int pthread_spin_trylock(pthread_spinlock_t *);
|
||||
int pthread_mutexattr_init(pthread_mutexattr_t *);
|
||||
int pthread_mutexattr_destroy(pthread_mutexattr_t *);
|
||||
int pthread_mutexattr_gettype(const pthread_mutexattr_t *, int *);
|
||||
int pthread_mutexattr_settype(pthread_mutexattr_t *, int);
|
||||
int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);
|
||||
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *, int *);
|
||||
int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
|
||||
int pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *);
|
||||
int pthread_mutex_lock(pthread_mutex_t *);
|
||||
int pthread_mutex_unlock(pthread_mutex_t *);
|
||||
int pthread_mutex_trylock(pthread_mutex_t *);
|
||||
int pthread_mutex_destroy(pthread_mutex_t *);
|
||||
int pthread_mutex_consistent(pthread_mutex_t *);
|
||||
int pthread_condattr_init(pthread_condattr_t *);
|
||||
int pthread_condattr_destroy(pthread_condattr_t *);
|
||||
int pthread_condattr_setpshared(pthread_condattr_t *, int);
|
||||
int pthread_condattr_getpshared(const pthread_condattr_t *, int *);
|
||||
int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *);
|
||||
int pthread_cond_destroy(pthread_cond_t *);
|
||||
int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
|
||||
int pthread_cond_broadcast(pthread_cond_t *);
|
||||
int pthread_cond_signal(pthread_cond_t *);
|
||||
int pthread_rwlockattr_init(pthread_rwlockattr_t *);
|
||||
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
|
||||
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int);
|
||||
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *, int *);
|
||||
int pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *);
|
||||
int pthread_rwlock_destroy(pthread_rwlock_t *);
|
||||
int pthread_rwlock_rdlock(pthread_rwlock_t *);
|
||||
int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
|
||||
int pthread_rwlock_wrlock(pthread_rwlock_t *);
|
||||
int pthread_rwlock_trywrlock(pthread_rwlock_t *);
|
||||
int pthread_rwlock_unlock(pthread_rwlock_t *);
|
||||
int pthread_key_create(pthread_key_t *, pthread_key_dtor);
|
||||
int pthread_attr_destroy(pthread_attr_t *) paramsnonnull();
|
||||
int pthread_attr_getdetachstate(const pthread_attr_t *, int *) paramsnonnull();
|
||||
int pthread_attr_getguardsize(const pthread_attr_t *, size_t *) paramsnonnull();
|
||||
int pthread_attr_getinheritsched(const pthread_attr_t *, int *) paramsnonnull();
|
||||
int pthread_attr_getschedpolicy(const pthread_attr_t *, int *) paramsnonnull();
|
||||
int pthread_attr_getscope(const pthread_attr_t *, int *) paramsnonnull();
|
||||
int pthread_attr_getstack(const pthread_attr_t *, void **, size_t *) paramsnonnull();
|
||||
int pthread_attr_getstacksize(const pthread_attr_t *, size_t *) paramsnonnull();
|
||||
int pthread_attr_init(pthread_attr_t *) paramsnonnull();
|
||||
int pthread_attr_setdetachstate(pthread_attr_t *, int) paramsnonnull();
|
||||
int pthread_attr_setguardsize(pthread_attr_t *, size_t) paramsnonnull();
|
||||
int pthread_attr_setinheritsched(pthread_attr_t *, int) paramsnonnull();
|
||||
int pthread_attr_setschedpolicy(pthread_attr_t *, int) paramsnonnull();
|
||||
int pthread_attr_setscope(pthread_attr_t *, int) paramsnonnull();
|
||||
int pthread_attr_setstack(pthread_attr_t *, void *, size_t) paramsnonnull((1));
|
||||
int pthread_attr_setstacksize(pthread_attr_t *, size_t) paramsnonnull();
|
||||
int pthread_barrier_destroy(pthread_barrier_t *) paramsnonnull();
|
||||
int pthread_barrier_init(pthread_barrier_t *, const pthread_barrierattr_t *, unsigned) paramsnonnull((1));
|
||||
int pthread_barrier_wait(pthread_barrier_t *) paramsnonnull();
|
||||
int pthread_barrierattr_destroy(pthread_barrierattr_t *) paramsnonnull();
|
||||
int pthread_barrierattr_getpshared(const pthread_barrierattr_t *, int *) paramsnonnull();
|
||||
int pthread_barrierattr_init(pthread_barrierattr_t *) paramsnonnull();
|
||||
int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int) paramsnonnull();
|
||||
int pthread_cancel(pthread_t);
|
||||
int pthread_cond_broadcast(pthread_cond_t *) paramsnonnull();
|
||||
int pthread_cond_destroy(pthread_cond_t *) paramsnonnull();
|
||||
int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *) paramsnonnull((1));
|
||||
int pthread_cond_signal(pthread_cond_t *) paramsnonnull();
|
||||
int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *) paramsnonnull();
|
||||
int pthread_condattr_destroy(pthread_condattr_t *) paramsnonnull();
|
||||
int pthread_condattr_getpshared(const pthread_condattr_t *, int *) paramsnonnull();
|
||||
int pthread_condattr_init(pthread_condattr_t *) paramsnonnull();
|
||||
int pthread_condattr_setpshared(pthread_condattr_t *, int) paramsnonnull();
|
||||
int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *) paramsnonnull((1, 3));
|
||||
int pthread_detach(pthread_t);
|
||||
int pthread_equal(pthread_t, pthread_t);
|
||||
int pthread_getattr_np(pthread_t, pthread_attr_t *) paramsnonnull();
|
||||
int pthread_getname_np(pthread_t, char *, size_t) paramsnonnull();
|
||||
int pthread_getunique_np(pthread_t, pthread_id_np_t *) paramsnonnull();
|
||||
int pthread_join(pthread_t, void **);
|
||||
int pthread_key_create(pthread_key_t *, pthread_key_dtor) paramsnonnull((1));
|
||||
int pthread_key_delete(pthread_key_t);
|
||||
int pthread_kill(pthread_t, int);
|
||||
int pthread_mutex_consistent(pthread_mutex_t *) paramsnonnull();
|
||||
int pthread_mutex_destroy(pthread_mutex_t *) paramsnonnull();
|
||||
int pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *) paramsnonnull((1));
|
||||
int pthread_mutex_lock(pthread_mutex_t *) paramsnonnull();
|
||||
int pthread_mutex_trylock(pthread_mutex_t *) paramsnonnull();
|
||||
int pthread_mutex_unlock(pthread_mutex_t *) paramsnonnull();
|
||||
int pthread_mutexattr_destroy(pthread_mutexattr_t *) paramsnonnull();
|
||||
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *, int *) paramsnonnull();
|
||||
int pthread_mutexattr_gettype(const pthread_mutexattr_t *, int *) paramsnonnull();
|
||||
int pthread_mutexattr_init(pthread_mutexattr_t *) paramsnonnull();
|
||||
int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int) paramsnonnull();
|
||||
int pthread_mutexattr_settype(pthread_mutexattr_t *, int) paramsnonnull();
|
||||
int pthread_once(pthread_once_t *, void (*)(void)) paramsnonnull();
|
||||
int pthread_orphan_np(void);
|
||||
int pthread_print_np(int, const char *, ...);
|
||||
int pthread_rwlock_destroy(pthread_rwlock_t *) paramsnonnull();
|
||||
int pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *) paramsnonnull((1));
|
||||
int pthread_rwlock_rdlock(pthread_rwlock_t *) paramsnonnull();
|
||||
int pthread_rwlock_tryrdlock(pthread_rwlock_t *) paramsnonnull();
|
||||
int pthread_rwlock_trywrlock(pthread_rwlock_t *) paramsnonnull();
|
||||
int pthread_rwlock_unlock(pthread_rwlock_t *) paramsnonnull();
|
||||
int pthread_rwlock_wrlock(pthread_rwlock_t *) paramsnonnull();
|
||||
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *) paramsnonnull();
|
||||
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *, int *) paramsnonnull();
|
||||
int pthread_rwlockattr_init(pthread_rwlockattr_t *) paramsnonnull();
|
||||
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int) paramsnonnull();
|
||||
int pthread_setcancelstate(int, int *);
|
||||
int pthread_setcanceltype(int, int *);
|
||||
int pthread_setname_np(pthread_t, const char *) paramsnonnull();
|
||||
int pthread_setschedprio(pthread_t, int);
|
||||
int pthread_setspecific(pthread_key_t, const void *);
|
||||
int pthread_spin_destroy(pthread_spinlock_t *) paramsnonnull();
|
||||
int pthread_spin_init(pthread_spinlock_t *, int) paramsnonnull();
|
||||
int pthread_spin_lock(pthread_spinlock_t *) paramsnonnull();
|
||||
int pthread_spin_trylock(pthread_spinlock_t *) paramsnonnull();
|
||||
int pthread_spin_unlock(pthread_spinlock_t *) paramsnonnull();
|
||||
int pthread_testcancel_np(void);
|
||||
int pthread_tryjoin_np(pthread_t, void **);
|
||||
int pthread_yield(void);
|
||||
pthread_id_np_t pthread_getthreadid_np(void);
|
||||
pthread_t pthread_self(void) pureconst;
|
||||
void *pthread_getspecific(pthread_key_t);
|
||||
int pthread_barrierattr_init(pthread_barrierattr_t *);
|
||||
int pthread_barrierattr_destroy(pthread_barrierattr_t *);
|
||||
int pthread_barrierattr_getpshared(const pthread_barrierattr_t *, int *);
|
||||
int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int);
|
||||
int pthread_barrier_wait(pthread_barrier_t *);
|
||||
int pthread_barrier_destroy(pthread_barrier_t *);
|
||||
int pthread_barrier_init(pthread_barrier_t *, const pthread_barrierattr_t *,
|
||||
unsigned);
|
||||
void _pthread_cleanup_pop(struct _pthread_cleanup_buffer *, int);
|
||||
void _pthread_cleanup_push(struct _pthread_cleanup_buffer *, void (*)(void *),
|
||||
void *);
|
||||
void pthread_cleanup_pop(struct _pthread_cleanup_buffer *, int) paramsnonnull();
|
||||
void pthread_cleanup_push(struct _pthread_cleanup_buffer *, void (*)(void *), void *) paramsnonnull((1));
|
||||
void pthread_decimate_np(void);
|
||||
void pthread_exit(void *) wontreturn;
|
||||
void pthread_testcancel(void);
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
#define pthread_cleanup_push(routine, arg) \
|
||||
{ \
|
||||
struct _pthread_cleanup_buffer _buffer; \
|
||||
_pthread_cleanup_push(&_buffer, (routine), (arg));
|
||||
pthread_cleanup_push(&_buffer, (routine), (arg));
|
||||
|
||||
#define pthread_cleanup_pop(execute) \
|
||||
_pthread_cleanup_pop(&_buffer, (execute)); \
|
||||
#define pthread_cleanup_pop(execute) \
|
||||
pthread_cleanup_pop(&_buffer, (execute)); \
|
||||
}
|
||||
|
||||
#if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 && \
|
||||
|
|
|
@ -2,21 +2,26 @@
|
|||
#define COSMOPOLITAN_LIBC_INTRIN_PTHREAD2_H_
|
||||
#include "libc/calls/struct/cpuset.h"
|
||||
#include "libc/calls/struct/sched_param.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
/* clang-format off */
|
||||
|
||||
int pthread_attr_getschedparam(const pthread_attr_t *, struct sched_param *);
|
||||
int pthread_attr_setschedparam(pthread_attr_t *, const struct sched_param *);
|
||||
int pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *,
|
||||
const struct timespec *);
|
||||
int pthread_setaffinity_np(pthread_t, size_t, const cpu_set_t *);
|
||||
int pthread_getaffinity_np(pthread_t, size_t, cpu_set_t *);
|
||||
int pthread_setschedparam(pthread_t, int, const struct sched_param *);
|
||||
int pthread_getschedparam(pthread_t, int *, struct sched_param *);
|
||||
int pthread_attr_getschedparam(const pthread_attr_t *, struct sched_param *) paramsnonnull();
|
||||
int pthread_attr_getsigmask_np(const pthread_attr_t *, sigset_t *) paramsnonnull((1));
|
||||
int pthread_attr_setschedparam(pthread_attr_t *, const struct sched_param *) paramsnonnull();
|
||||
int pthread_attr_setsigmask_np(pthread_attr_t *, const sigset_t *) paramsnonnull((1));
|
||||
int pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, const struct timespec *) paramsnonnull((1, 2));
|
||||
int pthread_getaffinity_np(pthread_t, size_t, cpu_set_t *) paramsnonnull();
|
||||
int pthread_getschedparam(pthread_t, int *, struct sched_param *) paramsnonnull();
|
||||
int pthread_setaffinity_np(pthread_t, size_t, const cpu_set_t *) paramsnonnull();
|
||||
int pthread_setschedparam(pthread_t, int, const struct sched_param *) paramsnonnull();
|
||||
int pthread_timedjoin_np(pthread_t, void **, struct timespec *);
|
||||
|
||||
/* clang-format off */
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_INTRIN_PTHREAD2_H_ */
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/cp.internal.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
|
@ -37,9 +38,10 @@
|
|||
*
|
||||
* @return 0 on success, or errno on error
|
||||
* @raise ECANCELED if calling thread was cancelled in masked mode
|
||||
* @raise EBUSY if `abstime` was specified and deadline expired
|
||||
* @cancellationpoint
|
||||
*/
|
||||
errno_t _wait0(const atomic_int *ctid) {
|
||||
errno_t _wait0(const atomic_int *ctid, struct timespec *abstime) {
|
||||
int x, rc = 0;
|
||||
// "The behavior is undefined if the value specified by the thread
|
||||
// argument to pthread_join() refers to the calling thread."
|
||||
|
@ -50,9 +52,13 @@ errno_t _wait0(const atomic_int *ctid) {
|
|||
if (!(rc = pthread_testcancel_np())) {
|
||||
BEGIN_CANCELLATION_POINT;
|
||||
while ((x = atomic_load_explicit(ctid, memory_order_acquire))) {
|
||||
if (nsync_futex_wait_(ctid, x, !IsWindows(), 0) == -ECANCELED) {
|
||||
rc = nsync_futex_wait_(ctid, x, !IsWindows(), abstime);
|
||||
if (rc == -ECANCELED) {
|
||||
rc = ECANCELED;
|
||||
break;
|
||||
} else if (rc == -ETIMEDOUT) {
|
||||
rc = EBUSY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
END_CANCELLATION_POINT;
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_INTRIN_WAIT0_H_
|
||||
#define COSMOPOLITAN_LIBC_INTRIN_WAIT0_H_
|
||||
#include "libc/atomic.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
errno_t _wait0(const atomic_int *) _Hide;
|
||||
errno_t _wait0(const atomic_int *, struct timespec *) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -42,6 +42,7 @@ static const struct ContentTypeExtension {
|
|||
{"css", "text/css"}, //
|
||||
{"csv", "text/csv"}, //
|
||||
{"diff", "text/plain"}, //
|
||||
{"diff", "text/plain"}, //
|
||||
{"doc", "application/msword"}, //
|
||||
{"epub", "application/epub+zip"}, //
|
||||
{"gif", "image/gif"}, //
|
||||
|
@ -71,6 +72,7 @@ static const struct ContentTypeExtension {
|
|||
{"ogv", "video/ogg"}, //
|
||||
{"ogx", "application/ogg"}, //
|
||||
{"otf", "font/otf"}, //
|
||||
{"patch", "text/plain"}, //
|
||||
{"pdf", "application/pdf"}, //
|
||||
{"png", "image/png"}, //
|
||||
{"rar", "application/vnd.rar"}, //
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue