Read the wakeup pipe fds atomically

Merged
HE
3mo ago
+228-78

Address the race condition caught by CI

test-fork-exec                                [ FAIL ] (exit 134)
    ==================
    WARNING: ThreadSanitizer: data race (pid=76887)
      Read of size 4 at 0x0001004fc6c4 by thread T1:
        #0 wakeup_pipe_signal poll.c:63 (elfuse:arm64+0x100060248)
        #1 preempt_thread_main proc.c:2897 (elfuse:arm64+0x10007368c)
    
      Previous write of size 4 at 0x0001004fc6c4 by main thread:
        #0 wakeup_pipe_init poll.c:57 (elfuse:arm64+0x1000601e8)
        #1 syscall_init syscall.c:117 (elfuse:arm64+0x10002dcbc)
        #2 guest_bootstrap_prepare bootstrap.c:574 (elfuse:arm64+0x10000fce4)
        #3 guest_bootstrap_prepare bootstrap.c:369 (elfuse:arm64+0x10000ecd4)
        #4 main main.c:243 (elfuse:arm64+0x1000008c4)
    
      Location is global 'wakeup_pipe_wr' at 0x0001004fc6c4 (elfuse+0x1000c46c4)
    
      Thread T1 (tid=39753171, running) created by main thread at:
        #0 pthread_create <null> (libclang_rt.tsan_osx_dynamic.dylib:arm64e+0x33834)
        #1 proc_preempt_init proc.c:2997 (elfuse:arm64+0x1000735c4)
        #2 main main.c:464 (elfuse:arm64+0x100001254)
    
    SUMMARY: ThreadSanitizer: data race poll.c:63 in wakeup_pipe_signal
    ==================


Summary by cubic

Fixes a wakeup-pipe data race by making the pipe fds atomic and reading the wake fd once per wait. Old behavior: plain ints allowed torn reads between init and signal delivery and code re-read the fd in pselect6. New behavior: _Atomic int with relaxed loads/stores and a single read per ppoll/pselect6; no readiness semantics change.

  • In ppoll/pselect6, load the wake fd once, reuse it across FD_SET/ISSET/CLR and the poll fallback, then drain and decrement the result when only the wakeup fired.
  • Move the wakeup-pipe API to syscall/wakeup-pipe.c/.h; remove it from syscall/poll.h; update all includes to syscall/wakeup-pipe.h.
  • Add native host concurrency test test-wakeup-pipe-host; build and run in host and sanitizer lanes.