mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-02 17:28:30 +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
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue