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
|
||||
|
||||
o/$(MODE)/examples/life-nomod.com.zip.o: ZIPOBJ_FLAGS += -B
|
||||
o/$(MODE)/examples/life-classic.com.zip.o: ZIPOBJ_FLAGS += -B
|
||||
o/$(MODE)/examples/pylife/pylife.com.zip.o: ZIPOBJ_FLAGS += -B
|
||||
o/$(MODE)/examples/life-nomod.com.zip.o: o/$(MODE)/examples/life-nomod.com
|
||||
@$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) -B $(OUTPUT_OPTION) $<
|
||||
|
||||
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: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
|
|
|
@ -7,7 +7,7 @@ struct timespec {
|
|||
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 /* COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMESPEC_H_ */
|
||||
|
|
|
@ -29,7 +29,9 @@ struct SprintfStr {
|
|||
};
|
||||
|
||||
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);
|
||||
} else if (t->i < t->n) {
|
||||
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" \
|
||||
: /* no inputs */ \
|
||||
: "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; \
|
||||
})
|
||||
|
||||
|
@ -60,7 +61,8 @@
|
|||
"nopl\t%a1" \
|
||||
: "+D"(__arg) \
|
||||
: "X"(FUNC), "X"(IMAGE_BASE_VIRTUAL) \
|
||||
: "rax", "rsi", "rdx", "rcx", "r8", "r9", "memory"); \
|
||||
: "rax", "rsi", "rdx", "rcx", "r8", "r9", "r10", "r11", \
|
||||
"memory", "cc"); \
|
||||
0; \
|
||||
})
|
||||
|
||||
|
|
|
@ -44,7 +44,8 @@ int pthread_mutex_lock(pthread_mutex_t *mutex) {
|
|||
}
|
||||
}
|
||||
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) {
|
||||
__builtin_ia32_pause();
|
||||
} else {
|
||||
|
|
|
@ -38,7 +38,7 @@ int pthread_mutex_unlock(pthread_mutex_t *mutex) {
|
|||
atomic_store_explicit(&mutex->owner, 0, memory_order_relaxed);
|
||||
if (IsLinux() &&
|
||||
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;
|
||||
|
|
|
@ -24,5 +24,5 @@
|
|||
* @threadsafe
|
||||
*/
|
||||
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_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 futex 0xfff053fffffff0ca globl
|
||||
scall sys_futex 0xfff053fffffff0ca globl hidden
|
||||
scall set_robust_list 0xfffffffffffff111 globl
|
||||
scall get_robust_list 0xfffffffffffff112 globl
|
||||
scall sys_uname 0xffffff0a4ffff03f globl hidden
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
|
|
@ -19,5 +19,5 @@
|
|||
#include "libc/testlib/testlib.h"
|
||||
|
||||
char g_fixturename[256];
|
||||
unsigned g_testlib_ran;
|
||||
unsigned g_testlib_failed;
|
||||
_Atomic(unsigned) g_testlib_ran;
|
||||
_Atomic(unsigned) g_testlib_failed;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define COSMOPOLITAN_LIBC_TESTLIB_H_
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ugly.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
@ -318,8 +317,8 @@ extern char g_fixturename[256];
|
|||
extern char g_testlib_olddir[PATH_MAX];
|
||||
extern char g_testlib_tmpdir[PATH_MAX];
|
||||
extern bool g_testlib_shoulddebugbreak; /* set by testmain */
|
||||
extern unsigned g_testlib_ran; /* set by wrappers */
|
||||
extern unsigned g_testlib_failed; /* set by wrappers */
|
||||
extern _Atomic(unsigned) g_testlib_ran; /* 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_file; /* 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) {
|
||||
while ((x = atomic_load(&td->tid))) {
|
||||
// FUTEX_WAIT_PRIVATE makes it hang
|
||||
cthread_memory_wait32((uint32_t *)&td->tid, x, 0);
|
||||
cthread_memory_wait32(&td->tid, x, 0);
|
||||
}
|
||||
}
|
||||
if (exitcode) {
|
||||
|
|
|
@ -70,8 +70,8 @@ int cthread_sem_init(cthread_sem_t *, int);
|
|||
int cthread_sem_destroy(cthread_sem_t *);
|
||||
int cthread_sem_wait(cthread_sem_t *, int, const struct timespec *);
|
||||
int cthread_sem_signal(cthread_sem_t *);
|
||||
int cthread_memory_wait32(uint32_t *, uint32_t, const struct timespec *);
|
||||
int cthread_memory_wake32(uint32_t *, int);
|
||||
int cthread_memory_wait32(int *, int, const struct timespec *);
|
||||
int cthread_memory_wake32(int *, int);
|
||||
void cthread_zombies_add(cthread_t);
|
||||
void cthread_zombies_reap(void);
|
||||
|
||||
|
|
|
@ -24,12 +24,11 @@
|
|||
#include "libc/thread/freebsd.internal.h"
|
||||
#include "libc/thread/thread.h"
|
||||
|
||||
int cthread_memory_wait32(uint32_t* addr, uint32_t val,
|
||||
const struct timespec* timeout) {
|
||||
int cthread_memory_wait32(int* addr, int val, const struct timespec* timeout) {
|
||||
size_t size;
|
||||
struct _umtx_time *put, ut;
|
||||
if (IsLinux() || IsOpenbsd()) {
|
||||
return futex(addr, FUTEX_WAIT, val, timeout, 0);
|
||||
return sys_futex(addr, FUTEX_WAIT, val, timeout, 0);
|
||||
|
||||
#if 0
|
||||
} 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()) {
|
||||
return futex(addr, FUTEX_WAKE, n, 0, 0);
|
||||
return sys_futex(addr, FUTEX_WAKE, n, 0, 0);
|
||||
#if 0
|
||||
} else if (IsFreebsd()) {
|
||||
return _umtx_op(addr, UMTX_OP_MUTEX_WAKE, n, 0, 0);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "libc/fmt/bing.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/calls/struct/rlimit.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/rlimit.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/bits/popcnt.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
void SetUp(void) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/bits/bits.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
#define BASENAME(x) basename(gc(strdup(x)))
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/fmt/leb128.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(zleb64, testZero) {
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/nexgen32e/gettls.h"
|
||||
#include "libc/nexgen32e/threaded.h"
|
||||
|
|
|
@ -76,10 +76,13 @@ o/$(MODE)/test/libc/log/backtrace.com.dbg: \
|
|||
$(APE_NO_MODIFY_SELF)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/test/libc/log/backtrace.com.zip.o \
|
||||
o/$(MODE)/test/libc/log/backtrace.com.dbg.zip.o: \
|
||||
ZIPOBJ_FLAGS += \
|
||||
-B
|
||||
o/$(MODE)/test/libc/log/backtrace.com.zip.o: \
|
||||
o/$(MODE)/test/libc/log/backtrace.com
|
||||
@$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) -B $(OUTPUT_OPTION) $<
|
||||
|
||||
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
|
||||
o/$(MODE)/test/libc/log: \
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/mem/arena.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "libc/mem/mem.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/cxaatexit.internal.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
void *_memset(void *, int, size_t) asm("memset");
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#define THREADS 8
|
||||
#define ENTRIES 1024
|
||||
|
||||
uint32_t ready;
|
||||
int ready;
|
||||
volatile uint64_t A[THREADS * ENTRIES];
|
||||
|
||||
void OnChld(int sig) {
|
||||
|
@ -109,7 +109,7 @@ TEST(rand64, testThreadSafety_doesntProduceIdenticalValues) {
|
|||
for (i = 0; i < THREADS; ++i) {
|
||||
while ((j = atomic_load((uint32_t *)(tls[i] + 0x38)))) {
|
||||
// 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()));
|
||||
free(tls[i]);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sock/sock.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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/stdio/hex.internal.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/hyperion.h"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
|
|
@ -35,6 +35,7 @@ TEST_LIBC_STDIO_DIRECTDEPS = \
|
|||
LIBC_STR \
|
||||
LIBC_STUBS \
|
||||
LIBC_SYSV \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_TESTLIB \
|
||||
LIBC_TIME \
|
||||
LIBC_LOG \
|
||||
|
|
|
@ -177,6 +177,7 @@ BENCH(vappendf, bench) {
|
|||
const char t[] = {0};
|
||||
char *b = 0;
|
||||
EZBENCH2("appendf", donothing, appendf(&b, "hello"));
|
||||
EZBENCH2("kappendf", donothing, kappendf(&b, "hello"));
|
||||
free(b), b = 0;
|
||||
EZBENCH2("appends", donothing, appends(&b, "hello"));
|
||||
free(b), b = 0;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/alg/alg.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/str/oldutf16.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/hyperion.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/hyperion.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "net/http/escape.h"
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/hyperion.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/limits.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/hyperion.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "tool/args/args.h"
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.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: \
|
||||
QUOTA = -M100g
|
||||
|
||||
o/$(MODE)/test/tool/plinko/algebra_test.lisp.zip.o \
|
||||
o/$(MODE)/test/tool/plinko/library_test.lisp.zip.o: \
|
||||
ZIPOBJ_FLAGS += \
|
||||
-B
|
||||
o/$(MODE)/test/tool/plinko/algebra_test.lisp.zip.o: ZIPOBJ_FLAGS += -B
|
||||
o/$(MODE)/test/tool/plinko/library_test.lisp.zip.o: ZIPOBJ_FLAGS += -B
|
||||
|
||||
.PHONY: 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) \
|
||||
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_bigtens[];
|
||||
hidden extern const double __gdtoa_tinytens[];
|
||||
hidden extern const unsigned char __gdtoa_hexdig[];
|
||||
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/runtime/runtime.h"
|
||||
#include "third_party/gdtoa/gdtoa.internal.h"
|
||||
#include "third_party/gdtoa/lock.h"
|
||||
/* clang-format off */
|
||||
|
||||
static ThInfo TI0;
|
||||
|
@ -46,68 +47,62 @@ __gdtoa_Brelease(Bigint *rv)
|
|||
}
|
||||
|
||||
static void
|
||||
Bclear(void)
|
||||
__gdtoa_Bclear(void)
|
||||
{
|
||||
int i;
|
||||
__gdtoa_lock();
|
||||
for (i = 0; i < ARRAYLEN(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 *
|
||||
__gdtoa_Balloc(int k)
|
||||
{
|
||||
#if 0
|
||||
int x;
|
||||
Bigint *rv;
|
||||
x = 1 << k;
|
||||
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;
|
||||
}
|
||||
__gdtoa_lock();
|
||||
if (k <= Kmax && (rv = TI0.Freelist[k]) != 0) {
|
||||
TI0.Freelist[k] = rv->next;
|
||||
} else {
|
||||
x = 1 << k;
|
||||
rv = (Bigint *)malloc(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
||||
rv = malloc(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
||||
rv->k = k;
|
||||
rv->maxwds = x;
|
||||
}
|
||||
rv->sign = 0;
|
||||
rv->wds = 0;
|
||||
__gdtoa_unlock();
|
||||
return rv;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
__gdtoa_Bfree(Bigint *v)
|
||||
{
|
||||
#if 0
|
||||
free(v);
|
||||
#else
|
||||
if (v) {
|
||||
if (v->k > Kmax) {
|
||||
free((void*)v);
|
||||
free(v);
|
||||
} else {
|
||||
__gdtoa_lock();
|
||||
v->next = TI0.Freelist[v->k];
|
||||
TI0.Freelist[v->k] = v;
|
||||
__gdtoa_unlock();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Bigint *
|
||||
__gdtoa_multadd(Bigint *b, int m, int a) /* multiply by m and add a */
|
||||
Bigint * /* multiply by m and add a */
|
||||
__gdtoa_multadd(Bigint *b, int m, int a)
|
||||
{
|
||||
int i, wds;
|
||||
ULong *x;
|
||||
|
@ -192,27 +187,18 @@ __gdtoa_mult(Bigint *a, Bigint *b)
|
|||
return c;
|
||||
}
|
||||
|
||||
static void
|
||||
__gdtoa_pow5mult_destroy(void) {
|
||||
__gdtoa_Brelease(TI0.P5s);
|
||||
TI0.P5s = 0;
|
||||
}
|
||||
|
||||
Bigint *
|
||||
__gdtoa_pow5mult(Bigint *b, int k)
|
||||
{
|
||||
Bigint *b1, *p5, *p51;
|
||||
int i;
|
||||
Bigint *b1, *p5, *p51;
|
||||
static const int p05[3] = { 5, 25, 125 };
|
||||
if ((i = k & 3))
|
||||
b = __gdtoa_multadd(b, p05[i-1], 0);
|
||||
if (!(k >>= 2))
|
||||
return b;
|
||||
if (!(p5 = TI0.P5s)) {
|
||||
p5 = TI0.P5s = __gdtoa_i2b(625);
|
||||
p5->next = 0;
|
||||
atexit(__gdtoa_pow5mult_destroy);
|
||||
}
|
||||
__gdtoa_lock();
|
||||
p5 = TI0.P5s;
|
||||
for(;;) {
|
||||
if (k & 1) {
|
||||
b1 = __gdtoa_mult(b, p5);
|
||||
|
@ -227,6 +213,7 @@ __gdtoa_pow5mult(Bigint *b, int k)
|
|||
}
|
||||
p5 = p51;
|
||||
}
|
||||
__gdtoa_unlock();
|
||||
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/Modules/_tracemalloc.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/gcmodule.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/bytesobject.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/classobject.c \
|
||||
third_party/python/Objects/codeobject.c \
|
||||
|
|
|
@ -190,12 +190,15 @@ TryAgain:
|
|||
freeaddrinfo(ai);
|
||||
}
|
||||
|
||||
bool Send(int *pipes, int pipescount, const void *output, size_t outputsize) {
|
||||
bool okall;
|
||||
int rc, i, have;
|
||||
bool Send(int tmpfd, const void *output, size_t outputsize) {
|
||||
bool ok;
|
||||
char *zbuf;
|
||||
size_t zsize;
|
||||
int rc, have;
|
||||
static bool once;
|
||||
static z_stream zs;
|
||||
char *zbuf = gc(malloc(PIPE_BUF));
|
||||
zsize = 32768;
|
||||
zbuf = gc(malloc(zsize));
|
||||
if (!once) {
|
||||
CHECK_EQ(Z_OK, deflateInit2(&zs, 4, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
|
||||
Z_DEFAULT_STRATEGY));
|
||||
|
@ -203,25 +206,24 @@ bool Send(int *pipes, int pipescount, const void *output, size_t outputsize) {
|
|||
}
|
||||
zs.next_in = output;
|
||||
zs.avail_in = outputsize;
|
||||
okall = true;
|
||||
ok = true;
|
||||
do {
|
||||
zs.avail_out = PIPE_BUF;
|
||||
zs.avail_out = zsize;
|
||||
zs.next_out = (unsigned char *)zbuf;
|
||||
rc = deflate(&zs, Z_SYNC_FLUSH);
|
||||
CHECK_NE(Z_STREAM_ERROR, rc);
|
||||
have = PIPE_BUF - zs.avail_out;
|
||||
for (i = 0; i < pipescount; ++i) {
|
||||
rc = write(pipes[i * 2 + 1], zbuf, have);
|
||||
if (rc != have) {
|
||||
DEBUGF("write(%d, %d) → %d", pipes[i * 2 + 1], have, rc);
|
||||
okall = false;
|
||||
}
|
||||
have = zsize - zs.avail_out;
|
||||
rc = write(tmpfd, zbuf, have);
|
||||
if (rc != have) {
|
||||
DEBUGF("write(%d, %d) → %d", tmpfd, have, rc);
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
} while (!zs.avail_out);
|
||||
return okall;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool SendRequest(int *pipes, int pipescount) {
|
||||
bool SendRequest(int tmpfd) {
|
||||
int fd;
|
||||
char *p;
|
||||
size_t i;
|
||||
|
@ -249,17 +251,14 @@ bool SendRequest(int *pipes, int pipescount) {
|
|||
q = mempcpy(q, name, namesize);
|
||||
assert(hdrsize == q - hdr);
|
||||
okall = true;
|
||||
okall &= Send(pipes, pipescount, hdr, hdrsize);
|
||||
okall &= Send(pipes, pipescount, p, progsize);
|
||||
okall &= Send(tmpfd, hdr, hdrsize);
|
||||
okall &= Send(tmpfd, p, progsize);
|
||||
CHECK_NE(-1, munmap(p, st.st_size));
|
||||
CHECK_NE(-1, close(fd));
|
||||
for (i = 0; i < pipescount; ++i) {
|
||||
okall &= !close(pipes[i * 2 + 1]);
|
||||
}
|
||||
return okall;
|
||||
}
|
||||
|
||||
bool RelayRequest(void) {
|
||||
void RelayRequest(void) {
|
||||
int i, rc, have, transferred;
|
||||
char *buf = gc(malloc(PIPE_BUF));
|
||||
for (transferred = 0;;) {
|
||||
|
@ -281,7 +280,6 @@ bool RelayRequest(void) {
|
|||
TlsDie("relay request failed to flush", rc);
|
||||
}
|
||||
close(13);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Recv(unsigned char *p, size_t n) {
|
||||
|
@ -351,16 +349,17 @@ int RunOnHost(char *spec) {
|
|||
1);
|
||||
if (!strchr(g_hostname, '.')) strcat(g_hostname, ".test.");
|
||||
DEBUGF("connecting to %s port %d", g_hostname, g_runitdport);
|
||||
do {
|
||||
for (;;) {
|
||||
Connect();
|
||||
EzFd(g_sock);
|
||||
if (!EzHandshake2()) break;
|
||||
WARNF("warning: got connection reset in handshake");
|
||||
close(g_sock);
|
||||
for (;;) {
|
||||
Connect();
|
||||
EzFd(g_sock);
|
||||
if (!(rc = EzHandshake2())) {
|
||||
break;
|
||||
}
|
||||
} while ((rc = RelayRequest()) == -1 || (rc = ReadResponse()) == -1);
|
||||
return rc;
|
||||
WARNF("got reset in handshake -0x%04x", rc);
|
||||
close(g_sock);
|
||||
}
|
||||
RelayRequest();
|
||||
return ReadResponse();
|
||||
}
|
||||
|
||||
bool IsParallelBuild(void) {
|
||||
|
@ -373,12 +372,20 @@ bool ShouldRunInParralel(void) {
|
|||
}
|
||||
|
||||
int SpawnSubprocesses(int argc, char *argv[]) {
|
||||
const char *tpath;
|
||||
sigset_t chldmask, savemask;
|
||||
int i, rc, ws, pid, tmpfd, *pids, exitcode;
|
||||
struct sigaction ignore, saveint, savequit;
|
||||
int i, rc, ws, pid, *pids, *pipes, exitcode;
|
||||
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.
|
||||
// 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
|
||||
//
|
||||
// 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));
|
||||
pipes = calloc(argc, sizeof(int) * 2);
|
||||
ignore.sa_flags = 0;
|
||||
ignore.sa_handler = SIG_IGN;
|
||||
sigemptyset(&ignore.sa_mask);
|
||||
|
@ -401,26 +410,18 @@ int SpawnSubprocesses(int argc, char *argv[]) {
|
|||
sigprocmask(SIG_BLOCK, &chldmask, &savemask);
|
||||
for (i = 0; i < argc; ++i) {
|
||||
args[3] = argv[i];
|
||||
CHECK_NE(-1, pipe2(pipes + i * 2, O_CLOEXEC));
|
||||
CHECK_NE(-1, (pids[i] = vfork()));
|
||||
if (!pids[i]) {
|
||||
dup2(pipes[i * 2], 13);
|
||||
dup2(open(tpath, O_RDONLY | O_CLOEXEC), 13);
|
||||
sigaction(SIGINT, &(struct sigaction){0}, 0);
|
||||
sigaction(SIGQUIT, &(struct sigaction){0}, 0);
|
||||
sigprocmask(SIG_SETMASK, &savemask, 0);
|
||||
execve(args[0], args, environ); // for htop
|
||||
_Exit(127);
|
||||
}
|
||||
close(pipes[i * 2]); // close reader
|
||||
}
|
||||
|
||||
// the smart part is we only do the expensive deflate operation from
|
||||
// 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
|
||||
// wait for children to terminate
|
||||
for (;;) {
|
||||
if ((pid = wait(&ws)) == -1) {
|
||||
if (errno == EINTR) continue;
|
||||
|
@ -443,10 +444,10 @@ int SpawnSubprocesses(int argc, char *argv[]) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
CHECK_NE(-1, unlink(tpath));
|
||||
sigprocmask(SIG_SETMASK, &savemask, 0);
|
||||
sigaction(SIGQUIT, &savequit, 0);
|
||||
sigaction(SIGINT, &saveint, 0);
|
||||
free(pipes);
|
||||
free(pids);
|
||||
return exitcode;
|
||||
}
|
||||
|
|
|
@ -267,7 +267,7 @@ void SendOutputFragmentMessage(enum RunitCommand kind, unsigned char *buf,
|
|||
|
||||
void Recv(void *output, size_t outputsize) {
|
||||
int rc;
|
||||
ssize_t tx, chunk, received;
|
||||
ssize_t tx, chunk, received, totalgot;
|
||||
static bool once;
|
||||
static int zstatus;
|
||||
static char buf[32768];
|
||||
|
@ -282,6 +282,7 @@ void Recv(void *output, size_t outputsize) {
|
|||
CHECK_EQ(Z_OK, inflateInit(&zs));
|
||||
once = true;
|
||||
}
|
||||
totalgot = 0;
|
||||
for (;;) {
|
||||
if (rbuf.len >= outputsize) {
|
||||
tx = MIN(outputsize, rbuf.len);
|
||||
|
@ -312,6 +313,7 @@ void Recv(void *output, size_t outputsize) {
|
|||
close(g_clifd);
|
||||
TlsDie("read failed", received);
|
||||
}
|
||||
totalgot += received;
|
||||
// decompress packet completely
|
||||
// into a dynamical size buffer
|
||||
zs.avail_in = received;
|
||||
|
@ -331,12 +333,14 @@ void Recv(void *output, size_t outputsize) {
|
|||
CHECK_NE(Z_STREAM_ERROR, zstatus);
|
||||
switch (zstatus) {
|
||||
case Z_NEED_DICT:
|
||||
zstatus = Z_DATA_ERROR; // make negative
|
||||
// fallthrough
|
||||
WARNF("tls recv Z_NEED_DICT %ld total %ld", received, totalgot);
|
||||
exit(1);
|
||||
case Z_DATA_ERROR:
|
||||
WARNF("tls recv Z_DATA_ERROR %ld total %ld", received, totalgot);
|
||||
exit(1);
|
||||
case Z_MEM_ERROR:
|
||||
close(g_clifd);
|
||||
FATALF("tls recv zlib hard error %d", zstatus);
|
||||
WARNF("tls recv Z_MEM_ERROR %ld total %ld", received, totalgot);
|
||||
exit(1);
|
||||
case Z_BUF_ERROR:
|
||||
zstatus = Z_OK; // harmless? nothing for inflate to do
|
||||
break; // it probably just our wraparound eof
|
||||
|
|
|
@ -63,7 +63,6 @@ $(TOOL_PLINKO_OBJS): \
|
|||
$(BUILD_FILES) \
|
||||
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/binarytrees.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 += \
|
||||
-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
|
||||
o/$(MODE)/tool/plinko: $(TOOL_PLINKO_BINS) $(TOOL_PLINKO_CHECKS)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue