diff --git a/libc/calls/read-nt.c b/libc/calls/read-nt.c index 2894af20f9d..7ce32aaf032 100644 --- a/libc/calls/read-nt.c +++ b/libc/calls/read-nt.c @@ -31,7 +31,6 @@ #include "libc/intrin/atomic.h" #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/dll.h" -#include "libc/intrin/kprintf.h" #include "libc/intrin/nomultics.internal.h" #include "libc/intrin/strace.internal.h" #include "libc/intrin/weaken.h" @@ -129,14 +128,14 @@ struct Keystroke { struct Keystrokes { atomic_uint once; + bool end_of_file; + bool ohno_decckm; + uint16_t utf16hs; + atomic_int_fast16_t used; int64_t cin, cot; struct Dll *list; struct Dll *line; struct Dll *free; - bool end_of_file; - bool ohno_decckm; - unsigned char pc; - uint16_t utf16hs; pthread_mutex_t lock; const struct VirtualKey *vkt; struct Keystroke pool[512]; @@ -156,6 +155,12 @@ static textwindows void OpenConsole(void) { kNtFileShareWrite, 0, kNtOpenExisting, 0, 0); } +static textwindows int AddSignal(int sig) { + atomic_fetch_or_explicit(&__get_tls()->tib_sigpending, 1ull << (sig - 1), + memory_order_relaxed); + return 0; +} + static textwindows void InitConsole(void) { cosmo_once(&__keystroke.once, OpenConsole); } @@ -295,9 +300,9 @@ static textwindows int ProcessKeyEvent(const struct NtInputRecord *r, char *p) { // tcsetattr() lets anyone reconfigure these keybindings if (c && !(__ttyconf.magic & kTtyNoIsigs)) { if (c == __ttyconf.vintr) { - return __sig_enqueue(SIGINT); + return AddSignal(SIGINT); } else if (c == __ttyconf.vquit) { - return __sig_enqueue(SIGQUIT); + return AddSignal(SIGQUIT); } } @@ -399,7 +404,7 @@ static textwindows int ConvertConsoleInputToAnsi(const struct NtInputRecord *r, case kNtMouseEvent: return ProcessMouseEvent(r, p); case kNtWindowBufferSizeEvent: - return __sig_enqueue(SIGWINCH); + return AddSignal(SIGWINCH); default: return 0; } @@ -409,8 +414,8 @@ static textwindows struct Keystroke *NewKeystroke(void) { struct Dll *e; struct Keystroke *k = 0; int i, n = ARRAYLEN(__keystroke.pool); - if (atomic_load_explicit(&__keystroke.pc, memory_order_acquire) < n && - (i = atomic_fetch_add(&__keystroke.pc, 1)) < n) { + if (atomic_load_explicit(&__keystroke.used, memory_order_acquire) < n && + (i = atomic_fetch_add(&__keystroke.used, 1)) < n) { k = __keystroke.pool + i; } else { if ((e = dll_first(__keystroke.free))) { diff --git a/libc/calls/sig.c b/libc/calls/sig.c index e7919cc217a..1a6b8d99648 100644 --- a/libc/calls/sig.c +++ b/libc/calls/sig.c @@ -91,7 +91,8 @@ textwindows void __sig_delete(int sig) { BLOCK_SIGNALS; _pthread_lock(); for (e = dll_last(_pthread_list); e; e = dll_prev(_pthread_list, e)) { - POSIXTHREAD_CONTAINER(e)->tib->tib_sigpending &= ~(1ull << (sig - 1)); + atomic_fetch_and_explicit(&POSIXTHREAD_CONTAINER(e)->tib->tib_sigpending, + ~(1ull << (sig - 1)), memory_order_relaxed); } _pthread_unlock(); ALLOW_SIGNALS; @@ -157,7 +158,8 @@ static textwindows bool __sig_start(struct PosixThread *pt, int sig, } if (pt->tib->tib_sigmask & (1ull << (sig - 1))) { STRACE("enqueing %G on %d", sig, _pthread_tid(pt)); - pt->tib->tib_sigpending |= 1ull << (sig - 1); + atomic_fetch_or_explicit(&pt->tib->tib_sigpending, 1ull << (sig - 1), + memory_order_relaxed); return false; } if (*rva == (intptr_t)SIG_DFL) { @@ -339,7 +341,8 @@ static int __sig_killer(struct PosixThread *pt, int sig, int sic) { !((uintptr_t)__executable_start <= nc.Rip && nc.Rip < (uintptr_t)__privileged_start)) { STRACE("enqueing %G on %d rip %p", sig, _pthread_tid(pt), nc.Rip); - pt->tib->tib_sigpending |= 1ull << (sig - 1); + atomic_fetch_or_explicit(&pt->tib->tib_sigpending, 1ull << (sig - 1), + memory_order_relaxed); ResumeThread(th); __sig_cancel(pt, sig, flags); return 0; diff --git a/libc/calls/sigpending.c b/libc/calls/sigpending.c index d9400b92d17..50c630f1405 100644 --- a/libc/calls/sigpending.c +++ b/libc/calls/sigpending.c @@ -55,7 +55,8 @@ int sigpending(sigset_t *pending) { rc = 0; } else if (IsWindows()) { *pending = atomic_load_explicit(&__sig.pending, memory_order_acquire) | - __get_tls()->tib_sigpending; + atomic_load_explicit(&__get_tls()->tib_sigpending, + memory_order_acquire); rc = 0; } else { rc = enosys(); diff --git a/libc/calls/struct/sigset.internal.h b/libc/calls/struct/sigset.internal.h index 50351c76334..17793a0b5b2 100644 --- a/libc/calls/struct/sigset.internal.h +++ b/libc/calls/struct/sigset.internal.h @@ -15,7 +15,6 @@ COSMOPOLITAN_C_START_ } \ while (0) -int __sig_enqueue(int); sigset_t __sig_block(void); void __sig_unblock(sigset_t); void __sig_finishwait(sigset_t); diff --git a/libc/intrin/sig.c b/libc/intrin/sig.c index 03c037c5635..dfb4da24995 100644 --- a/libc/intrin/sig.c +++ b/libc/intrin/sig.c @@ -48,11 +48,6 @@ void __sig_unblock(sigset_t m) { } } -textwindows int __sig_enqueue(int sig) { - __get_tls()->tib_sigpending |= 1ull << (sig - 1); - return 0; -} - textwindows sigset_t __sig_beginwait(sigset_t waitmask) { return atomic_exchange_explicit(&__get_tls()->tib_sigmask, waitmask, memory_order_acquire); diff --git a/libc/proc/fork-nt.c b/libc/proc/fork-nt.c index bdcd0db5bcc..529004c8964 100644 --- a/libc/proc/fork-nt.c +++ b/libc/proc/fork-nt.c @@ -16,24 +16,18 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" +#include "ape/sections.internal.h" #include "libc/calls/internal.h" #include "libc/calls/sig.internal.h" #include "libc/calls/state.internal.h" -#include "libc/calls/struct/fd.internal.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/calls/wincrash.internal.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/atomic.h" #include "libc/intrin/directmap.internal.h" -#include "libc/intrin/dll.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/strace.internal.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" -#include "libc/mem/mem.h" -#include "libc/nt/console.h" #include "libc/nt/createfile.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/creationdisposition.h" @@ -41,21 +35,17 @@ #include "libc/nt/enum/pageflags.h" #include "libc/nt/enum/startf.h" #include "libc/nt/errors.h" -#include "libc/nt/files.h" #include "libc/nt/ipc.h" #include "libc/nt/memory.h" #include "libc/nt/process.h" #include "libc/nt/runtime.h" #include "libc/nt/signals.h" #include "libc/nt/struct/ntexceptionpointers.h" -#include "libc/nt/synchronization.h" -#include "libc/nt/thread.h" -#include "libc/nt/thunk/msabi.h" -#include "libc/proc/describefds.internal.h" #include "libc/proc/ntspawn.h" #include "libc/proc/proc.internal.h" #include "libc/runtime/internal.h" #include "libc/runtime/memtrack.internal.h" +#include "libc/runtime/runtime.h" #include "libc/runtime/symbols.internal.h" #include "libc/str/str.h" #include "libc/sysv/consts/at.h" @@ -65,7 +55,6 @@ #include "libc/sysv/consts/sig.h" #include "libc/sysv/errfuns.h" #include "libc/thread/itimer.internal.h" -#include "libc/thread/posixthread.internal.h" #include "libc/thread/tls.h" #ifdef __x86_64__ @@ -395,10 +384,9 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { __set_tls(tib); __morph_tls(); __tls_enabled_set(true); - // get new main thread handle - // clear pending signals - tib->tib_sigpending = 0; + // the child's pending signals is initially empty atomic_store_explicit(&__sig.pending, 0, memory_order_relaxed); + atomic_store_explicit(&tib->tib_sigpending, 0, memory_order_relaxed); // re-enable threads __enable_threads(); // re-apply code morphing for function tracing diff --git a/test/libc/calls/getcwd_test.c b/test/libc/calls/getcwd_test.c index 76dad7bf1f3..2a4be30ea79 100644 --- a/test/libc/calls/getcwd_test.c +++ b/test/libc/calls/getcwd_test.c @@ -23,6 +23,7 @@ #include "libc/log/check.h" #include "libc/macros.internal.h" #include "libc/mem/gc.internal.h" +#include "libc/str/str.h" #include "libc/testlib/testlib.h" #include "libc/x/x.h" @@ -48,5 +49,6 @@ TEST(getcwd, testWindows_addsFunnyPrefix) { if (!IsWindows()) return; char path[PATH_MAX]; ASSERT_NE(0, getcwd(path, sizeof(path))); - EXPECT_STARTSWITH("/C/", path); + path[1] = tolower(path[1]); + EXPECT_STARTSWITH("/c/", path); }