Commits on Source 13

  • cznic's avatar
    nuc64: auto deps · ccaf682c
    cznic authored
    ccaf682c
  • cznic's avatar
    modernc.org/libc: nuc64 auto generate · 1aded7cd
    cznic authored
    1aded7cd
  • cznic's avatar
    modernc.org/libc: pi32 auto generate · 61e8485a
    cznic authored
    61e8485a
  • cznic's avatar
    modernc.org/libc: pi64 auto generate · f6b2610a
    cznic authored
    f6b2610a
  • cznic's avatar
    modernc.org/libc: ppc64le auto generate · 234b2163
    cznic authored
    234b2163
  • cznic's avatar
    modernc.org/libc: linux_loong64b auto generate · 05e89648
    cznic authored
    05e89648
  • cznic's avatar
    modernc.org/libc: riscv64 auto generate · 7cdf9f2b
    cznic authored
    7cdf9f2b
  • cznic's avatar
    libc_musl: fix lost-wakeup deadlock in ___lock/___unlock · 852ba3a8
    cznic authored
    ___lock/___unlock emulated a C mutex using an atomic lock-word fast path
    plus a throwaway hand-off object stored in a map. When an unlocker took
    locksMu before a contending locker had registered its hand-off, ___unlock
    synthesized one and immediately discarded it; the waiter then blocked on a
    fresh, never-unlocked mutex forever, and the lock word was left non-zero, so
    every subsequent ___lock on that address also blocked. The process wedged
    permanently at zero CPU.
    
    The window is reachable through the exported API alone: localtime, localtime_r
    and mktime all take the single process-global timezone lock (_lock4) via
    __secs_to_zone on every call, so goroutines calling them concurrently can hit
    it. Reported against modernc.org/quickjs evaluating JS Date local-time getters.
    
    Replace the scheme with a per-address sync.Mutex, created lazily and
    reference-counted for cleanup. The opaque C lock word is no longer touched
    (nothing reads it outside these two functions); routing all mutual exclusion
    through the per-address mutex makes the hand-off race-free, so a release
    delivered before the waiter blocks is no longer lost.
    
    Add TestIssue51: a mutual-exclusion stress on ___lock/___unlock plus a
    concurrent localtime_r stress; both clean under -race.
    
    Fixes: #51
    
    Co-Authored-By: default avatarClaude Opus 4.8 (1M context) <noreply@anthropic.com>
    852ba3a8
  • cznic's avatar
    builder.json: s/arm$/arm\$/ · 62087adb
    cznic authored
    62087adb
  • cznic's avatar
    modernc.org/libc: e5-1650 auto generate · c62e387f
    cznic authored
    c62e387f
  • cznic's avatar
    modernc.org/libc: fix __atomic_compare_exchange* reporting a bogus old value on failure · e20e49ab
    cznic authored
    The failure path re-read *ptr in a separate step instead of reporting the
    value observed during the failed comparison. C11 7.17.7.4 puts that update
    inside the atomic read-modify-write ("Atomically, compares ... and if false,
    updates the value in expected with the value pointed to by object"), and the
    hardware does exactly that: cmpxchg loads the actual value in the same
    instruction.
    
    If *ptr transiently reverted to the expected value inside the window between
    the failed CAS and the separate reload, the helper returned failure while
    writing the expected value back into *expected. Callers spinning on
    
    	while (atomic_compare_exchange_strong(&lock, &zero, 1) != 0) ;
    
    then left the loop without having acquired anything, because that idiom exits
    precisely when the reported old value equals the expected one.
    
    Restore the invariant that a failure reports a witness != old by retrying
    while the observed value is still old. A strong CAS that failed against old
    means *p != old at that instant, so a witness equal to old is never a valid
    failure report; and if the value did revert, a cmpxchg issued at that moment
    would have succeeded, making the retry more faithful than the bogus report.
    
    Affects the lock-free Int32/Uint32/Int64/Uint64 helpers. The Int8/Int16 and
    __c11_atomic_compare_exchange_strong* variants read the witness under the same
    mutex that guards the compare and were already correct.
    
    Found via modernc.org/libquickjs CI builders wedging at 100% CPU for 19+ hours
    in test262's Atomics agent tests, which use exactly that spin idiom. Hang rates
    on a 2-CPU linux/386 box, 200 runs of a single test: 20/200 (BigInt64Array) and
    16/200 (Int32Array) before, 0/200 after.
    
    TestIssue52/failure_witness fails on the old code (order 10^3 violations per
    2000000 attempts on amd64, 19028/2000000 on 386) and passes on the new. Only
    the contended case can observe this: TestIssue52/uncontended_semantics passes
    even on the broken code, which is why it went unnoticed.
    
    Closes #52
    
    Co-Authored-By: default avatarClaude Opus 4.8 (1M context) <noreply@anthropic.com>
    e20e49ab
  • cznic's avatar
    modernc.org/libc: s390x auto generate · e1e8eb7d
    cznic authored
    e1e8eb7d
  • cznic's avatar
    modernc.org/libc: fix readdir returning deleted entries on openbsd · 342f5ac3
    cznic authored
    getdirentries(2) reports records of deleted files with d_fileno set to zero
    and readdir(3) must not return them. On FFS such a record survives an unlink
    whenever it is the first one in a directory block, so any directory larger
    than a single 512-byte block reported ghost entries for files that were
    already gone.
    
    That made Tcl's glob (via libtcl8.6) see deleted files, causing the
    modernc.org/libsqlite3 openbsd/amd64 test failures delete_db-1.3.1,
    delete_db-1.4.1, multiplex-2.4.5, multiplex-5.3.prep and quota-5.3.prep.
    The failures only showed up in full-suite runs, once the shared working
    directory had grown past one block.
    
    Also stop iterating on a malformed d_reclen rather than spinning on it,
    matching the checks in OpenBSD's _readdir_unlocked().
    
    Co-Authored-By: default avatarClaude Opus 4.8 (1M context) <noreply@anthropic.com>
    342f5ac3
Loading
Loading