mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-24 23:09:02 +00:00
Make more fixes and improvements
- Fix Makefile flaking due to ZIPOBJ_FLAGS generation - Make printf() floating point and gdtoa thread safe - Polish up the runit / runitd programs some more - Prune some more makefile dependencies
This commit is contained in:
parent
3c285337a2
commit
a3865ecc3c
61 changed files with 316 additions and 132 deletions
|
@ -169,9 +169,14 @@ o/$(MODE)/usr/share/dict/words: \
|
||||||
################################################################################
|
################################################################################
|
||||||
# binaries for execve_test.com
|
# binaries for execve_test.com
|
||||||
|
|
||||||
o/$(MODE)/examples/life-nomod.com.zip.o: ZIPOBJ_FLAGS += -B
|
o/$(MODE)/examples/life-nomod.com.zip.o: o/$(MODE)/examples/life-nomod.com
|
||||||
o/$(MODE)/examples/life-classic.com.zip.o: ZIPOBJ_FLAGS += -B
|
@$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) -B $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/examples/pylife/pylife.com.zip.o: ZIPOBJ_FLAGS += -B
|
|
||||||
|
o/$(MODE)/examples/life-classic.com.zip.o: o/$(MODE)/examples/life-classic.com
|
||||||
|
@$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) -B $(OUTPUT_OPTION) $<
|
||||||
|
|
||||||
|
o/$(MODE)/examples/pylife/pylife.com.zip.o: o/$(MODE)/examples/pylife/pylife.com
|
||||||
|
@$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) -B $(OUTPUT_OPTION) $<
|
||||||
|
|
||||||
o/$(MODE)/examples/life-classic.com.dbg: \
|
o/$(MODE)/examples/life-classic.com.dbg: \
|
||||||
$(EXAMPLES_DEPS) \
|
$(EXAMPLES_DEPS) \
|
||||||
|
|
|
@ -7,7 +7,7 @@ struct timespec {
|
||||||
int64_t tv_nsec; /* nanoseconds */
|
int64_t tv_nsec; /* nanoseconds */
|
||||||
};
|
};
|
||||||
|
|
||||||
int futex(uint32_t *, int, int, const struct timespec *, uint32_t *);
|
int sys_futex(int *, int, int, const struct timespec *, int *);
|
||||||
|
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMESPEC_H_ */
|
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMESPEC_H_ */
|
||||||
|
|
|
@ -29,7 +29,9 @@ struct SprintfStr {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int vsnprintfputchar(const char *s, struct SprintfStr *t, size_t n) {
|
static int vsnprintfputchar(const char *s, struct SprintfStr *t, size_t n) {
|
||||||
if (t->i + n <= t->n) {
|
if (n == 1 && t->i < t->n) {
|
||||||
|
t->p[t->i] = s[0];
|
||||||
|
} else if (t->i + n <= t->n) {
|
||||||
memcpy(t->p + t->i, s, n);
|
memcpy(t->p + t->i, s, n);
|
||||||
} else if (t->i < t->n) {
|
} else if (t->i < t->n) {
|
||||||
memcpy(t->p + t->i, s, t->n - t->i);
|
memcpy(t->p + t->i, s, t->n - t->i);
|
||||||
|
|
37
libc/intrin/describefutexop.c
Normal file
37
libc/intrin/describefutexop.c
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*-*- 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/intrin/describeflags.internal.h"
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/nt/enum/consolemodeflags.h"
|
||||||
|
#include "libc/sysv/consts/futex.h"
|
||||||
|
|
||||||
|
const char *DescribeNtFutexOp(int x) {
|
||||||
|
const struct DescribeFlags kFutexOp[] = {
|
||||||
|
{FUTEX_WAIT_PRIVATE, "WAIT_PRIVATE"}, //
|
||||||
|
{FUTEX_WAKE_PRIVATE, "WAKE_PRIVATE"}, //
|
||||||
|
{FUTEX_REQUEUE_PRIVATE, "REQUEUE_PRIVATE"}, //
|
||||||
|
{FUTEX_PRIVATE_FLAG, "PRIVATE_FLAG"}, //
|
||||||
|
{FUTEX_REQUEUE, "REQUEUE"}, //
|
||||||
|
{FUTEX_WAIT, "WAIT"}, //
|
||||||
|
{FUTEX_WAKE, "WAKE"}, //
|
||||||
|
};
|
||||||
|
_Alignas(char) static char futexop[32];
|
||||||
|
return DescribeFlags(futexop, sizeof(futexop), kFutexOp, ARRAYLEN(kFutexOp),
|
||||||
|
"FUTEX_", x);
|
||||||
|
}
|
|
@ -44,7 +44,8 @@
|
||||||
"nopl\t%a0" \
|
"nopl\t%a0" \
|
||||||
: /* no inputs */ \
|
: /* no inputs */ \
|
||||||
: "X"(FUNC), "X"(IMAGE_BASE_VIRTUAL) \
|
: "X"(FUNC), "X"(IMAGE_BASE_VIRTUAL) \
|
||||||
: "rax", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "memory"); \
|
: "rax", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r10", \
|
||||||
|
"r11", "memory", "cc"); \
|
||||||
0; \
|
0; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -60,7 +61,8 @@
|
||||||
"nopl\t%a1" \
|
"nopl\t%a1" \
|
||||||
: "+D"(__arg) \
|
: "+D"(__arg) \
|
||||||
: "X"(FUNC), "X"(IMAGE_BASE_VIRTUAL) \
|
: "X"(FUNC), "X"(IMAGE_BASE_VIRTUAL) \
|
||||||
: "rax", "rsi", "rdx", "rcx", "r8", "r9", "memory"); \
|
: "rax", "rsi", "rdx", "rcx", "r8", "r9", "r10", "r11", \
|
||||||
|
"memory", "cc"); \
|
||||||
0; \
|
0; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,8 @@ int pthread_mutex_lock(pthread_mutex_t *mutex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
atomic_fetch_add(&mutex->waits, +1);
|
atomic_fetch_add(&mutex->waits, +1);
|
||||||
if (!IsLinux() || futex((void *)&mutex->owner, FUTEX_WAIT, owner, 0, 0)) {
|
if (!IsLinux() ||
|
||||||
|
sys_futex((void *)&mutex->owner, FUTEX_WAIT, owner, 0, 0)) {
|
||||||
if (++tries & 7) {
|
if (++tries & 7) {
|
||||||
__builtin_ia32_pause();
|
__builtin_ia32_pause();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -38,7 +38,7 @@ int pthread_mutex_unlock(pthread_mutex_t *mutex) {
|
||||||
atomic_store_explicit(&mutex->owner, 0, memory_order_relaxed);
|
atomic_store_explicit(&mutex->owner, 0, memory_order_relaxed);
|
||||||
if (IsLinux() &&
|
if (IsLinux() &&
|
||||||
atomic_load_explicit(&mutex->waits, memory_order_acquire)) {
|
atomic_load_explicit(&mutex->waits, memory_order_acquire)) {
|
||||||
futex((void *)&mutex->owner, FUTEX_WAKE, 1, 0, 0);
|
sys_futex((void *)&mutex->owner, FUTEX_WAKE, 1, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -24,5 +24,5 @@
|
||||||
* @threadsafe
|
* @threadsafe
|
||||||
*/
|
*/
|
||||||
int(getc)(FILE *f) {
|
int(getc)(FILE *f) {
|
||||||
return getc(f);
|
return fgetc(f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
.include "o/libc/sysv/macros.internal.inc"
|
|
||||||
.scall futex,0xfff053fffffff0ca,globl
|
|
2
libc/sysv/calls/sys_futex.s
Normal file
2
libc/sysv/calls/sys_futex.s
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.include "o/libc/sysv/macros.internal.inc"
|
||||||
|
.scall sys_futex,0xfff053fffffff0ca,globl,hidden
|
|
@ -100,7 +100,7 @@ scall sys_kill 0x02507a025202503e globl hidden # kill(pid, sig, 1) b/c xnu
|
||||||
scall sys_killpg 0xffffff092fffffff globl hidden
|
scall sys_killpg 0xffffff092fffffff globl hidden
|
||||||
scall sys_clone 0x11fffffffffff038 globl hidden
|
scall sys_clone 0x11fffffffffff038 globl hidden
|
||||||
scall sys_tkill 0x13e0771b121690c8 globl hidden # thr_kill() on freebsd; _lwp_kill() on netbsd; thrkill() on openbsd where arg3 should be 0; bsdthread_terminate() on XNU which only has 1 arg
|
scall sys_tkill 0x13e0771b121690c8 globl hidden # thr_kill() on freebsd; _lwp_kill() on netbsd; thrkill() on openbsd where arg3 should be 0; bsdthread_terminate() on XNU which only has 1 arg
|
||||||
scall futex 0xfff053fffffff0ca globl
|
scall sys_futex 0xfff053fffffff0ca globl hidden
|
||||||
scall set_robust_list 0xfffffffffffff111 globl
|
scall set_robust_list 0xfffffffffffff111 globl
|
||||||
scall get_robust_list 0xfffffffffffff112 globl
|
scall get_robust_list 0xfffffffffffff112 globl
|
||||||
scall sys_uname 0xffffff0a4ffff03f globl hidden
|
scall sys_uname 0xffffff0a4ffff03f globl hidden
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/fmt/fmt.h"
|
#include "libc/fmt/fmt.h"
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/runtime/gc.internal.h"
|
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
|
@ -19,5 +19,5 @@
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
char g_fixturename[256];
|
char g_fixturename[256];
|
||||||
unsigned g_testlib_ran;
|
_Atomic(unsigned) g_testlib_ran;
|
||||||
unsigned g_testlib_failed;
|
_Atomic(unsigned) g_testlib_failed;
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#define COSMOPOLITAN_LIBC_TESTLIB_H_
|
#define COSMOPOLITAN_LIBC_TESTLIB_H_
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/runtime/gc.internal.h"
|
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/testlib/ugly.h"
|
#include "libc/testlib/ugly.h"
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
|
@ -318,8 +317,8 @@ extern char g_fixturename[256];
|
||||||
extern char g_testlib_olddir[PATH_MAX];
|
extern char g_testlib_olddir[PATH_MAX];
|
||||||
extern char g_testlib_tmpdir[PATH_MAX];
|
extern char g_testlib_tmpdir[PATH_MAX];
|
||||||
extern bool g_testlib_shoulddebugbreak; /* set by testmain */
|
extern bool g_testlib_shoulddebugbreak; /* set by testmain */
|
||||||
extern unsigned g_testlib_ran; /* set by wrappers */
|
extern _Atomic(unsigned) g_testlib_ran; /* set by wrappers */
|
||||||
extern unsigned g_testlib_failed; /* set by wrappers */
|
extern _Atomic(unsigned) g_testlib_failed; /* set by wrappers */
|
||||||
extern const char *testlib_showerror_errno; /* set by macros */
|
extern const char *testlib_showerror_errno; /* set by macros */
|
||||||
extern const char *testlib_showerror_file; /* set by macros */
|
extern const char *testlib_showerror_file; /* set by macros */
|
||||||
extern const char *testlib_showerror_func; /* set by macros */
|
extern const char *testlib_showerror_func; /* set by macros */
|
||||||
|
|
|
@ -56,7 +56,7 @@ int cthread_join(cthread_t td, void **exitcode) {
|
||||||
if (~atomic_fetch_add(&td->state, cthread_joining) & cthread_finished) {
|
if (~atomic_fetch_add(&td->state, cthread_joining) & cthread_finished) {
|
||||||
while ((x = atomic_load(&td->tid))) {
|
while ((x = atomic_load(&td->tid))) {
|
||||||
// FUTEX_WAIT_PRIVATE makes it hang
|
// FUTEX_WAIT_PRIVATE makes it hang
|
||||||
cthread_memory_wait32((uint32_t *)&td->tid, x, 0);
|
cthread_memory_wait32(&td->tid, x, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (exitcode) {
|
if (exitcode) {
|
||||||
|
|
|
@ -70,8 +70,8 @@ int cthread_sem_init(cthread_sem_t *, int);
|
||||||
int cthread_sem_destroy(cthread_sem_t *);
|
int cthread_sem_destroy(cthread_sem_t *);
|
||||||
int cthread_sem_wait(cthread_sem_t *, int, const struct timespec *);
|
int cthread_sem_wait(cthread_sem_t *, int, const struct timespec *);
|
||||||
int cthread_sem_signal(cthread_sem_t *);
|
int cthread_sem_signal(cthread_sem_t *);
|
||||||
int cthread_memory_wait32(uint32_t *, uint32_t, const struct timespec *);
|
int cthread_memory_wait32(int *, int, const struct timespec *);
|
||||||
int cthread_memory_wake32(uint32_t *, int);
|
int cthread_memory_wake32(int *, int);
|
||||||
void cthread_zombies_add(cthread_t);
|
void cthread_zombies_add(cthread_t);
|
||||||
void cthread_zombies_reap(void);
|
void cthread_zombies_reap(void);
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,11 @@
|
||||||
#include "libc/thread/freebsd.internal.h"
|
#include "libc/thread/freebsd.internal.h"
|
||||||
#include "libc/thread/thread.h"
|
#include "libc/thread/thread.h"
|
||||||
|
|
||||||
int cthread_memory_wait32(uint32_t* addr, uint32_t val,
|
int cthread_memory_wait32(int* addr, int val, const struct timespec* timeout) {
|
||||||
const struct timespec* timeout) {
|
|
||||||
size_t size;
|
size_t size;
|
||||||
struct _umtx_time *put, ut;
|
struct _umtx_time *put, ut;
|
||||||
if (IsLinux() || IsOpenbsd()) {
|
if (IsLinux() || IsOpenbsd()) {
|
||||||
return futex(addr, FUTEX_WAIT, val, timeout, 0);
|
return sys_futex(addr, FUTEX_WAIT, val, timeout, 0);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
} else if (IsFreebsd()) {
|
} else if (IsFreebsd()) {
|
||||||
|
@ -59,9 +58,9 @@ int cthread_memory_wait32(uint32_t* addr, uint32_t val,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cthread_memory_wake32(uint32_t* addr, int n) {
|
int cthread_memory_wake32(int* addr, int n) {
|
||||||
if (IsLinux() || IsOpenbsd()) {
|
if (IsLinux() || IsOpenbsd()) {
|
||||||
return futex(addr, FUTEX_WAKE, n, 0, 0);
|
return sys_futex(addr, FUTEX_WAKE, n, 0, 0);
|
||||||
#if 0
|
#if 0
|
||||||
} else if (IsFreebsd()) {
|
} else if (IsFreebsd()) {
|
||||||
return _umtx_op(addr, UMTX_OP_MUTEX_WAKE, n, 0, 0);
|
return _umtx_op(addr, UMTX_OP_MUTEX_WAKE, n, 0, 0);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "libc/fmt/bing.internal.h"
|
#include "libc/fmt/bing.internal.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/testlib/ezbench.h"
|
#include "libc/testlib/ezbench.h"
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "libc/fmt/fmt.h"
|
#include "libc/fmt/fmt.h"
|
||||||
#include "libc/log/check.h"
|
#include "libc/log/check.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "libc/calls/struct/rlimit.h"
|
#include "libc/calls/struct/rlimit.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/sysv/consts/rlimit.h"
|
#include "libc/sysv/consts/rlimit.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/popcnt.h"
|
#include "libc/bits/popcnt.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
void SetUp(void) {
|
void SetUp(void) {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/fmt/conv.h"
|
#include "libc/fmt/conv.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
#define BASENAME(x) basename(gc(strdup(x)))
|
#define BASENAME(x) basename(gc(strdup(x)))
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/fmt/leb128.h"
|
#include "libc/fmt/leb128.h"
|
||||||
#include "libc/limits.h"
|
#include "libc/limits.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
TEST(zleb64, testZero) {
|
TEST(zleb64, testZero) {
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "libc/log/libfatal.internal.h"
|
#include "libc/log/libfatal.internal.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/nexgen32e/gettls.h"
|
#include "libc/nexgen32e/gettls.h"
|
||||||
#include "libc/nexgen32e/threaded.h"
|
#include "libc/nexgen32e/threaded.h"
|
||||||
|
|
|
@ -76,10 +76,13 @@ o/$(MODE)/test/libc/log/backtrace.com.dbg: \
|
||||||
$(APE_NO_MODIFY_SELF)
|
$(APE_NO_MODIFY_SELF)
|
||||||
@$(APELINK)
|
@$(APELINK)
|
||||||
|
|
||||||
o/$(MODE)/test/libc/log/backtrace.com.zip.o \
|
o/$(MODE)/test/libc/log/backtrace.com.zip.o: \
|
||||||
o/$(MODE)/test/libc/log/backtrace.com.dbg.zip.o: \
|
o/$(MODE)/test/libc/log/backtrace.com
|
||||||
ZIPOBJ_FLAGS += \
|
@$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) -B $(OUTPUT_OPTION) $<
|
||||||
-B
|
|
||||||
|
o/$(MODE)/test/libc/log/backtrace.com.dbg.zip.o: \
|
||||||
|
o/$(MODE)/test/libc/log/backtrace.com.dbg
|
||||||
|
@$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) -B $(OUTPUT_OPTION) $<
|
||||||
|
|
||||||
.PHONY: o/$(MODE)/test/libc/log
|
.PHONY: o/$(MODE)/test/libc/log
|
||||||
o/$(MODE)/test/libc/log: \
|
o/$(MODE)/test/libc/log: \
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/log/libfatal.internal.h"
|
#include "libc/log/libfatal.internal.h"
|
||||||
#include "libc/mem/arena.h"
|
#include "libc/mem/arena.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/stdio/append.internal.h"
|
#include "libc/stdio/append.internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/testlib/ezbench.h"
|
#include "libc/testlib/ezbench.h"
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/rand/rand.h"
|
#include "libc/rand/rand.h"
|
||||||
#include "libc/runtime/cxaatexit.internal.h"
|
#include "libc/runtime/cxaatexit.internal.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/runtime/memtrack.internal.h"
|
#include "libc/runtime/memtrack.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/nexgen32e/nexgen32e.h"
|
#include "libc/nexgen32e/nexgen32e.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
void *_memset(void *, int, size_t) asm("memset");
|
void *_memset(void *, int, size_t) asm("memset");
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/nexgen32e/nexgen32e.h"
|
#include "libc/nexgen32e/nexgen32e.h"
|
||||||
#include "libc/rand/rand.h"
|
#include "libc/rand/rand.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/testlib/ezbench.h"
|
#include "libc/testlib/ezbench.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/rand/rand.h"
|
#include "libc/rand/rand.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#define THREADS 8
|
#define THREADS 8
|
||||||
#define ENTRIES 1024
|
#define ENTRIES 1024
|
||||||
|
|
||||||
uint32_t ready;
|
int ready;
|
||||||
volatile uint64_t A[THREADS * ENTRIES];
|
volatile uint64_t A[THREADS * ENTRIES];
|
||||||
|
|
||||||
void OnChld(int sig) {
|
void OnChld(int sig) {
|
||||||
|
@ -109,7 +109,7 @@ TEST(rand64, testThreadSafety_doesntProduceIdenticalValues) {
|
||||||
for (i = 0; i < THREADS; ++i) {
|
for (i = 0; i < THREADS; ++i) {
|
||||||
while ((j = atomic_load((uint32_t *)(tls[i] + 0x38)))) {
|
while ((j = atomic_load((uint32_t *)(tls[i] + 0x38)))) {
|
||||||
// FUTEX_WAIT_PRIVATE makes it hang
|
// FUTEX_WAIT_PRIVATE makes it hang
|
||||||
cthread_memory_wait32((uint32_t *)(tls[i] + 0x38), j, 0);
|
cthread_memory_wait32((int *)(tls[i] + 0x38), j, 0);
|
||||||
}
|
}
|
||||||
EXPECT_SYS(0, 0, munmap(stacks[i], GetStackSize()));
|
EXPECT_SYS(0, 0, munmap(stacks[i], GetStackSize()));
|
||||||
free(tls[i]);
|
free(tls[i]);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "libc/intrin/kprintf.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/sysv/consts/map.h"
|
#include "libc/sysv/consts/map.h"
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
#include "libc/sysv/consts/af.h"
|
#include "libc/sysv/consts/af.h"
|
||||||
|
|
62
test/libc/stdio/dtoa_test.c
Normal file
62
test/libc/stdio/dtoa_test.c
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/fmt/fmt.h"
|
||||||
|
#include "libc/intrin/spinlock.h"
|
||||||
|
#include "libc/math.h"
|
||||||
|
#include "libc/runtime/stack.h"
|
||||||
|
#include "libc/stdio/stdio.h"
|
||||||
|
#include "libc/sysv/consts/clone.h"
|
||||||
|
#include "libc/sysv/consts/map.h"
|
||||||
|
#include "libc/sysv/consts/prot.h"
|
||||||
|
#include "libc/testlib/testlib.h"
|
||||||
|
#include "libc/x/x.h"
|
||||||
|
|
||||||
|
#define THREADS 16
|
||||||
|
|
||||||
|
char *stack[THREADS];
|
||||||
|
char tls[THREADS][64];
|
||||||
|
|
||||||
|
int Worker(void *p) {
|
||||||
|
int i;
|
||||||
|
char str[64];
|
||||||
|
for (i = 0; i < 256; ++i) {
|
||||||
|
bzero(str, sizeof(str));
|
||||||
|
snprintf(str, sizeof(str), "%.15g", atan2(-1., -.5));
|
||||||
|
ASSERT_STREQ("-2.0344439357957", str);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(dtoa, test) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < THREADS; ++i) {
|
||||||
|
clone(Worker,
|
||||||
|
(stack[i] = mmap(0, GetStackSize(), PROT_READ | PROT_WRITE,
|
||||||
|
MAP_STACK | MAP_ANONYMOUS, -1, 0)),
|
||||||
|
GetStackSize(),
|
||||||
|
CLONE_THREAD | CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
|
||||||
|
CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | CLONE_SETTLS,
|
||||||
|
0, 0, __initialize_tls(tls[i]), sizeof(tls[i]),
|
||||||
|
(int *)(tls[i] + 0x38));
|
||||||
|
}
|
||||||
|
for (i = 0; i < THREADS; ++i) {
|
||||||
|
_spinlock((int *)(tls[i] + 0x38));
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/stdio/hex.internal.h"
|
#include "libc/stdio/hex.internal.h"
|
||||||
#include "libc/testlib/ezbench.h"
|
#include "libc/testlib/ezbench.h"
|
||||||
#include "libc/testlib/hyperion.h"
|
#include "libc/testlib/hyperion.h"
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/log/check.h"
|
#include "libc/log/check.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
|
@ -35,6 +35,7 @@ TEST_LIBC_STDIO_DIRECTDEPS = \
|
||||||
LIBC_STR \
|
LIBC_STR \
|
||||||
LIBC_STUBS \
|
LIBC_STUBS \
|
||||||
LIBC_SYSV \
|
LIBC_SYSV \
|
||||||
|
LIBC_TINYMATH \
|
||||||
LIBC_TESTLIB \
|
LIBC_TESTLIB \
|
||||||
LIBC_TIME \
|
LIBC_TIME \
|
||||||
LIBC_LOG \
|
LIBC_LOG \
|
||||||
|
|
|
@ -177,6 +177,7 @@ BENCH(vappendf, bench) {
|
||||||
const char t[] = {0};
|
const char t[] = {0};
|
||||||
char *b = 0;
|
char *b = 0;
|
||||||
EZBENCH2("appendf", donothing, appendf(&b, "hello"));
|
EZBENCH2("appendf", donothing, appendf(&b, "hello"));
|
||||||
|
EZBENCH2("kappendf", donothing, kappendf(&b, "hello"));
|
||||||
free(b), b = 0;
|
free(b), b = 0;
|
||||||
EZBENCH2("appends", donothing, appends(&b, "hello"));
|
EZBENCH2("appends", donothing, appends(&b, "hello"));
|
||||||
free(b), b = 0;
|
free(b), b = 0;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/alg/alg.h"
|
#include "libc/alg/alg.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/rand/rand.h"
|
#include "libc/rand/rand.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/testlib/ezbench.h"
|
#include "libc/testlib/ezbench.h"
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/str/oldutf16.internal.h"
|
#include "libc/str/oldutf16.internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/testlib/ezbench.h"
|
#include "libc/testlib/ezbench.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/testlib/ezbench.h"
|
#include "libc/testlib/ezbench.h"
|
||||||
#include "libc/testlib/hyperion.h"
|
#include "libc/testlib/hyperion.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/testlib/ezbench.h"
|
#include "libc/testlib/ezbench.h"
|
||||||
#include "libc/testlib/hyperion.h"
|
#include "libc/testlib/hyperion.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
#include "net/http/escape.h"
|
#include "net/http/escape.h"
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/testlib/ezbench.h"
|
#include "libc/testlib/ezbench.h"
|
||||||
#include "libc/testlib/hyperion.h"
|
#include "libc/testlib/hyperion.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/limits.h"
|
#include "libc/limits.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/rand/rand.h"
|
#include "libc/rand/rand.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/testlib/ezbench.h"
|
#include "libc/testlib/ezbench.h"
|
||||||
#include "libc/testlib/hyperion.h"
|
#include "libc/testlib/hyperion.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
#include "tool/args/args.h"
|
#include "tool/args/args.h"
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/testlib/ezbench.h"
|
#include "libc/testlib/ezbench.h"
|
||||||
|
|
|
@ -80,10 +80,8 @@ o/$(MODE)/test/tool/plinko/%.com.dbg: \
|
||||||
o/$(MODE)/test/tool/plinko/plinko_test.com.runs: \
|
o/$(MODE)/test/tool/plinko/plinko_test.com.runs: \
|
||||||
QUOTA = -M100g
|
QUOTA = -M100g
|
||||||
|
|
||||||
o/$(MODE)/test/tool/plinko/algebra_test.lisp.zip.o \
|
o/$(MODE)/test/tool/plinko/algebra_test.lisp.zip.o: ZIPOBJ_FLAGS += -B
|
||||||
o/$(MODE)/test/tool/plinko/library_test.lisp.zip.o: \
|
o/$(MODE)/test/tool/plinko/library_test.lisp.zip.o: ZIPOBJ_FLAGS += -B
|
||||||
ZIPOBJ_FLAGS += \
|
|
||||||
-B
|
|
||||||
|
|
||||||
.PHONY: o/$(MODE)/test/tool/plinko
|
.PHONY: o/$(MODE)/test/tool/plinko
|
||||||
o/$(MODE)/test/tool/plinko: \
|
o/$(MODE)/test/tool/plinko: \
|
||||||
|
|
3
third_party/gdtoa/gdtoa.internal.h
vendored
3
third_party/gdtoa/gdtoa.internal.h
vendored
|
@ -348,9 +348,8 @@ typedef struct ThInfo {
|
||||||
#define Bcopy(x, y) \
|
#define Bcopy(x, y) \
|
||||||
memcpy(&x->sign, &y->sign, y->wds * sizeof(ULong) + 2 * sizeof(int))
|
memcpy(&x->sign, &y->sign, y->wds * sizeof(ULong) + 2 * sizeof(int))
|
||||||
|
|
||||||
hidden extern char *__gdtoa_dtoa_result;
|
|
||||||
hidden extern const double __gdtoa_bigtens[];
|
|
||||||
hidden extern const double __gdtoa_tens[];
|
hidden extern const double __gdtoa_tens[];
|
||||||
|
hidden extern const double __gdtoa_bigtens[];
|
||||||
hidden extern const double __gdtoa_tinytens[];
|
hidden extern const double __gdtoa_tinytens[];
|
||||||
hidden extern const unsigned char __gdtoa_hexdig[];
|
hidden extern const unsigned char __gdtoa_hexdig[];
|
||||||
hidden extern const char *const __gdtoa_InfName[6];
|
hidden extern const char *const __gdtoa_InfName[6];
|
||||||
|
|
30
third_party/gdtoa/lock.c
vendored
Normal file
30
third_party/gdtoa/lock.c
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*-*- 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/intrin/pthread.h"
|
||||||
|
#include "third_party/gdtoa/lock.h"
|
||||||
|
|
||||||
|
static pthread_mutex_t __gdtoa_lock_obj;
|
||||||
|
|
||||||
|
int(__gdtoa_lock)(void) {
|
||||||
|
return pthread_mutex_lock(&__gdtoa_lock_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
int(__gdtoa_unlock)(void) {
|
||||||
|
return pthread_mutex_unlock(&__gdtoa_lock_obj);
|
||||||
|
}
|
21
third_party/gdtoa/lock.h
vendored
Normal file
21
third_party/gdtoa/lock.h
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef COSMOPOLITAN_THIRD_PARTY_GDTOA_LOCK_H_
|
||||||
|
#define COSMOPOLITAN_THIRD_PARTY_GDTOA_LOCK_H_
|
||||||
|
#include "libc/intrin/nopl.h"
|
||||||
|
#include "libc/nexgen32e/threaded.h"
|
||||||
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
int __gdtoa_lock(void);
|
||||||
|
int __gdtoa_unlock(void);
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && !defined(__llvm__) && !defined(__STRICT_ANSI__)
|
||||||
|
#define __gdtoa_lock() _NOPL0("__threadcalls", __gdtoa_lock)
|
||||||
|
#define __gdtoa_unlock() _NOPL0("__threadcalls", __gdtoa_unlock)
|
||||||
|
#else
|
||||||
|
#define __gdtoa_lock() (__threaded ? __gdtoa_lock() : 0)
|
||||||
|
#define __gdtoa_unlock() (__threaded ? __gdtoa_unlock() : 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
#endif /* COSMOPOLITAN_THIRD_PARTY_GDTOA_LOCK_H_ */
|
65
third_party/gdtoa/misc.c
vendored
65
third_party/gdtoa/misc.c
vendored
|
@ -33,6 +33,7 @@
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "third_party/gdtoa/gdtoa.internal.h"
|
#include "third_party/gdtoa/gdtoa.internal.h"
|
||||||
|
#include "third_party/gdtoa/lock.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static ThInfo TI0;
|
static ThInfo TI0;
|
||||||
|
@ -46,68 +47,62 @@ __gdtoa_Brelease(Bigint *rv)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Bclear(void)
|
__gdtoa_Bclear(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
__gdtoa_lock();
|
||||||
for (i = 0; i < ARRAYLEN(TI0.Freelist); ++i)
|
for (i = 0; i < ARRAYLEN(TI0.Freelist); ++i)
|
||||||
__gdtoa_Brelease(TI0.Freelist[i]);
|
__gdtoa_Brelease(TI0.Freelist[i]);
|
||||||
bzero(&TI0.Freelist, sizeof(TI0.Freelist));
|
__gdtoa_Brelease(TI0.P5s);
|
||||||
|
bzero(&TI0, sizeof(TI0));
|
||||||
|
__gdtoa_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((__constructor__)) static void
|
||||||
|
__gdtoa_Binit(void)
|
||||||
|
{
|
||||||
|
atexit(__gdtoa_Bclear);
|
||||||
|
TI0.P5s = __gdtoa_i2b(625);
|
||||||
|
TI0.P5s->next = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bigint *
|
Bigint *
|
||||||
__gdtoa_Balloc(int k)
|
__gdtoa_Balloc(int k)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
int x;
|
int x;
|
||||||
Bigint *rv;
|
Bigint *rv;
|
||||||
x = 1 << k;
|
__gdtoa_lock();
|
||||||
rv = (Bigint *)malloc(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
|
||||||
rv->k = k;
|
|
||||||
rv->maxwds = x;
|
|
||||||
rv->sign = 0;
|
|
||||||
rv->wds = 0;
|
|
||||||
return rv;
|
|
||||||
#else
|
|
||||||
int x;
|
|
||||||
Bigint *rv;
|
|
||||||
static char once;
|
|
||||||
if (!once) {
|
|
||||||
atexit(Bclear);
|
|
||||||
once = 1;
|
|
||||||
}
|
|
||||||
if (k <= Kmax && (rv = TI0.Freelist[k]) != 0) {
|
if (k <= Kmax && (rv = TI0.Freelist[k]) != 0) {
|
||||||
TI0.Freelist[k] = rv->next;
|
TI0.Freelist[k] = rv->next;
|
||||||
} else {
|
} else {
|
||||||
x = 1 << k;
|
x = 1 << k;
|
||||||
rv = (Bigint *)malloc(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
rv = malloc(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
||||||
rv->k = k;
|
rv->k = k;
|
||||||
rv->maxwds = x;
|
rv->maxwds = x;
|
||||||
}
|
}
|
||||||
rv->sign = 0;
|
rv->sign = 0;
|
||||||
rv->wds = 0;
|
rv->wds = 0;
|
||||||
|
__gdtoa_unlock();
|
||||||
return rv;
|
return rv;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
__gdtoa_Bfree(Bigint *v)
|
__gdtoa_Bfree(Bigint *v)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
free(v);
|
|
||||||
#else
|
|
||||||
if (v) {
|
if (v) {
|
||||||
if (v->k > Kmax) {
|
if (v->k > Kmax) {
|
||||||
free((void*)v);
|
free(v);
|
||||||
} else {
|
} else {
|
||||||
|
__gdtoa_lock();
|
||||||
v->next = TI0.Freelist[v->k];
|
v->next = TI0.Freelist[v->k];
|
||||||
TI0.Freelist[v->k] = v;
|
TI0.Freelist[v->k] = v;
|
||||||
|
__gdtoa_unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Bigint *
|
Bigint * /* multiply by m and add a */
|
||||||
__gdtoa_multadd(Bigint *b, int m, int a) /* multiply by m and add a */
|
__gdtoa_multadd(Bigint *b, int m, int a)
|
||||||
{
|
{
|
||||||
int i, wds;
|
int i, wds;
|
||||||
ULong *x;
|
ULong *x;
|
||||||
|
@ -192,27 +187,18 @@ __gdtoa_mult(Bigint *a, Bigint *b)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
__gdtoa_pow5mult_destroy(void) {
|
|
||||||
__gdtoa_Brelease(TI0.P5s);
|
|
||||||
TI0.P5s = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bigint *
|
Bigint *
|
||||||
__gdtoa_pow5mult(Bigint *b, int k)
|
__gdtoa_pow5mult(Bigint *b, int k)
|
||||||
{
|
{
|
||||||
Bigint *b1, *p5, *p51;
|
|
||||||
int i;
|
int i;
|
||||||
|
Bigint *b1, *p5, *p51;
|
||||||
static const int p05[3] = { 5, 25, 125 };
|
static const int p05[3] = { 5, 25, 125 };
|
||||||
if ((i = k & 3))
|
if ((i = k & 3))
|
||||||
b = __gdtoa_multadd(b, p05[i-1], 0);
|
b = __gdtoa_multadd(b, p05[i-1], 0);
|
||||||
if (!(k >>= 2))
|
if (!(k >>= 2))
|
||||||
return b;
|
return b;
|
||||||
if (!(p5 = TI0.P5s)) {
|
__gdtoa_lock();
|
||||||
p5 = TI0.P5s = __gdtoa_i2b(625);
|
p5 = TI0.P5s;
|
||||||
p5->next = 0;
|
|
||||||
atexit(__gdtoa_pow5mult_destroy);
|
|
||||||
}
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (k & 1) {
|
if (k & 1) {
|
||||||
b1 = __gdtoa_mult(b, p5);
|
b1 = __gdtoa_mult(b, p5);
|
||||||
|
@ -227,6 +213,7 @@ __gdtoa_pow5mult(Bigint *b, int k)
|
||||||
}
|
}
|
||||||
p5 = p51;
|
p5 = p51;
|
||||||
}
|
}
|
||||||
|
__gdtoa_unlock();
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
third_party/python/python.mk
vendored
4
third_party/python/python.mk
vendored
|
@ -293,7 +293,7 @@ THIRD_PARTY_PYTHON_INCS = \
|
||||||
THIRD_PARTY_PYTHON_STAGE1_A_SRCS = \
|
THIRD_PARTY_PYTHON_STAGE1_A_SRCS = \
|
||||||
third_party/python/Modules/_tracemalloc.c \
|
third_party/python/Modules/_tracemalloc.c \
|
||||||
third_party/python/Modules/faulthandler.c \
|
third_party/python/Modules/faulthandler.c \
|
||||||
third_party/python/Objects/abstract.c \
|
third_party/python/Objects/abstract.c \
|
||||||
third_party/python/Modules/fspath.c \
|
third_party/python/Modules/fspath.c \
|
||||||
third_party/python/Modules/gcmodule.c \
|
third_party/python/Modules/gcmodule.c \
|
||||||
third_party/python/Modules/getbuildinfo.c \
|
third_party/python/Modules/getbuildinfo.c \
|
||||||
|
@ -305,7 +305,7 @@ THIRD_PARTY_PYTHON_STAGE1_A_SRCS = \
|
||||||
third_party/python/Objects/bytes_methods.c \
|
third_party/python/Objects/bytes_methods.c \
|
||||||
third_party/python/Objects/bytesobject.c \
|
third_party/python/Objects/bytesobject.c \
|
||||||
third_party/python/Objects/capsule.c \
|
third_party/python/Objects/capsule.c \
|
||||||
third_party/python/Objects/call.c \
|
third_party/python/Objects/call.c \
|
||||||
third_party/python/Objects/cellobject.c \
|
third_party/python/Objects/cellobject.c \
|
||||||
third_party/python/Objects/classobject.c \
|
third_party/python/Objects/classobject.c \
|
||||||
third_party/python/Objects/codeobject.c \
|
third_party/python/Objects/codeobject.c \
|
||||||
|
|
|
@ -190,12 +190,15 @@ TryAgain:
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Send(int *pipes, int pipescount, const void *output, size_t outputsize) {
|
bool Send(int tmpfd, const void *output, size_t outputsize) {
|
||||||
bool okall;
|
bool ok;
|
||||||
int rc, i, have;
|
char *zbuf;
|
||||||
|
size_t zsize;
|
||||||
|
int rc, have;
|
||||||
static bool once;
|
static bool once;
|
||||||
static z_stream zs;
|
static z_stream zs;
|
||||||
char *zbuf = gc(malloc(PIPE_BUF));
|
zsize = 32768;
|
||||||
|
zbuf = gc(malloc(zsize));
|
||||||
if (!once) {
|
if (!once) {
|
||||||
CHECK_EQ(Z_OK, deflateInit2(&zs, 4, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
|
CHECK_EQ(Z_OK, deflateInit2(&zs, 4, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
|
||||||
Z_DEFAULT_STRATEGY));
|
Z_DEFAULT_STRATEGY));
|
||||||
|
@ -203,25 +206,24 @@ bool Send(int *pipes, int pipescount, const void *output, size_t outputsize) {
|
||||||
}
|
}
|
||||||
zs.next_in = output;
|
zs.next_in = output;
|
||||||
zs.avail_in = outputsize;
|
zs.avail_in = outputsize;
|
||||||
okall = true;
|
ok = true;
|
||||||
do {
|
do {
|
||||||
zs.avail_out = PIPE_BUF;
|
zs.avail_out = zsize;
|
||||||
zs.next_out = (unsigned char *)zbuf;
|
zs.next_out = (unsigned char *)zbuf;
|
||||||
rc = deflate(&zs, Z_SYNC_FLUSH);
|
rc = deflate(&zs, Z_SYNC_FLUSH);
|
||||||
CHECK_NE(Z_STREAM_ERROR, rc);
|
CHECK_NE(Z_STREAM_ERROR, rc);
|
||||||
have = PIPE_BUF - zs.avail_out;
|
have = zsize - zs.avail_out;
|
||||||
for (i = 0; i < pipescount; ++i) {
|
rc = write(tmpfd, zbuf, have);
|
||||||
rc = write(pipes[i * 2 + 1], zbuf, have);
|
if (rc != have) {
|
||||||
if (rc != have) {
|
DEBUGF("write(%d, %d) → %d", tmpfd, have, rc);
|
||||||
DEBUGF("write(%d, %d) → %d", pipes[i * 2 + 1], have, rc);
|
ok = false;
|
||||||
okall = false;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} while (!zs.avail_out);
|
} while (!zs.avail_out);
|
||||||
return okall;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SendRequest(int *pipes, int pipescount) {
|
bool SendRequest(int tmpfd) {
|
||||||
int fd;
|
int fd;
|
||||||
char *p;
|
char *p;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -249,17 +251,14 @@ bool SendRequest(int *pipes, int pipescount) {
|
||||||
q = mempcpy(q, name, namesize);
|
q = mempcpy(q, name, namesize);
|
||||||
assert(hdrsize == q - hdr);
|
assert(hdrsize == q - hdr);
|
||||||
okall = true;
|
okall = true;
|
||||||
okall &= Send(pipes, pipescount, hdr, hdrsize);
|
okall &= Send(tmpfd, hdr, hdrsize);
|
||||||
okall &= Send(pipes, pipescount, p, progsize);
|
okall &= Send(tmpfd, p, progsize);
|
||||||
CHECK_NE(-1, munmap(p, st.st_size));
|
CHECK_NE(-1, munmap(p, st.st_size));
|
||||||
CHECK_NE(-1, close(fd));
|
CHECK_NE(-1, close(fd));
|
||||||
for (i = 0; i < pipescount; ++i) {
|
|
||||||
okall &= !close(pipes[i * 2 + 1]);
|
|
||||||
}
|
|
||||||
return okall;
|
return okall;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RelayRequest(void) {
|
void RelayRequest(void) {
|
||||||
int i, rc, have, transferred;
|
int i, rc, have, transferred;
|
||||||
char *buf = gc(malloc(PIPE_BUF));
|
char *buf = gc(malloc(PIPE_BUF));
|
||||||
for (transferred = 0;;) {
|
for (transferred = 0;;) {
|
||||||
|
@ -281,7 +280,6 @@ bool RelayRequest(void) {
|
||||||
TlsDie("relay request failed to flush", rc);
|
TlsDie("relay request failed to flush", rc);
|
||||||
}
|
}
|
||||||
close(13);
|
close(13);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Recv(unsigned char *p, size_t n) {
|
bool Recv(unsigned char *p, size_t n) {
|
||||||
|
@ -351,16 +349,17 @@ int RunOnHost(char *spec) {
|
||||||
1);
|
1);
|
||||||
if (!strchr(g_hostname, '.')) strcat(g_hostname, ".test.");
|
if (!strchr(g_hostname, '.')) strcat(g_hostname, ".test.");
|
||||||
DEBUGF("connecting to %s port %d", g_hostname, g_runitdport);
|
DEBUGF("connecting to %s port %d", g_hostname, g_runitdport);
|
||||||
do {
|
for (;;) {
|
||||||
for (;;) {
|
Connect();
|
||||||
Connect();
|
EzFd(g_sock);
|
||||||
EzFd(g_sock);
|
if (!(rc = EzHandshake2())) {
|
||||||
if (!EzHandshake2()) break;
|
break;
|
||||||
WARNF("warning: got connection reset in handshake");
|
|
||||||
close(g_sock);
|
|
||||||
}
|
}
|
||||||
} while ((rc = RelayRequest()) == -1 || (rc = ReadResponse()) == -1);
|
WARNF("got reset in handshake -0x%04x", rc);
|
||||||
return rc;
|
close(g_sock);
|
||||||
|
}
|
||||||
|
RelayRequest();
|
||||||
|
return ReadResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsParallelBuild(void) {
|
bool IsParallelBuild(void) {
|
||||||
|
@ -373,12 +372,20 @@ bool ShouldRunInParralel(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int SpawnSubprocesses(int argc, char *argv[]) {
|
int SpawnSubprocesses(int argc, char *argv[]) {
|
||||||
|
const char *tpath;
|
||||||
sigset_t chldmask, savemask;
|
sigset_t chldmask, savemask;
|
||||||
|
int i, rc, ws, pid, tmpfd, *pids, exitcode;
|
||||||
struct sigaction ignore, saveint, savequit;
|
struct sigaction ignore, saveint, savequit;
|
||||||
int i, rc, ws, pid, *pids, *pipes, exitcode;
|
|
||||||
char *args[5] = {argv[0], argv[1], argv[2]};
|
char *args[5] = {argv[0], argv[1], argv[2]};
|
||||||
argc -= 3;
|
|
||||||
argv += 3;
|
// create compressed network request ahead of time
|
||||||
|
CHECK_NE(-1, (tmpfd = open(
|
||||||
|
(tpath = gc(xasprintf(
|
||||||
|
"%s/runit.%d", firstnonnull(getenv("TMPDIR"), "/tmp"),
|
||||||
|
getpid()))),
|
||||||
|
O_WRONLY | O_CREAT | O_TRUNC, 0755)));
|
||||||
|
CHECK(SendRequest(tmpfd));
|
||||||
|
CHECK_NE(-1, close(tmpfd));
|
||||||
|
|
||||||
// fork off 𝑛 subprocesses for each host on which we run binary.
|
// fork off 𝑛 subprocesses for each host on which we run binary.
|
||||||
// what's important here is htop in tree mode will report like:
|
// what's important here is htop in tree mode will report like:
|
||||||
|
@ -389,8 +396,10 @@ int SpawnSubprocesses(int argc, char *argv[]) {
|
||||||
// └─runit.com netbsd
|
// └─runit.com netbsd
|
||||||
//
|
//
|
||||||
// That way when one hangs, it's easy to know what o/s it is.
|
// That way when one hangs, it's easy to know what o/s it is.
|
||||||
|
argc -= 3;
|
||||||
|
argv += 3;
|
||||||
|
exitcode = 0;
|
||||||
pids = calloc(argc, sizeof(int));
|
pids = calloc(argc, sizeof(int));
|
||||||
pipes = calloc(argc, sizeof(int) * 2);
|
|
||||||
ignore.sa_flags = 0;
|
ignore.sa_flags = 0;
|
||||||
ignore.sa_handler = SIG_IGN;
|
ignore.sa_handler = SIG_IGN;
|
||||||
sigemptyset(&ignore.sa_mask);
|
sigemptyset(&ignore.sa_mask);
|
||||||
|
@ -401,26 +410,18 @@ int SpawnSubprocesses(int argc, char *argv[]) {
|
||||||
sigprocmask(SIG_BLOCK, &chldmask, &savemask);
|
sigprocmask(SIG_BLOCK, &chldmask, &savemask);
|
||||||
for (i = 0; i < argc; ++i) {
|
for (i = 0; i < argc; ++i) {
|
||||||
args[3] = argv[i];
|
args[3] = argv[i];
|
||||||
CHECK_NE(-1, pipe2(pipes + i * 2, O_CLOEXEC));
|
|
||||||
CHECK_NE(-1, (pids[i] = vfork()));
|
CHECK_NE(-1, (pids[i] = vfork()));
|
||||||
if (!pids[i]) {
|
if (!pids[i]) {
|
||||||
dup2(pipes[i * 2], 13);
|
dup2(open(tpath, O_RDONLY | O_CLOEXEC), 13);
|
||||||
sigaction(SIGINT, &(struct sigaction){0}, 0);
|
sigaction(SIGINT, &(struct sigaction){0}, 0);
|
||||||
sigaction(SIGQUIT, &(struct sigaction){0}, 0);
|
sigaction(SIGQUIT, &(struct sigaction){0}, 0);
|
||||||
sigprocmask(SIG_SETMASK, &savemask, 0);
|
sigprocmask(SIG_SETMASK, &savemask, 0);
|
||||||
execve(args[0], args, environ); // for htop
|
execve(args[0], args, environ); // for htop
|
||||||
_Exit(127);
|
_Exit(127);
|
||||||
}
|
}
|
||||||
close(pipes[i * 2]); // close reader
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the smart part is we only do the expensive deflate operation from
|
// wait for children to terminate
|
||||||
// the main process we assume file descriptor 13 is safely inherited
|
|
||||||
static z_stream zs;
|
|
||||||
sigaction(SIGPIPE, &ignore, 0);
|
|
||||||
exitcode = SendRequest(pipes, argc) ? 0 : 150;
|
|
||||||
|
|
||||||
// now wait for the children to terminate
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((pid = wait(&ws)) == -1) {
|
if ((pid = wait(&ws)) == -1) {
|
||||||
if (errno == EINTR) continue;
|
if (errno == EINTR) continue;
|
||||||
|
@ -443,10 +444,10 @@ int SpawnSubprocesses(int argc, char *argv[]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CHECK_NE(-1, unlink(tpath));
|
||||||
sigprocmask(SIG_SETMASK, &savemask, 0);
|
sigprocmask(SIG_SETMASK, &savemask, 0);
|
||||||
sigaction(SIGQUIT, &savequit, 0);
|
sigaction(SIGQUIT, &savequit, 0);
|
||||||
sigaction(SIGINT, &saveint, 0);
|
sigaction(SIGINT, &saveint, 0);
|
||||||
free(pipes);
|
|
||||||
free(pids);
|
free(pids);
|
||||||
return exitcode;
|
return exitcode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -267,7 +267,7 @@ void SendOutputFragmentMessage(enum RunitCommand kind, unsigned char *buf,
|
||||||
|
|
||||||
void Recv(void *output, size_t outputsize) {
|
void Recv(void *output, size_t outputsize) {
|
||||||
int rc;
|
int rc;
|
||||||
ssize_t tx, chunk, received;
|
ssize_t tx, chunk, received, totalgot;
|
||||||
static bool once;
|
static bool once;
|
||||||
static int zstatus;
|
static int zstatus;
|
||||||
static char buf[32768];
|
static char buf[32768];
|
||||||
|
@ -282,6 +282,7 @@ void Recv(void *output, size_t outputsize) {
|
||||||
CHECK_EQ(Z_OK, inflateInit(&zs));
|
CHECK_EQ(Z_OK, inflateInit(&zs));
|
||||||
once = true;
|
once = true;
|
||||||
}
|
}
|
||||||
|
totalgot = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (rbuf.len >= outputsize) {
|
if (rbuf.len >= outputsize) {
|
||||||
tx = MIN(outputsize, rbuf.len);
|
tx = MIN(outputsize, rbuf.len);
|
||||||
|
@ -312,6 +313,7 @@ void Recv(void *output, size_t outputsize) {
|
||||||
close(g_clifd);
|
close(g_clifd);
|
||||||
TlsDie("read failed", received);
|
TlsDie("read failed", received);
|
||||||
}
|
}
|
||||||
|
totalgot += received;
|
||||||
// decompress packet completely
|
// decompress packet completely
|
||||||
// into a dynamical size buffer
|
// into a dynamical size buffer
|
||||||
zs.avail_in = received;
|
zs.avail_in = received;
|
||||||
|
@ -331,12 +333,14 @@ void Recv(void *output, size_t outputsize) {
|
||||||
CHECK_NE(Z_STREAM_ERROR, zstatus);
|
CHECK_NE(Z_STREAM_ERROR, zstatus);
|
||||||
switch (zstatus) {
|
switch (zstatus) {
|
||||||
case Z_NEED_DICT:
|
case Z_NEED_DICT:
|
||||||
zstatus = Z_DATA_ERROR; // make negative
|
WARNF("tls recv Z_NEED_DICT %ld total %ld", received, totalgot);
|
||||||
// fallthrough
|
exit(1);
|
||||||
case Z_DATA_ERROR:
|
case Z_DATA_ERROR:
|
||||||
|
WARNF("tls recv Z_DATA_ERROR %ld total %ld", received, totalgot);
|
||||||
|
exit(1);
|
||||||
case Z_MEM_ERROR:
|
case Z_MEM_ERROR:
|
||||||
close(g_clifd);
|
WARNF("tls recv Z_MEM_ERROR %ld total %ld", received, totalgot);
|
||||||
FATALF("tls recv zlib hard error %d", zstatus);
|
exit(1);
|
||||||
case Z_BUF_ERROR:
|
case Z_BUF_ERROR:
|
||||||
zstatus = Z_OK; // harmless? nothing for inflate to do
|
zstatus = Z_OK; // harmless? nothing for inflate to do
|
||||||
break; // it probably just our wraparound eof
|
break; // it probably just our wraparound eof
|
||||||
|
|
|
@ -63,7 +63,6 @@ $(TOOL_PLINKO_OBJS): \
|
||||||
$(BUILD_FILES) \
|
$(BUILD_FILES) \
|
||||||
tool/plinko/plinko.mk
|
tool/plinko/plinko.mk
|
||||||
|
|
||||||
o/$(MODE)/tool/plinko/plinko.com.zip.o \
|
|
||||||
o/$(MODE)/tool/plinko/lib/library.lisp.zip.o \
|
o/$(MODE)/tool/plinko/lib/library.lisp.zip.o \
|
||||||
o/$(MODE)/tool/plinko/lib/binarytrees.lisp.zip.o \
|
o/$(MODE)/tool/plinko/lib/binarytrees.lisp.zip.o \
|
||||||
o/$(MODE)/tool/plinko/lib/algebra.lisp.zip.o \
|
o/$(MODE)/tool/plinko/lib/algebra.lisp.zip.o \
|
||||||
|
@ -72,6 +71,10 @@ o/$(MODE)/tool/plinko/lib/ok.lisp.zip.o: \
|
||||||
ZIPOBJ_FLAGS += \
|
ZIPOBJ_FLAGS += \
|
||||||
-B
|
-B
|
||||||
|
|
||||||
|
o/$(MODE)/tool/plinko/plinko.com.zip.o: \
|
||||||
|
o/$(MODE)/tool/plinko/plinko.com
|
||||||
|
@$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) -B $(OUTPUT_OPTION) $<
|
||||||
|
|
||||||
.PHONY: o/$(MODE)/tool/plinko
|
.PHONY: o/$(MODE)/tool/plinko
|
||||||
o/$(MODE)/tool/plinko: $(TOOL_PLINKO_BINS) $(TOOL_PLINKO_CHECKS)
|
o/$(MODE)/tool/plinko: $(TOOL_PLINKO_BINS) $(TOOL_PLINKO_CHECKS)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue