mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-28 07:18:30 +00:00
Improve redbean
- Improve serialization - Add Benchmark() API to redbean - Refactor UNIX API to be assert() friendly - Make the redbean Lua REPL print data structures - Fix recent regressions in linenoise reverse search - Add -i flag so redbean can be a language interpreter
This commit is contained in:
parent
2046c0d2ae
commit
451e3f73d9
74 changed files with 1781 additions and 1024 deletions
|
@ -119,6 +119,9 @@ int fsync(int);
|
|||
int ftruncate(int, int64_t);
|
||||
int getdents(unsigned, void *, unsigned, long *);
|
||||
int getdomainname(char *, size_t);
|
||||
int getegid(void) nosideeffect;
|
||||
int geteuid(void) nosideeffect;
|
||||
int getgid(void) nosideeffect;
|
||||
int gethostname(char *, size_t);
|
||||
int getloadavg(double *, int);
|
||||
int getpgid(int);
|
||||
|
@ -130,6 +133,7 @@ int getrlimit(int, struct rlimit *);
|
|||
int getrusage(int, struct rusage *);
|
||||
int getsid(int) nosideeffect;
|
||||
int gettid(void);
|
||||
int getuid(void) nosideeffect;
|
||||
int kill(int, int);
|
||||
int killpg(int, int);
|
||||
int link(const char *, const char *) dontthrow;
|
||||
|
@ -196,6 +200,7 @@ int sysinfo(struct sysinfo *);
|
|||
int touch(const char *, uint32_t);
|
||||
int truncate(const char *, uint64_t);
|
||||
int ttyname_r(int, char *, size_t);
|
||||
int umask(int);
|
||||
int uname(struct utsname *);
|
||||
int unlink(const char *);
|
||||
int unlink_s(const char **);
|
||||
|
@ -226,11 +231,6 @@ ssize_t splice(int, int64_t *, int, int64_t *, size_t, uint32_t);
|
|||
ssize_t vmsplice(int, const struct iovec *, int64_t, uint32_t);
|
||||
ssize_t write(int, const void *, size_t);
|
||||
struct dirent *readdir(DIR *);
|
||||
uint32_t getegid(void) nosideeffect;
|
||||
uint32_t geteuid(void) nosideeffect;
|
||||
uint32_t getgid(void) nosideeffect;
|
||||
uint32_t getuid(void) nosideeffect;
|
||||
uint32_t umask(uint32_t);
|
||||
void rewinddir(DIR *);
|
||||
void sync(void);
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@ o/$(MODE)/libc/calls/execlp.o \
|
|||
o/$(MODE)/libc/calls/execve-nt.o \
|
||||
o/$(MODE)/libc/calls/execve-sysv.o \
|
||||
o/$(MODE)/libc/calls/readlinkat-nt.o \
|
||||
o/$(MODE)/libc/calls/describeopenflags.greg.o \
|
||||
o/$(MODE)/libc/calls/mkntenvblock.o: \
|
||||
OVERRIDE_CPPFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
|
38
libc/calls/describeclockname.c
Normal file
38
libc/calls/describeclockname.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*-*- 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/fmt/itoa.h"
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
|
||||
/**
|
||||
* Describes clock_gettime() clock argument.
|
||||
*/
|
||||
char *DescribeClockName(int x) {
|
||||
int i;
|
||||
char *s;
|
||||
_Alignas(char) static char buf[32];
|
||||
if ((s = GetMagnumStr(kClockNames, x))) {
|
||||
stpcpy(stpcpy(buf, "CLOCK_"), s);
|
||||
return buf;
|
||||
} else {
|
||||
FormatInt32(buf, x);
|
||||
return buf;
|
||||
}
|
||||
}
|
41
libc/calls/describeopenflags.greg.c
Normal file
41
libc/calls/describeopenflags.greg.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*-*- 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/fmt/itoa.h"
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
|
||||
/**
|
||||
* Describes clock_gettime() clock argument.
|
||||
*/
|
||||
char *DescribeOpenFlags(int x) {
|
||||
char *s;
|
||||
int i, n;
|
||||
struct DescribeFlags *d;
|
||||
_Alignas(char) static char openflags[128];
|
||||
// TODO(jart): unify DescribeFlags and MagnumStr data structures
|
||||
for (n = 0; kOpenFlags[n].x != MAGNUM_TERMINATOR;) ++n;
|
||||
d = alloca(n * sizeof(struct DescribeFlags));
|
||||
for (i = 0; i < n; ++i) {
|
||||
d[i].flag = MAGNUM_NUMBER(kOpenFlags, i);
|
||||
d[i].name = MAGNUM_STRING(kOpenFlags, i);
|
||||
}
|
||||
return DescribeFlags(openflags, sizeof(openflags), d, n, "O_", x);
|
||||
}
|
|
@ -28,6 +28,7 @@
|
|||
*/
|
||||
int32_t sys_fstatat(int32_t dirfd, const char *path, struct stat *st,
|
||||
int32_t flags) {
|
||||
int rc;
|
||||
void *p;
|
||||
union metastat ms;
|
||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
* Returns effective group ID of calling process.
|
||||
* @return group id
|
||||
*/
|
||||
uint32_t getegid(void) {
|
||||
int getegid(void) {
|
||||
int rc;
|
||||
if (!IsWindows()) {
|
||||
rc = sys_getegid();
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* Returns effective user ID of calling process.
|
||||
* @return user id
|
||||
*/
|
||||
uint32_t geteuid(void) {
|
||||
int geteuid(void) {
|
||||
int rc;
|
||||
if (!IsWindows()) {
|
||||
rc = sys_geteuid();
|
||||
|
|
|
@ -51,7 +51,7 @@ static textwindows dontinline uint32_t GetUserNameHash(void) {
|
|||
* @asyncsignalsafe
|
||||
* @vforksafe
|
||||
*/
|
||||
uint32_t getuid(void) {
|
||||
int getuid(void) {
|
||||
int rc;
|
||||
if (!IsWindows()) {
|
||||
rc = sys_getuid();
|
||||
|
@ -71,7 +71,7 @@ uint32_t getuid(void) {
|
|||
* @asyncsignalsafe
|
||||
* @vforksafe
|
||||
*/
|
||||
uint32_t getgid(void) {
|
||||
int getgid(void) {
|
||||
int rc;
|
||||
if (!IsWindows()) {
|
||||
rc = sys_getgid();
|
||||
|
|
47
libc/calls/kclocknames.S
Normal file
47
libc/calls/kclocknames.S
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 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/fmt/magnumstrs.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.macro .e e s
|
||||
.long \e - kClockNames
|
||||
.long 1f - kClockNames
|
||||
.rodata.str1.1
|
||||
1: .string "\s"
|
||||
.previous
|
||||
.endm
|
||||
|
||||
.section .rodata
|
||||
.align 4
|
||||
.underrun
|
||||
kClockNames:
|
||||
.e CLOCK_REALTIME,"REALTIME"
|
||||
.e CLOCK_MONOTONIC,"MONOTONIC"
|
||||
.e CLOCK_MONOTONIC_RAW,"MONOTONIC_RAW"
|
||||
.e CLOCK_REALTIME_COARSE,"REALTIME_COARSE"
|
||||
.e CLOCK_MONOTONIC_COARSE,"MONOTONIC_COARSE"
|
||||
.e CLOCK_PROCESS_CPUTIME_ID,"PROCESS_CPUTIME_ID"
|
||||
.e CLOCK_TAI,"TAI"
|
||||
.e CLOCK_PROF,"PROF"
|
||||
.e CLOCK_BOOTTIME,"BOOTTIME"
|
||||
.e CLOCK_REALTIME_ALARM,"REALTIME_ALARM"
|
||||
.e CLOCK_BOOTTIME_ALARM,"BOOTTIME_ALARM"
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kClockNames,globl,hidden
|
||||
.overrun
|
64
libc/calls/kopenflags.S
Normal file
64
libc/calls/kopenflags.S
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 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/fmt/magnumstrs.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.macro .e e s
|
||||
.long \e - kOpenFlags
|
||||
.long 1f - kOpenFlags
|
||||
.rodata.str1.1
|
||||
1: .string "\s"
|
||||
.previous
|
||||
.endm
|
||||
|
||||
.section .rodata
|
||||
.align 4
|
||||
.underrun
|
||||
kOpenFlags:
|
||||
.e O_RDWR,"RDWR" // order matters
|
||||
.e O_RDONLY,"RDONLY" //
|
||||
.e O_WRONLY,"WRONLY" //
|
||||
.e O_ACCMODE,"ACCMODE" // mask of prev three
|
||||
.e O_CREAT,"CREAT" //
|
||||
.e O_EXCL,"EXCL" //
|
||||
.e O_TRUNC,"TRUNC" //
|
||||
.e O_CLOEXEC,"CLOEXEC" //
|
||||
.e O_DIRECT,"DIRECT" // no-op on xnu/openbsd
|
||||
.e O_APPEND,"APPEND" // weird on nt
|
||||
.e O_TMPFILE,"TMPFILE" // linux, windows
|
||||
.e O_NOFOLLOW,"NOFOLLOW" // unix
|
||||
.e O_SYNC,"SYNC" // unix
|
||||
.e O_ASYNC,"ASYNC" // unix
|
||||
.e O_NOCTTY,"NOCTTY" // unix
|
||||
.e O_NOATIME,"NOATIME" // linux
|
||||
.e O_EXEC,"EXEC" // free/openbsd
|
||||
.e O_SEARCH,"SEARCH" // free/netbsd
|
||||
.e O_DSYNC,"DSYNC" // linux/xnu/open/netbsd
|
||||
.e O_RSYNC,"RSYNC" // linux/open/netbsd
|
||||
.e O_PATH,"PATH" // linux
|
||||
.e O_VERIFY,"VERIFY" // freebsd
|
||||
.e O_SHLOCK,"SHLOCK" // bsd
|
||||
.e O_EXLOCK,"EXLOCK" // bsd
|
||||
.e O_RANDOM,"RANDOM" // windows
|
||||
.e O_SEQUENTIAL,"SEQUENTIAL" // windows
|
||||
.e O_COMPRESSED,"COMPRESSED" // windows
|
||||
.e O_INDEXED,"INDEXED" // windows
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kOpenFlags,globl,hidden
|
||||
.overrun
|
|
@ -21,6 +21,7 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -74,7 +75,8 @@ int openat(int dirfd, const char *file, int flags, ...) {
|
|||
} else {
|
||||
rc = efault();
|
||||
}
|
||||
STRACE("openat(%s, %#s, %#x, %#o) → %d% m", __strace_dirfd(buf, dirfd), file,
|
||||
flags, (flags & (O_CREAT | O_TMPFILE)) ? mode : 0, rc);
|
||||
STRACE("openat(%s, %#s, %s, %#o) → %d% m", __strace_dirfd(buf, dirfd), file,
|
||||
DescribeOpenFlags(flags), (flags & (O_CREAT | O_TMPFILE)) ? mode : 0,
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
* @return previous mask
|
||||
* @note always succeeds
|
||||
*/
|
||||
unsigned umask(unsigned newmask) {
|
||||
unsigned oldmask;
|
||||
int umask(int newmask) {
|
||||
int oldmask;
|
||||
if (!IsWindows()) {
|
||||
oldmask = sys_umask(newmask);
|
||||
} else {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.macro .e e s
|
||||
|
@ -115,6 +116,6 @@ kErrnoDocs:
|
|||
.e ENOTRECOVERABLE,"State not recoverable"
|
||||
.e ENONET,"Machine is not on the network"
|
||||
.e ERESTART,"Interrupted system call should be restarted"
|
||||
.long -123
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kErrnoDocs,globl,hidden
|
||||
.overrun
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.macro .e e
|
||||
|
@ -27,7 +28,7 @@
|
|||
.endm
|
||||
|
||||
.section .rodata
|
||||
.align 4
|
||||
.align 4
|
||||
.underrun
|
||||
kErrnoNames:
|
||||
.e EINVAL
|
||||
|
@ -116,6 +117,6 @@ kErrnoNames:
|
|||
.e ENONET
|
||||
.e ERESTART
|
||||
.e ENODATA
|
||||
.long -123
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kErrnoNames,globl,hidden
|
||||
.overrun
|
||||
|
|
|
@ -1,22 +1,35 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_FMT_MAGNUMSTRS_H_
|
||||
#define COSMOPOLITAN_LIBC_FMT_MAGNUMSTRS_H_
|
||||
|
||||
#define MAGNUM_TERMINATOR -123
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define MAGNUM_NUMBER(TABLE, INDEX) \
|
||||
*(const int *)((uintptr_t)TABLE + TABLE[INDEX].x)
|
||||
|
||||
#define MAGNUM_STRING(TABLE, INDEX) \
|
||||
(const char *)((uintptr_t)TABLE + TABLE[INDEX].s)
|
||||
|
||||
struct MagnumStr {
|
||||
int x, s;
|
||||
};
|
||||
|
||||
extern const struct MagnumStr kErrnoDocs[];
|
||||
extern const struct MagnumStr kErrnoNames[];
|
||||
extern const struct MagnumStr kIpOptnames[];
|
||||
extern const struct MagnumStr kSignalNames[];
|
||||
extern const struct MagnumStr kSockOptnames[];
|
||||
extern const struct MagnumStr kTcpOptnames[];
|
||||
hidden extern const struct MagnumStr kClockNames[];
|
||||
hidden extern const struct MagnumStr kErrnoDocs[];
|
||||
hidden extern const struct MagnumStr kErrnoNames[];
|
||||
hidden extern const struct MagnumStr kIpOptnames[];
|
||||
hidden extern const struct MagnumStr kOpenFlags[];
|
||||
hidden extern const struct MagnumStr kSignalNames[];
|
||||
hidden extern const struct MagnumStr kSockOptnames[];
|
||||
hidden extern const struct MagnumStr kTcpOptnames[];
|
||||
|
||||
const char *DescribeSockLevel(int);
|
||||
const char *DescribeSockOptname(int, int);
|
||||
const char *GetMagnumStr(const struct MagnumStr *, int);
|
||||
char *DescribeClockName(int) hidden;
|
||||
char *DescribeOpenFlags(int) hidden;
|
||||
char *DescribeSockLevel(int) hidden;
|
||||
char *DescribeSockOptname(int, int) hidden;
|
||||
char *GetMagnumStr(const struct MagnumStr *, int) hidden;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* Converts errno value to descriptive sentence.
|
||||
* @return non-null rodata string or null if not found
|
||||
*/
|
||||
const char *strerdoc(int x) {
|
||||
char *strerdoc(int x) {
|
||||
if (x) {
|
||||
return GetMagnumStr(kErrnoDocs, x);
|
||||
} else {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* Converts errno value to symbolic name.
|
||||
* @return non-null rodata string or null if not found
|
||||
*/
|
||||
const char *strerrno(int x) {
|
||||
char *strerrno(int x) {
|
||||
if (x) {
|
||||
return GetMagnumStr(kErrnoNames, x);
|
||||
} else {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "libc/sysv/consts/prot.h"
|
||||
|
||||
const char *DescribeMapFlags(int x) {
|
||||
static char mapflags[256];
|
||||
_Alignas(char) static char mapflags[256];
|
||||
const struct DescribeFlags kMapFlags[] = {
|
||||
{MAP_ANONYMOUS, "ANONYMOUS"}, //
|
||||
{MAP_PRIVATE, "PRIVATE"}, //
|
||||
|
|
|
@ -34,7 +34,7 @@ static const struct DescribeFlags kConsoleModeInputFlags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeNtConsoleModeInputFlags(uint32_t x) {
|
||||
static char consolemodeinputflags[256];
|
||||
_Alignas(char) static char consolemodeinputflags[256];
|
||||
return DescribeFlags(consolemodeinputflags, sizeof(consolemodeinputflags),
|
||||
kConsoleModeInputFlags, ARRAYLEN(kConsoleModeInputFlags),
|
||||
"kNtEnable", x);
|
||||
|
|
|
@ -29,7 +29,7 @@ static const struct DescribeFlags kConsoleModeOutputFlags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeNtConsoleModeOutputFlags(uint32_t x) {
|
||||
static char consolemodeoutputflags[128];
|
||||
_Alignas(char) static char consolemodeoutputflags[128];
|
||||
return DescribeFlags(consolemodeoutputflags, sizeof(consolemodeoutputflags),
|
||||
kConsoleModeOutputFlags,
|
||||
ARRAYLEN(kConsoleModeOutputFlags), "kNt", x);
|
||||
|
|
|
@ -64,7 +64,7 @@ static const struct DescribeFlags kFileAccessflags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeNtFileAccessFlags(uint32_t x) {
|
||||
static char ntfileaccessflags[512];
|
||||
_Alignas(char) static char ntfileaccessflags[512];
|
||||
return DescribeFlags(ntfileaccessflags, sizeof(ntfileaccessflags),
|
||||
kFileAccessflags, ARRAYLEN(kFileAccessflags), "kNt", x);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ static const struct DescribeFlags kFileFlags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeNtFileFlagsAndAttributes(uint32_t x) {
|
||||
static char ntfileflags[256];
|
||||
_Alignas(char) static char ntfileflags[256];
|
||||
if (x == -1u) return "-1u";
|
||||
return DescribeFlags(ntfileflags, sizeof(ntfileflags), kFileFlags,
|
||||
ARRAYLEN(kFileFlags), "kNtFile", x);
|
||||
|
|
|
@ -31,7 +31,7 @@ static const struct DescribeFlags kFileMapFlags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeNtFileMapFlags(uint32_t x) {
|
||||
static char filemapflags[64];
|
||||
_Alignas(char) static char filemapflags[64];
|
||||
return DescribeFlags(filemapflags, sizeof(filemapflags), kFileMapFlags,
|
||||
ARRAYLEN(kFileMapFlags), "kNtFileMap", x);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ static const struct DescribeFlags kFileShareflags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeNtFileShareFlags(uint32_t x) {
|
||||
static char ntfileshareflags[64];
|
||||
_Alignas(char) static char ntfileshareflags[64];
|
||||
return DescribeFlags(ntfileshareflags, sizeof(ntfileshareflags),
|
||||
kFileShareflags, ARRAYLEN(kFileShareflags),
|
||||
"kNtFileShare", x);
|
||||
|
|
|
@ -29,7 +29,7 @@ static const struct DescribeFlags kFiletypeFlags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeNtFiletypeFlags(uint32_t x) {
|
||||
static char filetypeflags[64];
|
||||
_Alignas(char) static char filetypeflags[64];
|
||||
return DescribeFlags(filetypeflags, sizeof(filetypeflags), kFiletypeFlags,
|
||||
ARRAYLEN(kFiletypeFlags), "kNtFileType", x);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ static const struct DescribeFlags kMoveFileInputFlags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeNtMoveFileInputFlags(uint32_t x) {
|
||||
static char movefileflags[256];
|
||||
_Alignas(char) static char movefileflags[256];
|
||||
return DescribeFlags(movefileflags, sizeof(movefileflags),
|
||||
kMoveFileInputFlags, ARRAYLEN(kMoveFileInputFlags),
|
||||
"kNtMovefile", x);
|
||||
|
|
|
@ -42,7 +42,7 @@ static const struct DescribeFlags kPageFlags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeNtPageFlags(uint32_t x) {
|
||||
static char pageflags[64];
|
||||
_Alignas(char) static char pageflags[64];
|
||||
return DescribeFlags(pageflags, sizeof(pageflags), kPageFlags,
|
||||
ARRAYLEN(kPageFlags), "kNt", x);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ static const struct DescribeFlags kPipeModeFlags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeNtPipeModeFlags(uint32_t x) {
|
||||
static char pipemodeflags[64];
|
||||
_Alignas(char) static char pipemodeflags[64];
|
||||
return DescribeFlags(pipemodeflags, sizeof(pipemodeflags), kPipeModeFlags,
|
||||
ARRAYLEN(kPipeModeFlags), "kNtPipe", x);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ static const struct DescribeFlags kPipeOpenFlags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeNtPipeOpenFlags(uint32_t x) {
|
||||
static char pipeopenflags[64];
|
||||
_Alignas(char) static char pipeopenflags[64];
|
||||
return DescribeFlags(pipeopenflags, sizeof(pipeopenflags), kPipeOpenFlags,
|
||||
ARRAYLEN(kPipeOpenFlags), "kNtPipeAccess", x);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ static const struct DescribeFlags kProcessAccessflags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeNtProcessAccessFlags(uint32_t x) {
|
||||
static char ntprocessaccessflags[256];
|
||||
_Alignas(char) static char ntprocessaccessflags[256];
|
||||
return DescribeFlags(ntprocessaccessflags, sizeof(ntprocessaccessflags),
|
||||
kProcessAccessflags, ARRAYLEN(kProcessAccessflags),
|
||||
"kNtProcess", x);
|
||||
|
|
|
@ -39,7 +39,7 @@ static const struct DescribeFlags kNtStartFlags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeNtStartFlags(uint32_t x) {
|
||||
static char startflags[128];
|
||||
_Alignas(char) static char startflags[128];
|
||||
return DescribeFlags(startflags, sizeof(startflags), kNtStartFlags,
|
||||
ARRAYLEN(kNtStartFlags), "kNtStartf", x);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ static const struct DescribeFlags kSymbolicLinkflags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeNtSymbolicLinkFlags(uint32_t x) {
|
||||
static char ntsymboliclinkflags[64];
|
||||
_Alignas(char) static char ntsymboliclinkflags[64];
|
||||
return DescribeFlags(ntsymboliclinkflags, sizeof(ntsymboliclinkflags),
|
||||
kSymbolicLinkflags, ARRAYLEN(kSymbolicLinkflags),
|
||||
"kNtSymbolicLinkFlag", x);
|
||||
|
|
|
@ -27,7 +27,7 @@ static const struct DescribeFlags kProtFlags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeProtFlags(int x) {
|
||||
static char protflags[64];
|
||||
_Alignas(char) static char protflags[64];
|
||||
return DescribeFlags(protflags, sizeof(protflags), kProtFlags,
|
||||
ARRAYLEN(kProtFlags), "PROT_", x);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ static const struct DescribeFlags kRemapFlags[] = {
|
|||
};
|
||||
|
||||
const char *DescribeRemapFlags(int x) {
|
||||
static char remapflags[64];
|
||||
_Alignas(char) static char remapflags[64];
|
||||
return DescribeFlags(remapflags, sizeof(remapflags), kRemapFlags,
|
||||
ARRAYLEN(kRemapFlags), "MREMAP_", x);
|
||||
}
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
|
||||
const char *GetMagnumStr(const struct MagnumStr *ms, int x) {
|
||||
char *GetMagnumStr(const struct MagnumStr *ms, int x) {
|
||||
int i;
|
||||
for (i = 0; ms[i].x != -123; ++i) {
|
||||
if (x == *(const int *)((uintptr_t)ms + ms[i].x)) {
|
||||
return (const char *)((uintptr_t)ms + ms[i].s);
|
||||
for (i = 0; ms[i].x != MAGNUM_TERMINATOR; ++i) {
|
||||
if (x == MAGNUM_NUMBER(ms, i)) {
|
||||
return MAGNUM_STRING(ms, i);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
STATIC_YOINK("__get_symbol_by_addr");
|
||||
|
||||
#define MAXLEAKS 1000
|
||||
|
||||
static bool once;
|
||||
static bool hasleaks;
|
||||
|
||||
|
@ -46,15 +48,18 @@ static noasan void CheckLeak(void *x, void *y, size_t n, void *a) {
|
|||
static noasan void OnMemory(void *x, void *y, size_t n, void *a) {
|
||||
static int i;
|
||||
if (n) {
|
||||
if (++i < 20) {
|
||||
kprintf("%p %,lu bytes [dlmalloc]", x, n);
|
||||
if (IsAsan()) {
|
||||
__asan_print_trace(x);
|
||||
if (MAXLEAKS) {
|
||||
if (i < MAXLEAKS) {
|
||||
++i;
|
||||
kprintf("%p %,lu bytes [dlmalloc]", x, n);
|
||||
if (IsAsan()) {
|
||||
__asan_print_trace(x);
|
||||
}
|
||||
kprintf("\n");
|
||||
} else if (i == MAXLEAKS) {
|
||||
++i;
|
||||
kprintf("etc. etc.\n");
|
||||
}
|
||||
kprintf("\n");
|
||||
}
|
||||
if (i == 20) {
|
||||
kprintf("etc. etc.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
13
libc/nt/struct/linger.h
Normal file
13
libc/nt/struct/linger.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_LINGER_H_
|
||||
#define COSMOPOLITAN_LIBC_NT_STRUCT_LINGER_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct linger_nt {
|
||||
uint16_t l_onoff; /* on/off */
|
||||
uint16_t l_linger; /* seconds */
|
||||
};
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_LINGER_H_ */
|
|
@ -22,7 +22,7 @@
|
|||
/**
|
||||
* Describes setsockopt() level arguments.
|
||||
*/
|
||||
const char *DescribeSockLevel(int x) {
|
||||
char *DescribeSockLevel(int x) {
|
||||
static char buf[12];
|
||||
if (x == SOL_IP) return "SOL_IP";
|
||||
if (x == SOL_TCP) return "SOL_TCP";
|
||||
|
|
|
@ -18,26 +18,32 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
|
||||
/**
|
||||
* Describes setsockopt() optname arguments.
|
||||
*/
|
||||
const char *DescribeSockOptname(int l, int x) {
|
||||
char *DescribeSockOptname(int l, int x) {
|
||||
int i;
|
||||
static char buf[12], *s;
|
||||
char *ps, *s;
|
||||
const struct MagnumStr *ms = 0;
|
||||
_Alignas(char) static char buf[32];
|
||||
if (x) {
|
||||
if (l == SOL_SOCKET) {
|
||||
ps = "SO_";
|
||||
ms = kSockOptnames;
|
||||
} else if (l == SOL_TCP) {
|
||||
ps = "TCP_";
|
||||
ms = kTcpOptnames;
|
||||
} else if (l == SOL_IP) {
|
||||
ps = "IP_";
|
||||
ms = kIpOptnames;
|
||||
}
|
||||
}
|
||||
if (ms && (s = GetMagnumStr(ms, x))) {
|
||||
return s;
|
||||
stpcpy(stpcpy(buf, ps), s);
|
||||
return buf;
|
||||
} else {
|
||||
FormatInt32(buf, x);
|
||||
return buf;
|
||||
|
|
|
@ -20,8 +20,10 @@
|
|||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/nt/struct/linger.h"
|
||||
#include "libc/nt/winsock.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/yoink.inc"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/so.h"
|
||||
|
@ -33,6 +35,7 @@ textwindows int sys_getsockopt_nt(struct Fd *fd, int level, int optname,
|
|||
uint32_t *inout_optlen) {
|
||||
uint64_t ms;
|
||||
uint32_t in_optlen;
|
||||
struct linger_nt linger;
|
||||
assert(fd->kind == kFdSocket);
|
||||
|
||||
if (out_opt_optval && inout_optlen) {
|
||||
|
@ -55,6 +58,11 @@ textwindows int sys_getsockopt_nt(struct Fd *fd, int level, int optname,
|
|||
((struct timeval *)out_opt_optval)->tv_sec = ms / 1000;
|
||||
((struct timeval *)out_opt_optval)->tv_usec = ms % 1000 * 1000;
|
||||
*inout_optlen = sizeof(struct timeval);
|
||||
} else if (optname == SO_LINGER && in_optlen == sizeof(struct linger)) {
|
||||
linger = *(struct linger_nt *)out_opt_optval;
|
||||
((struct linger *)out_opt_optval)->l_onoff = !!linger.l_onoff;
|
||||
((struct linger *)out_opt_optval)->l_linger = linger.l_linger;
|
||||
*inout_optlen = sizeof(struct linger);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,24 +16,25 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.macro .e e
|
||||
.macro .e e s
|
||||
.long \e - kIpOptnames
|
||||
.long 1f - kIpOptnames
|
||||
.rodata.str1.1
|
||||
1: .string "\e"
|
||||
1: .string "\s"
|
||||
.previous
|
||||
.endm
|
||||
|
||||
.section .rodata
|
||||
.align 4
|
||||
.align 4
|
||||
.underrun
|
||||
kIpOptnames:
|
||||
.e IP_TOS # int
|
||||
.e IP_MTU # int
|
||||
.e IP_TTL # int
|
||||
.e IP_HDRINCL # bool32
|
||||
.long -123
|
||||
.e IP_TOS,"TOS" # int
|
||||
.e IP_MTU,"MTU" # int
|
||||
.e IP_TTL,"TTL" # int
|
||||
.e IP_HDRINCL,"HDRINCL" # bool32
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kIpOptnames,globl,hidden
|
||||
.overrun
|
||||
|
|
|
@ -16,13 +16,14 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.macro .e e
|
||||
.macro .e e s
|
||||
.long \e - kSockOptnames
|
||||
.long 1f - kSockOptnames
|
||||
.rodata.str1.1
|
||||
1: .string "\e"
|
||||
1: .string "\s"
|
||||
.previous
|
||||
.endm
|
||||
|
||||
|
@ -30,20 +31,22 @@
|
|||
.align 4
|
||||
.underrun
|
||||
kSockOptnames:
|
||||
.e SO_DEBUG # bool32
|
||||
.e SO_BROADCAST # bool32
|
||||
.e SO_REUSEADDR # bool32
|
||||
.e SO_REUSEPORT # bool32
|
||||
.e SO_KEEPALIVE # bool32
|
||||
.e SO_DONTROUTE # bool32
|
||||
.e SO_RCVTIMEO # timeval
|
||||
.e SO_SNDTIMEO # timeval
|
||||
.e SO_LINGER # linger
|
||||
.e SO_SNDBUF # int
|
||||
.e SO_RCVBUF # int
|
||||
.e SO_RCVLOWAT # int
|
||||
.e SO_SNDLOWAT # int
|
||||
.e SO_ERROR # int
|
||||
.long -123
|
||||
.e SO_DEBUG,"DEBUG" # bool32
|
||||
.e SO_ACCEPTCONN,"ACCEPTCONN" # bool32
|
||||
.e SO_BROADCAST,"BROADCAST" # bool32
|
||||
.e SO_REUSEADDR,"REUSEADDR" # bool32
|
||||
.e SO_REUSEPORT,"REUSEPORT" # bool32
|
||||
.e SO_KEEPALIVE,"KEEPALIVE" # bool32
|
||||
.e SO_DONTROUTE,"DONTROUTE" # bool32
|
||||
.e SO_RCVTIMEO,"RCVTIMEO" # timeval
|
||||
.e SO_SNDTIMEO,"SNDTIMEO" # timeval
|
||||
.e SO_LINGER,"LINGER" # linger
|
||||
.e SO_TYPE,"TYPE" # int
|
||||
.e SO_SNDBUF,"SNDBUF" # int
|
||||
.e SO_RCVBUF,"RCVBUF" # int
|
||||
.e SO_RCVLOWAT,"RCVLOWAT" # int
|
||||
.e SO_SNDLOWAT,"SNDLOWAT" # int
|
||||
.e SO_ERROR,"ERROR" # int
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kSockOptnames,globl,hidden
|
||||
.overrun
|
||||
|
|
|
@ -16,33 +16,34 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.macro .e e
|
||||
.macro .e e s
|
||||
.long \e - kTcpOptnames
|
||||
.long 1f - kTcpOptnames
|
||||
.rodata.str1.1
|
||||
1: .string "\e"
|
||||
1: .string "\s"
|
||||
.previous
|
||||
.endm
|
||||
|
||||
.section .rodata
|
||||
.align 4
|
||||
.align 4
|
||||
.underrun
|
||||
kTcpOptnames:
|
||||
.e TCP_NODELAY # bool32
|
||||
.e TCP_CORK # bool32
|
||||
.e TCP_QUICKACK # bool32
|
||||
.e TCP_FASTOPEN_CONNECT # bool32
|
||||
.e TCP_DEFER_ACCEPT # bool32
|
||||
.e TCP_KEEPIDLE # int (seconds)
|
||||
.e TCP_KEEPINTVL # int (seconds)
|
||||
.e TCP_FASTOPEN # int
|
||||
.e TCP_KEEPCNT # int
|
||||
.e TCP_MAXSEG # int
|
||||
.e TCP_SYNCNT # int
|
||||
.e TCP_NOTSENT_LOWAT # int
|
||||
.e TCP_WINDOW_CLAMP # int
|
||||
.long -123
|
||||
.e TCP_NODELAY,"NODELAY" # bool32
|
||||
.e TCP_CORK,"CORK" # bool32
|
||||
.e TCP_QUICKACK,"QUICKACK" # bool32
|
||||
.e TCP_FASTOPEN_CONNECT,"FASTOPEN_CONNECT" # bool32
|
||||
.e TCP_DEFER_ACCEPT,"DEFER_ACCEPT" # bool32
|
||||
.e TCP_KEEPIDLE,"KEEPIDLE" # int (seconds)
|
||||
.e TCP_KEEPINTVL,"KEEPINTVL" # int (seconds)
|
||||
.e TCP_FASTOPEN,"FASTOPEN" # int
|
||||
.e TCP_KEEPCNT,"KEEPCNT" # int
|
||||
.e TCP_MAXSEG,"MAXSEG" # int
|
||||
.e TCP_SYNCNT,"SYNCNT" # int
|
||||
.e TCP_NOTSENT_LOWAT,"NOTSENT_LOWAT" # int
|
||||
.e TCP_WINDOW_CLAMP,"WINDOW_CLAMP" # int
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kTcpOptnames,globl,hidden
|
||||
.overrun
|
||||
|
|
|
@ -19,16 +19,12 @@
|
|||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/struct/linger.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/consts/so.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
struct linger_nt { /* Linux+XNU+BSD ABI */
|
||||
uint16_t l_onoff; /* on/off */
|
||||
uint16_t l_linger; /* seconds */
|
||||
};
|
||||
|
||||
textwindows int sys_setsockopt_nt(struct Fd *fd, int level, int optname,
|
||||
const void *optval, uint32_t optlen) {
|
||||
int64_t ms;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/paths.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.macro .e e s
|
||||
|
@ -65,6 +66,6 @@ kSignalNames:
|
|||
.e SIGRTMIN,"RTMIN"
|
||||
.e SIGEMT,"EMT"
|
||||
.e SIGPWR,"PWR"
|
||||
.long -123
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kSignalNames,globl,hidden
|
||||
.overrun
|
||||
|
|
|
@ -262,8 +262,8 @@ wint_t towctrans(wint_t, wctrans_t);
|
|||
|
||||
char *strsignal(int) returnsnonnull libcesque;
|
||||
char *strerror(int) returnsnonnull dontthrow nocallback;
|
||||
const char *strerrno(int) nosideeffect libcesque;
|
||||
const char *strerdoc(int) nosideeffect libcesque;
|
||||
char *strerrno(int) nosideeffect libcesque;
|
||||
char *strerdoc(int) nosideeffect libcesque;
|
||||
int strerror_r(int, char *, size_t) dontthrow nocallback;
|
||||
int strerror_wr(int, uint32_t, char *, size_t) dontthrow nocallback;
|
||||
|
||||
|
|
|
@ -620,7 +620,7 @@ syscon clock CLOCK_MONOTONIC_RAW 4 4 0x4000 0x4000 0x4000 4 # actu
|
|||
syscon clock CLOCK_REALTIME_COARSE 5 -1 -1 -1 -1 -1 # Linux 2.6.32+; bsd consensus; not available on RHEL5
|
||||
syscon clock CLOCK_MONOTONIC_COARSE 6 -1 -1 -1 -1 -1 # Linux 2.6.32+; bsd consensus; not available on RHEL5
|
||||
syscon clock CLOCK_PROF -1 -1 2 -1 2 -1 #
|
||||
syscon clock CLOCK_BOOTTIME 7 -1 -1 6 6 -1 #
|
||||
syscon clock CLOCK_BOOTTIME 7 -1 -1 6 -1 -1 #
|
||||
syscon clock CLOCK_REALTIME_ALARM 8 -1 -1 -1 -1 -1 #
|
||||
syscon clock CLOCK_BOOTTIME_ALARM 9 -1 -1 -1 -1 -1 #
|
||||
syscon clock CLOCK_TAI 11 -1 -1 -1 -1 -1 #
|
||||
|
@ -669,16 +669,19 @@ syscon epoll EPOLLET 0x80000000 0x80000000 0x80000000 0x80000000 0x80000
|
|||
# * -1 we define as no-op
|
||||
#
|
||||
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||
syscon so SO_DEBUG 1 1 1 1 1 1 # debugging is enabled; consensus
|
||||
syscon so SO_TYPE 3 0x1008 0x1008 0x1008 0x1008 0x1008 # bsd consensus
|
||||
syscon so SO_ERROR 4 0x1007 0x1007 0x1007 0x1007 0x1007 # takes int pointer and stores/clears the pending error code; bsd consensus
|
||||
syscon so SO_ACCEPTCONN 30 2 2 2 2 2 # takes int pointer and stores boolean indicating if listen() was called on fd; bsd consensus
|
||||
syscon so SO_REUSEPORT 15 0x0200 0x0200 0x0200 0x0200 4 # bsd consensus (NT calls it SO_REUSEADDR)
|
||||
syscon so SO_REUSEADDR 2 4 4 4 4 0 # bsd consensus (default behavior on NT)
|
||||
syscon so SO_REUSEADDR 2 4 4 4 4 4 # bsd consensus (default behavior on NT)
|
||||
syscon so SO_EXCLUSIVEADDRUSE 0 0 0 0 0 ~4 # bsd consensus (default behavior on NT)
|
||||
syscon so SO_KEEPALIVE 9 8 8 8 8 8 # bsd consensus
|
||||
syscon so SO_DONTROUTE 5 0x10 0x10 0x10 0x10 0x10 # bsd consensus
|
||||
syscon so SO_BROADCAST 6 0x20 0x20 0x20 0x20 0x20 # bsd consensus
|
||||
syscon so SO_BROADCAST 6 0x20 0x20 0x20 0x20 0x20 # socket is configured for broadcast messages; bsd consensus
|
||||
syscon so SO_USELOOPBACK 0 0x40 0x40 0x40 0x40 0x40 # bsd consensus
|
||||
syscon so SO_LINGER 13 0x80 0x80 0x80 0x80 0x80 # takes struct linger; causes close() return value to actually mean something; bsd consensus
|
||||
syscon so SO_DEBUG 1 1 1 1 1 1 # consensus
|
||||
syscon so SO_ACCEPTCONN 30 2 2 2 2 2 # takes int pointer and stores boolean indicating if listen() was called on fd; bsd consensus
|
||||
syscon so SO_ERROR 4 0x1007 0x1007 0x1007 0x1007 0x1007 # takes int pointer and stores/clears the pending error code; bsd consensus
|
||||
syscon so SO_DONTLINGER 0 0 0 0 0 ~0x80 # disables so_linger on windows
|
||||
syscon so SO_OOBINLINE 10 0x0100 0x0100 0x0100 0x0100 0x0100 # bsd consensus
|
||||
syscon so SO_SNDBUF 7 0x1001 0x1001 0x1001 0x1001 0x1001 # bsd consensus
|
||||
syscon so SO_RCVBUF 8 0x1002 0x1002 0x1002 0x1002 0x1002 # bsd consensus
|
||||
|
@ -686,7 +689,6 @@ syscon so SO_RCVTIMEO 20 0x1006 0x1006 0x1006 0x100c 0x1006 # rec
|
|||
syscon so SO_SNDTIMEO 21 0x1005 0x1005 0x1005 0x100b 0x1005 # send timeout; takes struct timeval; bsd consensus
|
||||
syscon so SO_RCVLOWAT 18 0x1004 0x1004 0x1004 0x1004 0x1004 # bsd consensus
|
||||
syscon so SO_SNDLOWAT 19 0x1003 0x1003 0x1003 0x1003 0x1003 # bsd consensus
|
||||
syscon so SO_TYPE 3 0x1008 0x1008 0x1008 0x1008 0x1008 # bsd consensus
|
||||
syscon so SO_TIMESTAMP 29 0x0400 0x0400 0x0800 0x2000 0
|
||||
syscon so SO_SETFIB 0 0 0x1014 0 0 0
|
||||
syscon so SO_DOMAIN 39 0 0x1019 0x1024 0 0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon clock,CLOCK_BOOTTIME,7,-1,-1,6,6,-1
|
||||
.syscon clock,CLOCK_BOOTTIME,7,-1,-1,6,-1,-1
|
||||
|
|
2
libc/sysv/consts/SO_DONTLINGER.S
Normal file
2
libc/sysv/consts/SO_DONTLINGER.S
Normal file
|
@ -0,0 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon so,SO_DONTLINGER,0,0,0,0,0,~0x80
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon so,SO_REUSEADDR,2,4,4,4,4,0
|
||||
.syscon so,SO_REUSEADDR,2,4,4,4,4,4
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_TESTLIB_EZBENCH_H_
|
||||
#define COSMOPOLITAN_LIBC_TESTLIB_EZBENCH_H_
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nexgen32e/bench.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/testlib/bench.h"
|
||||
|
@ -9,151 +10,162 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define EZBENCH_COUNT 128
|
||||
#define EZBENCH_TRIES 10
|
||||
|
||||
#define EZBENCH(INIT, EXPR) EZBENCH2(#EXPR, INIT, EXPR)
|
||||
|
||||
#define EZBENCH2(NAME, INIT, EXPR) \
|
||||
do { \
|
||||
int Core, Tries, Interrupts; \
|
||||
int64_t Speculative, MemoryStrict; \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
INIT; \
|
||||
EXPR; \
|
||||
Speculative = BENCHLOOP(__startbench, __endbench, 128, ({ \
|
||||
INIT; \
|
||||
polluteregisters(); \
|
||||
}), \
|
||||
(EXPR)); \
|
||||
} while (++Tries < 10 && (__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == 10) __testlib_ezbenchwarn(" speculative"); \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
INIT; \
|
||||
EXPR; \
|
||||
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 32, ({ \
|
||||
INIT; \
|
||||
thrashcodecache(); \
|
||||
polluteregisters(); \
|
||||
}), \
|
||||
(EXPR)); \
|
||||
} while (++Tries < 10 && (__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == 10) __testlib_ezbenchwarn(" memory strict"); \
|
||||
__testlib_ezbenchreport( \
|
||||
NAME, MAX(0, Speculative - __testlib_ezbenchcontrol()), \
|
||||
MAX(0, MemoryStrict - __testlib_ezbenchcontrol())); \
|
||||
#define EZBENCH2(NAME, INIT, EXPR) \
|
||||
do { \
|
||||
int Core, Tries, Interrupts; \
|
||||
int64_t Speculative, MemoryStrict; \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
INIT; \
|
||||
EXPR; \
|
||||
Speculative = BENCHLOOP(__startbench, __endbench, EZBENCH_COUNT, ({ \
|
||||
INIT; \
|
||||
__polluteregisters(); \
|
||||
}), \
|
||||
(EXPR)); \
|
||||
} while (++Tries < EZBENCH_TRIES && \
|
||||
(__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" speculative"); \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
INIT; \
|
||||
EXPR; \
|
||||
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 32, ({ \
|
||||
INIT; \
|
||||
thrashcodecache(); \
|
||||
__polluteregisters(); \
|
||||
}), \
|
||||
(EXPR)); \
|
||||
} while (++Tries < EZBENCH_TRIES && \
|
||||
(__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" memory strict"); \
|
||||
__testlib_ezbenchreport( \
|
||||
NAME, MAX(0, Speculative - __testlib_ezbenchcontrol()), \
|
||||
MAX(0, MemoryStrict - __testlib_ezbenchcontrol())); \
|
||||
} while (0)
|
||||
|
||||
#define EZBENCH3(NAME, NUM, INIT, EXPR) \
|
||||
do { \
|
||||
int Core, Tries, Interrupts; \
|
||||
int64_t Speculative, MemoryStrict; \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
INIT; \
|
||||
EXPR; \
|
||||
Speculative = BENCHLOOP(__startbench, __endbench, NUM, ({ \
|
||||
INIT; \
|
||||
polluteregisters(); \
|
||||
}), \
|
||||
(EXPR)); \
|
||||
} while (++Tries < 10 && (__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == 10) __testlib_ezbenchwarn(" speculative"); \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
INIT; \
|
||||
EXPR; \
|
||||
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, NUM, ({ \
|
||||
INIT; \
|
||||
thrashcodecache(); \
|
||||
polluteregisters(); \
|
||||
}), \
|
||||
(EXPR)); \
|
||||
} while (++Tries < 10 && (__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == 10) __testlib_ezbenchwarn(" memory strict"); \
|
||||
__testlib_ezbenchreport( \
|
||||
NAME, MAX(0, Speculative - __testlib_ezbenchcontrol()), \
|
||||
MAX(0, MemoryStrict - __testlib_ezbenchcontrol())); \
|
||||
#define EZBENCH3(NAME, NUM, INIT, EXPR) \
|
||||
do { \
|
||||
int Core, Tries, Interrupts; \
|
||||
int64_t Speculative, MemoryStrict; \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
INIT; \
|
||||
EXPR; \
|
||||
Speculative = BENCHLOOP(__startbench, __endbench, NUM, ({ \
|
||||
INIT; \
|
||||
__polluteregisters(); \
|
||||
}), \
|
||||
(EXPR)); \
|
||||
} while (++Tries < EZBENCH_TRIES && \
|
||||
(__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" speculative"); \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
INIT; \
|
||||
EXPR; \
|
||||
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, NUM, ({ \
|
||||
INIT; \
|
||||
thrashcodecache(); \
|
||||
__polluteregisters(); \
|
||||
}), \
|
||||
(EXPR)); \
|
||||
} while (++Tries < EZBENCH_TRIES && \
|
||||
(__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" memory strict"); \
|
||||
__testlib_ezbenchreport( \
|
||||
NAME, MAX(0, Speculative - __testlib_ezbenchcontrol()), \
|
||||
MAX(0, MemoryStrict - __testlib_ezbenchcontrol())); \
|
||||
} while (0)
|
||||
|
||||
#define EZBENCH_C(NAME, CONTROL, EXPR) \
|
||||
do { \
|
||||
int Core, Tries, Interrupts; \
|
||||
int64_t Control, Speculative, MemoryStrict; \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
Control = BENCHLOOP(__startbench_m, __endbench_m, 128, ({ \
|
||||
thrashcodecache(); \
|
||||
polluteregisters(); \
|
||||
}), \
|
||||
(CONTROL)); \
|
||||
} while (++Tries < 10 && (__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == 10) __testlib_ezbenchwarn(" control"); \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
EXPR; \
|
||||
Speculative = BENCHLOOP(__startbench, __endbench, 128, \
|
||||
polluteregisters(), (EXPR)); \
|
||||
} while (++Tries < 10 && (__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == 10) __testlib_ezbenchwarn(" speculative"); \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
EXPR; \
|
||||
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 8, ({ \
|
||||
thrashcodecache(); \
|
||||
polluteregisters(); \
|
||||
}), \
|
||||
(EXPR)); \
|
||||
} while (++Tries < 10 && (__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == 10) __testlib_ezbenchwarn(" memory strict"); \
|
||||
__testlib_ezbenchreport(NAME, MAX(0, Speculative - Control), \
|
||||
MAX(0, MemoryStrict - Control)); \
|
||||
#define EZBENCH_C(NAME, CONTROL, EXPR) \
|
||||
do { \
|
||||
int Core, Tries, Interrupts; \
|
||||
int64_t Control, Speculative, MemoryStrict; \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
Control = BENCHLOOP(__startbench_m, __endbench_m, EZBENCH_COUNT, ({ \
|
||||
thrashcodecache(); \
|
||||
__polluteregisters(); \
|
||||
}), \
|
||||
(CONTROL)); \
|
||||
} while (++Tries < EZBENCH_TRIES && \
|
||||
(__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" control"); \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
EXPR; \
|
||||
Speculative = BENCHLOOP(__startbench, __endbench, EZBENCH_COUNT, \
|
||||
__polluteregisters(), (EXPR)); \
|
||||
} while (++Tries < EZBENCH_TRIES && \
|
||||
(__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" speculative"); \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
EXPR; \
|
||||
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 8, ({ \
|
||||
thrashcodecache(); \
|
||||
__polluteregisters(); \
|
||||
}), \
|
||||
(EXPR)); \
|
||||
} while (++Tries < EZBENCH_TRIES && \
|
||||
(__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" memory strict"); \
|
||||
__testlib_ezbenchreport(NAME, MAX(0, Speculative - Control), \
|
||||
MAX(0, MemoryStrict - Control)); \
|
||||
} while (0)
|
||||
|
||||
#define EZBENCH_N(NAME, N, EXPR) \
|
||||
do { \
|
||||
int64_t Speculative, Toto; \
|
||||
int Core, Tries, Interrupts; \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
EXPR; \
|
||||
Speculative = \
|
||||
BENCHLOOP(__startbench, __endbench, 32, polluteregisters(), (EXPR)); \
|
||||
} while (++Tries < 10 && (__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == 10) __testlib_ezbenchwarn(""); \
|
||||
__testlib_ezbenchreport_n( \
|
||||
NAME, 'n', N, MAX(0, Speculative - __testlib_ezbenchcontrol())); \
|
||||
#define EZBENCH_N(NAME, N, EXPR) \
|
||||
do { \
|
||||
int64_t Speculative, Toto; \
|
||||
int Core, Tries, Interrupts; \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
EXPR; \
|
||||
Speculative = BENCHLOOP(__startbench, __endbench, 32, \
|
||||
__polluteregisters(), (EXPR)); \
|
||||
} while (++Tries < EZBENCH_TRIES && \
|
||||
(__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(""); \
|
||||
__testlib_ezbenchreport_n( \
|
||||
NAME, 'n', N, MAX(0, Speculative - __testlib_ezbenchcontrol())); \
|
||||
} while (0)
|
||||
|
||||
#define EZBENCH_K(NAME, K, EXPR) \
|
||||
|
@ -164,14 +176,14 @@ COSMOPOLITAN_C_START_
|
|||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
EXPR; \
|
||||
Speculative = \
|
||||
BENCHLOOP(__startbench, __endbench, 128, donothing, (EXPR)); \
|
||||
Speculative = BENCHLOOP(__startbench, __endbench, EZBENCH_COUNT, \
|
||||
donothing, (EXPR)); \
|
||||
} while (Core != __testlib_getcore()); \
|
||||
__testlib_ezbenchreport_n( \
|
||||
NAME, 'k', K, MAX(0, Speculative - __testlib_ezbenchcontrol())); \
|
||||
} while (0)
|
||||
|
||||
void polluteregisters(void);
|
||||
void __polluteregisters(void);
|
||||
void __testlib_yield(void);
|
||||
int __testlib_getcore(void);
|
||||
int64_t __testlib_getinterrupts(void);
|
||||
|
|
|
@ -19,15 +19,15 @@
|
|||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
polluteregisters:
|
||||
__polluteregisters:
|
||||
.leafprologue
|
||||
xor %eax,%eax
|
||||
mov %ecx,%ecx
|
||||
mov %edx,%edx
|
||||
mov %r8d,%r8d
|
||||
mov %r9d,%r9d
|
||||
mov %r10d,%r10d
|
||||
mov %r11d,%r11d
|
||||
xor %ecx,%ecx
|
||||
xor %edx,%edx
|
||||
xor %r8d,%r8d
|
||||
xor %r9d,%r9d
|
||||
xor %r10d,%r10d
|
||||
xor %r11d,%r11d
|
||||
testb X86_HAVE(AVX)+kCpuids(%rip)
|
||||
jz .Lsse
|
||||
vpxor %xmm0,%xmm0,%xmm0
|
||||
|
@ -48,13 +48,13 @@ polluteregisters:
|
|||
xorps %xmm6,%xmm6
|
||||
xorps %xmm7,%xmm7
|
||||
.leafepilogue
|
||||
.endfn polluteregisters,globl
|
||||
.endfn __polluteregisters,globl
|
||||
|
||||
.end
|
||||
// Fill registers with junk data to create false dependencies.
|
||||
// Which shall create the problem that happens w/o vzeroupper.
|
||||
// Or the Core Architecture errata regarding BSR/BSF w/ 64bit.
|
||||
polluteregisters:
|
||||
__polluteregisters:
|
||||
.leafprologue
|
||||
mov $-1,%rax
|
||||
mov %rax,%rcx
|
||||
|
@ -92,4 +92,4 @@ polluteregisters:
|
|||
punpcklqdq %xmm0,%xmm6
|
||||
punpcklqdq %xmm0,%xmm7
|
||||
.leafepilogue
|
||||
.endfn polluteregisters,globl
|
||||
.endfn __polluteregisters,globl
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue