From 6be030cd7c58a94138f413b00c5c2d4ac952e310 Mon Sep 17 00:00:00 2001 From: Justine Tunney <jtunney@gmail.com> Date: Sat, 6 Jul 2024 01:39:15 -0700 Subject: [PATCH] Fix MODE=tinylinux build --- .../pthread_atfork_actual.c} | 0 libc/proc/fork.c | 2 + libc/stdio/fflush_unlocked.c | 47 ------------------- libc/stdio/flockfile.c | 38 +++++++++++++++ libc/stdio/stderr.c | 22 ++++----- libc/stdio/stdin.c | 21 ++++----- libc/stdio/stdout.c | 41 +++++++--------- test/libc/thread/pthread_atfork_test.c | 4 -- 8 files changed, 77 insertions(+), 98 deletions(-) rename libc/{thread/pthread_atfork.c => intrin/pthread_atfork_actual.c} (100%) diff --git a/libc/thread/pthread_atfork.c b/libc/intrin/pthread_atfork_actual.c similarity index 100% rename from libc/thread/pthread_atfork.c rename to libc/intrin/pthread_atfork_actual.c diff --git a/libc/proc/fork.c b/libc/proc/fork.c index 3a48db798..f1f138231 100644 --- a/libc/proc/fork.c +++ b/libc/proc/fork.c @@ -46,6 +46,8 @@ #include "libc/thread/posixthread.internal.h" #include "libc/thread/tls.h" +__static_yoink("_pthread_atfork"); + extern pthread_mutex_t _pthread_lock_obj; static void _onfork_prepare(void) { diff --git a/libc/stdio/fflush_unlocked.c b/libc/stdio/fflush_unlocked.c index dac00a5e4..579bc3676 100644 --- a/libc/stdio/fflush_unlocked.c +++ b/libc/stdio/fflush_unlocked.c @@ -16,58 +16,11 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" #include "libc/cxxabi.h" -#include "libc/errno.h" #include "libc/intrin/pushpop.internal.h" -#include "libc/macros.internal.h" #include "libc/mem/arraylist.internal.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" #include "libc/stdio/fflush.internal.h" #include "libc/stdio/internal.h" -#include "libc/stdio/stdio.h" -#include "libc/sysv/consts/o.h" -#include "libc/thread/thread.h" - -void(__fflush_lock)(void) { - pthread_mutex_lock(&__fflush_lock_obj); -} - -void(__fflush_unlock)(void) { - pthread_mutex_unlock(&__fflush_lock_obj); -} - -static void __stdio_fork_prepare(void) { - FILE *f; - __fflush_lock(); - for (int i = 0; i < __fflush.handles.i; ++i) - if ((f = __fflush.handles.p[i])) - pthread_mutex_lock(&f->lock); -} - -static void __stdio_fork_parent(void) { - FILE *f; - for (int i = __fflush.handles.i; i--;) - if ((f = __fflush.handles.p[i])) - pthread_mutex_unlock(&f->lock); - __fflush_unlock(); -} - -static void __stdio_fork_child(void) { - FILE *f; - for (int i = __fflush.handles.i; i--;) { - if ((f = __fflush.handles.p[i])) { - bzero(&f->lock, sizeof(f->lock)); - f->lock._word = PTHREAD_MUTEX_RECURSIVE; - } - } - pthread_mutex_init(&__fflush_lock_obj, 0); -} - -__attribute__((__constructor__(60))) static textstartup void stdioinit(void) { - pthread_atfork(__stdio_fork_prepare, __stdio_fork_parent, __stdio_fork_child); -} /** * Blocks until data from stream buffer is written out. diff --git a/libc/stdio/flockfile.c b/libc/stdio/flockfile.c index 556f86b63..2c381295f 100644 --- a/libc/stdio/flockfile.c +++ b/libc/stdio/flockfile.c @@ -16,8 +16,10 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/fflush.internal.h" #include "libc/stdio/internal.h" #include "libc/stdio/stdio.h" +#include "libc/str/str.h" #include "libc/thread/thread.h" /** @@ -26,3 +28,39 @@ void flockfile(FILE *f) { pthread_mutex_lock(&f->lock); } + +void(__fflush_lock)(void) { + pthread_mutex_lock(&__fflush_lock_obj); +} + +void(__fflush_unlock)(void) { + pthread_mutex_unlock(&__fflush_lock_obj); +} + +static void __stdio_fork_prepare(void) { + FILE *f; + __fflush_lock(); + for (int i = 0; i < __fflush.handles.i; ++i) + if ((f = __fflush.handles.p[i])) + pthread_mutex_lock(&f->lock); +} + +static void __stdio_fork_parent(void) { + FILE *f; + for (int i = __fflush.handles.i; i--;) + if ((f = __fflush.handles.p[i])) + pthread_mutex_unlock(&f->lock); + __fflush_unlock(); +} + +static void __stdio_fork_child(void) { + FILE *f; + for (int i = __fflush.handles.i; i--;) + if ((f = __fflush.handles.p[i])) + f->lock = (pthread_mutex_t)PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; + pthread_mutex_init(&__fflush_lock_obj, 0); +} + +__attribute__((__constructor__(60))) static textstartup void stdioinit(void) { + pthread_atfork(__stdio_fork_prepare, __stdio_fork_parent, __stdio_fork_child); +} diff --git a/libc/stdio/stderr.c b/libc/stdio/stderr.c index 4f80d4223..de694ed62 100644 --- a/libc/stdio/stderr.c +++ b/libc/stdio/stderr.c @@ -16,27 +16,25 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" #include "libc/stdio/internal.h" -#include "libc/stdio/stdio.h" #include "libc/sysv/consts/fileno.h" #include "libc/sysv/consts/o.h" #include "libc/thread/thread.h" +static FILE __stderr = { + .fd = STDERR_FILENO, + .bufmode = _IONBF, + .iomode = O_WRONLY, + .buf = __stderr.mem, + .size = sizeof(stderr->mem), + .lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, +}; + /** * Pointer to standard error stream. */ -FILE *stderr; - -static FILE __stderr; +FILE *stderr = &__stderr; __attribute__((__constructor__(60))) static textstartup void errinit(void) { - stderr = &__stderr; - stderr->fd = STDERR_FILENO; - stderr->bufmode = _IONBF; - stderr->iomode = O_WRONLY; - stderr->buf = stderr->mem; - stderr->size = sizeof(stderr->mem); - stderr->lock._word = PTHREAD_MUTEX_RECURSIVE; __fflush_register(stderr); } diff --git a/libc/stdio/stdin.c b/libc/stdio/stdin.c index 8f87e47ed..c5c3f6c2e 100644 --- a/libc/stdio/stdin.c +++ b/libc/stdio/stdin.c @@ -16,30 +16,29 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" #include "libc/calls/struct/stat.h" #include "libc/stdio/internal.h" -#include "libc/stdio/stdio.h" #include "libc/sysv/consts/fileno.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/s.h" #include "libc/thread/thread.h" +static FILE __stdin = { + .fd = STDIN_FILENO, + .iomode = O_RDONLY, + .bufmode = _IOFBF, + .buf = __stdin.mem, + .size = sizeof(stdin->mem), + .lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, +}; + /** * Pointer to standard input stream. */ -FILE *stdin; - -static FILE __stdin; +FILE *stdin = &__stdin; __attribute__((__constructor__(60))) static textstartup void initin(void) { struct stat st; - stdin = &__stdin; - stdin->fd = STDIN_FILENO; - stdin->iomode = O_RDONLY; - stdin->buf = stdin->mem; - stdin->size = sizeof(stdin->mem); - stdin->lock._word = PTHREAD_MUTEX_RECURSIVE; if (fstat(STDIN_FILENO, &st) || !S_ISREG(st.st_mode)) stdin->bufmode = _IONBF; __fflush_register(stdin); diff --git a/libc/stdio/stdout.c b/libc/stdio/stdout.c index c00e5d3fa..4c6b9b2d6 100644 --- a/libc/stdio/stdout.c +++ b/libc/stdio/stdout.c @@ -16,39 +16,32 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" -#include "libc/dce.h" #include "libc/stdio/internal.h" -#include "libc/stdio/stdio.h" #include "libc/sysv/consts/fileno.h" #include "libc/sysv/consts/o.h" #include "libc/thread/thread.h" +static FILE __stdout = { + .fd = STDOUT_FILENO, + .iomode = O_WRONLY, + .buf = __stdout.mem, + .size = sizeof(stdout->mem), + .lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, + + // Unlike other C libraries we don't bother calling fstat() to check + // if stdio is a character device and we instead choose to always + // line buffer it. We need it because there's no way to use the + // unbuffer command on a statically linked binary. This still goes + // fast. We value latency more than throughput, and stdio isn't the + // best api when the goal is throughput. + .bufmode = _IOLBF, +}; + /** * Pointer to standard output stream. */ -FILE *stdout; - -static FILE __stdout; +FILE *stdout = &__stdout; __attribute__((__constructor__(60))) static textstartup void outinit(void) { - stdout = &__stdout; - - stdout->fd = STDOUT_FILENO; - stdout->iomode = O_WRONLY; - stdout->buf = stdout->mem; - stdout->size = sizeof(stdout->mem); - stdout->lock._word = PTHREAD_MUTEX_RECURSIVE; - - /* - * Unlike other C libraries we don't bother calling fstat() to check - * if stdio is a character device and we instead choose to always line - * buffer it. We need it because there's no way to use the unbuffer - * command on a statically linked binary. This still goes fast. We - * value latency more than throughput, and stdio isn't the best api - * when the goal is throughput. - */ - stdout->bufmode = _IOLBF; - __fflush_register(stdout); } diff --git a/test/libc/thread/pthread_atfork_test.c b/test/libc/thread/pthread_atfork_test.c index f1e44139b..00a19cec5 100644 --- a/test/libc/thread/pthread_atfork_test.c +++ b/test/libc/thread/pthread_atfork_test.c @@ -83,12 +83,8 @@ void mu_wipe(void) { pthread_mutex_init(&mu, 0); } -static atomic_bool once; - void *Worker(void *arg) { for (int i = 0; i < 20; ++i) { - if (!atomic_exchange(&once, true)) - __print_maps(0); mu_lock(); usleep(20); mu_unlock();