• src/sbbs3/ringbuf.c

    From Rob Swindell (on Windows 11)@1:103/705 to Git commit to main/sbbs/master on Wed Jul 2 16:07:06 2025
    https://gitlab.synchro.net/main/sbbs/-/commit/284d2357304c84f2eafc5567
    Modified Files:
    src/sbbs3/ringbuf.c
    Log Message:
    Fix typos in comments
    --- SBBSecho 3.28-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Deucе@1:103/705 to Git commit to main/sbbs/master on Thu May 21 20:58:10 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/9e7885d0f08b00641b058beb
    Modified Files:
    src/sbbs3/ringbuf.c
    Log Message:
    ringbuf: only signal events on state transitions in mutex-held builds

    RingBufWrite called ResetEvent(empty_event) and SetEvent(data_event) unconditionally on every call, regardless of whether the ring's
    empty/non-empty state actually changed. In sexyz, send_byte calls
    RingBufWrite once per transmitted byte, so a download was paying for
    2-3 event-object operations per byte. On Win32 those operations are
    real kernel syscalls; on Unix they go through xpevent.c (pthread
    mutex+cond) which is much cheaper.

    A reporter on Windows saw 447 KB/s downloads on a link that delivered
    ~43 MB/s for the reverse direction (the upload path takes data through recv()->inbuf[] in 64 KiB chunks with no per-byte event signaling, so
    it wasn't affected).

    The unconditional signaling exists because RINGBUF_MUTEX is optional:
    without the mutex you cannot safely check "is this a transition" and
    then signal, since another writer/reader could change state between
    the check and the call. But every Synchronet build that defines
    RINGBUF_EVENT also defines RINGBUF_MUTEX (sbbs.vcxproj, websrvr.vcxproj, sbbsexec.vcxproj, sexyz.vcxproj, sbbsdefs.mk, CMakeLists.txt, and the
    sbbs.h fallback), so the slow path is the only one in practice.

    Add a #ifdef RINGBUF_MUTEX fast path inside the #ifdef RINGBUF_EVENT
    block in RingBufWrite and RingBufRead that uses the pre-update fill
    level (already captured for the truncation check) together with the
    post-clamp byte count to signal only on actual empty<->non-empty and below<->at-or-above-highwater transitions. The mutexless #else path
    preserves the existing always-signal semantics verbatim.

    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)