D930 - An event queue keeps its events as FreeBSD's kqueue keeps knotes

Status: decided Date: 2026-10-20

orbistoun-kernel's equeue module holds what sceKernelCreateEqueue makes. An event the guest registers is a knote keyed by filter and identifier, at most one per key. It goes on the ready list at most once, so repeated triggers before a wait come back as one event.

FreeBSD's sys/kern/kern_event.c is followed for each part, and the code cites the lines:

Only EVFILT_USER is kept as knotes. A change naming any other filter is refused as EINVAL, the answer FreeBSD gives for a filter it does not have.

Subsystem completions (flips, end-of-pipe releases) stay as they were before this decision. A subsystem registers a route and posts finished events to it. Each completion is delivered once, in order, on the same ready list as the knotes, and removing the route drops any completion still waiting. Coalescing these completions would change what data carries for each one, and that is not measured.

The guest entry points:

Entry points that no title in the library imports are not declared, following the dependency spine: the timers, sceKernelAddUserEvent, and the read, write and file events. obSCEne REQ-20261020T1315Z-kq01 measures their shapes ahead of the first title that needs them.

Why: the library's titles trigger user events, delete them, and delete queues (sceKernelDeleteEqueue has 15 importing modules). Before this decision a user event was registered and never delivered. It also shared one identifier space with flip ports, so a user event whose id matched a port handle would have received flips.

Measured by obSCEne REQ-20261020T1315Z-kq01 on FW 12.40, in reports/hardware/report-20261020-kq01-census.log:

sceAgcDriverDeleteEqEvent answers 0 and then ENOENT (rows 3645-3647). The timer filter is -7 with EV_CLEAR; its data counts expirations and its period is in microseconds. No library title uses timers yet (rows 3648 on).

Rejected: