Repository navigation
feat(libkernel): implement SIGEV_NONE POSIX timers - #9314
Conversation
Progress report (0c6a5bd → 642c0d5)📈 System libraries: 42.14% (+0.04%, +4 implemented, +1 declared, -5 removed functions) ✅ 4 implemented
🆕 1 declared as stubs
🗑️ 5 removed
|
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
The PS5 3.20 export lists have ktimer_* in libkernel as well as libkernel_sys, and on Windows a libkernel import never reaches libkernel_sys. The implementation moves unchanged to libkernel/Time/Ktimer.cpp.
|
Linux: Ubuntu 24.04.1 LTS (WSL2), GCC 13.3.0, Release; head
Run from the PC (Windows host, Linux in WSL2), not from the PR author's machine. |
harisibrar1
left a comment
There was a problem hiding this comment.
Checked against main 8b3e398 and FreeBSD releng/11.4 sys/kern/kern_time.c (kern_ktimer_create, kern_ktimer_settime/gettime/getoverrun/delete, realtimer_settime/gettime/expire, itimespecfix, itimer_accept):
- Main still has only the five throwing
ktimer_*stubs inlibkernel_sys/Export.Discovery.cpp, and this head merges onto main cleanly. - The clock set (0 and 4), the sigevent checks (NONE, SIGNAL and THREAD_ID, signo 1..128), and ids 3..31 with
EAGAINall matchkern_ktimer_create. So does theEAGAIN-before-EFAULTorder for a NULLtimerid, since FreeBSD only fails at thecopyout. - The settime order (
EFAULTfor a NULL value before the id check), the interval being fixed only when armed, the old value taken before the store, and the absolute conversion all matchrealtimer_settime. Gettime checks the id beforeEFAULT, askern_ktimer_gettime+copyoutdo. - The closed-form periodic catch-up gives the same next expiry as the
while (cts >= value)loop inrealtimer_expire, andgetoverrunreturning 0 is right becauseit_overrun_lastonly changes initimer_accept. - Signal-delivering timers (including NULL
sigevent→SIGEV_SIGNAL/SIGALRM) throw after validation, before a slot is taken, and are in the debt file. Good. - Small nit, not blocking: in
Remaining,Expirealways leavesvalue == 0orvalue > now, so theGuestTimespec{0, 1}branch atKtimer.cpp:98can't be reached. It could be dropped, and the PR text adjusted to match.
Reviewed with AI assistance (Claude Code); the checks above were run locally on my machine.
What
Implements the POSIX timer syscalls
ktimer_create,ktimer_settime,ktimer_gettime,ktimer_getoverrunandktimer_deletein libkernel, in a newlibkernel/Time/Ktimer.cpp, following FreeBSD 11sys/kern/kern_time.c(kern_ktimer_create,realtimer_settime,realtimer_gettime,realtimer_expire,itimespecfix). They replace five discovery stubs that threw.Moved to libkernel so libkernel imports reach it on Windows. The PS5 3.20 export lists have
ktimer_*in libkernel as well as libkernel_sys, and on Windows a libkernel import never searches libkernel_sys (WindowsEntryStubBuilder.cpp:175only falls back from libkernel_sys and libkernel_web to libkernel). The libkernel_sys stubs are removed, so both imports reach the libkernel exports and the duplicate-export rule holds. The code is unchanged by the move.ktimer_create:CLOCK_REALTIME(0) andCLOCK_MONOTONIC(4) have timers; any other clock givesEINVAL.sigev_notifyother thanSIGEV_NONE,SIGEV_SIGNALorSIGEV_THREAD_IDgivesEINVAL, and for the two signal forms so does asigev_signooutside 1..128.setitimer;EAGAINwhen all are in use. A NULLtimeridgivesEFAULTand keeps no timer.ktimer_settime:EFAULT, and an id that isn't live givesEINVAL.itimespecfixapplies toit_value, and toit_intervalonly when the timer is being armed; a disarming value clears the interval.TIMER_ABSTIME(1) takesit_valueas absolute on the timer's clock.ktimer_gettimewould report it.ktimer_gettime: returns the remaining time, or 1 ns for an expiry that is due but not yet processed.ktimer_getoverrun: returns 0, because FreeBSD reportsit_overrun_last, which only changes when the timer's signal is accepted (itimer_accept).ktimer_delete:EINVALfor an id that isn't live.Why expiry is computed on read: a
SIGEV_NONEtimer delivers nothing (itimer_firedoes nothing for it), so expiry is worked out from the guestclock_gettimewhenever the timer is read, and no thread or callout is needed.What throws: a
SIGEV_SIGNALorSIGEV_THREAD_IDtimer, and one created with a NULLsigevent(which FreeBSD turns intoSIGEV_SIGNALwithSIGALRM), throws after validation, because delivering a guest signal from a timer is not modelled.The tick: sub-tick values round to 1 ms, FreeBSD's tick at hz 1000. The console's hz is not measured, since
kern.clockrateis unanswered. A debt line records both gaps.Ktimer.cppis added to libkernel's source list. The debt line is inlibkernel.md, under Functional.Tested
Windows 11 Pro 26200, WinLibs GCC 15.2.0 r7, Release. This is a CPU-side export, so no GPU is involved.
New test
guest_kernel_sys_ktimer, which covers:EAGAINafter 29 timers, and a deleted id being reused;itimerspecEINVALfields, and a disarming value clearing the interval;getoverrun0;TIMER_ABSTIMEin the future, in the past, and in the past on a periodic timer, on both clocks.Results:
guest_kernel_sysstill passes.tools/check_conventions.pypasses, including the duplicate-export rule:ktimer_*is exported by libkernel only.Ktimer.cppremoved from libkernel's sources, the test fails to link (undefined reference to ktimer_create_nid_postfix), so the exports it reaches are libkernel's.TickNanoseconds = 1), the test fails at line 140;tools/pr_overlap.pycrashes on this machine's partial clone, so I rangit merge-treeagainst every open PR that touches these files. It merges cleanly with all of them except:Export.Discovery.cpp. That's a one-line resolution by mergingmaininto whichever lands later.mainin files this PR doesn't touch.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)