The ccd arena is single-threaded and sized by measurement #57

Open
opened 2026-08-02 18:33:43 -04:00 by tachikoma · 0 comments
Collaborator

Source: TODO.md, "The ccd arena is single-threaded and sized by measurement" (at bbb7b8f)

src/collision_arena.c is one static arena of AKGL_CCD_ARENA_BYTES (64 KB) with
a bump pointer, reset at the top of every akgl_collision_test.

Two things follow that are true today and would not survive a change. This issue
exists so neither is rediscovered the hard way.

  • It is not thread-safe. libakgl is single-threaded behind
    akgl_game.statelock, and two threads in the narrowphase at once would
    interleave allocations in the same arena. Threading libakgl means an arena per
    thread, or a lock, before anything else.
  • The size is a measurement, not a guess. One GJK/EPA box pair measures 7,264
    bytes. Exhaustion is reported, not crashed: ccdGJKPenetration returns -2 and
    akgl_collision_test raises AKGL_ERR_COLLISION with the high-water mark in the
    message, so the failure names its own fix. MPR -- the default on the frame path
    -- allocates nothing at all, so the arena is only under pressure from a caller
    who has explicitly asked for EPA's manifold.

akgl_ccd_arena_highwater() is public so a game can assert its own ceiling.

Closing this means either threading the library (and taking the arena with it) or
deciding that libakgl stays single-threaded and saying so in the manual.

Files: src/collision_arena.c


Filed by Tachikoma (Claude Code, Opus 5, 1M context)

**Source:** TODO.md, "The ccd arena is single-threaded and sized by measurement" (at bbb7b8f) `src/collision_arena.c` is one static arena of `AKGL_CCD_ARENA_BYTES` (64 KB) with a bump pointer, reset at the top of every `akgl_collision_test`. Two things follow that are true today and would not survive a change. **This issue exists so neither is rediscovered the hard way.** - **It is not thread-safe.** libakgl is single-threaded behind `akgl_game.statelock`, and two threads in the narrowphase at once would interleave allocations in the same arena. **Threading libakgl means an arena per thread, or a lock, before anything else.** - **The size is a measurement, not a guess.** One GJK/EPA box pair measures 7,264 bytes. Exhaustion is reported, not crashed: `ccdGJKPenetration` returns -2 and `akgl_collision_test` raises `AKGL_ERR_COLLISION` with the high-water mark in the message, so the failure names its own fix. MPR -- the default on the frame path -- allocates nothing at all, so the arena is only under pressure from a caller who has explicitly asked for EPA's manifold. `akgl_ccd_arena_highwater()` is public so a game can assert its own ceiling. Closing this means either threading the library (and taking the arena with it) or deciding that libakgl stays single-threaded and saying so in the manual. **Files:** `src/collision_arena.c` --- Filed by Tachikoma (Claude Code, Opus 5, 1M context)
tachikoma added this to the Unscheduled milestone 2026-08-02 18:33:43 -04:00
tachikoma added the docsdesign-decisionblast-radius:low labels 2026-08-02 18:33:43 -04:00
tachikoma added the status::grooming label 2026-08-02 18:49:25 -04:00
Sign in to join this conversation.