Repository navigation
Timers: binary heap in a fixed array - #28
Merged
Merged
Conversation
pt_sleep() inserted into a deadline-sorted list with interrupts masked. A new sleep usually has the latest deadline, so a typical insert walked every sleeper, and pt_timer_cancel() did the same. Keep the sleepers in a binary min-heap instead, an array of PT_NTIMERS (default 16) pointers inside pt_timers_t. Each env stores its slot, in place of next, so the env doesn't grow and cancel is O(log N) too. A fixed array fits PT_NO_MALLOC. A sleeper that finds every slot in use waits on the timer set for one. It sets full_wait in the same critical section as its enqueue, and pt_timer_run() broadcasts when it sees full_wait and a free slot. A slot freed by pt_timer_cancel() is handed on at the next pt_timer_run(), since cancel has no protothread_t to broadcast with. Equal deadlines no longer wake in FIFO order. Nothing documented or tested that. test_timer_heap fills the heap with random deadlines, cancels random entries, and checks the heap after every step, over 100 seeds. test_timer_full covers waiting for a slot, including after a cancel. Both catch a broken slot hand-off and a missing sift-up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SR7v9BVsFrHiEhQBSqZmAs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
pt_sleep()inserted into a deadline-sorted list with interrupts masked. A new sleep usually has the latest deadline, so a typical insert walked every sleeper, andpt_timer_cancel()did the same.This keeps the sleepers in a binary min-heap instead, an array of
PT_NTIMERS(default 16) pointers insidept_timers_t. A sleep, a cancel, and each wakeup are now O(log N) with interrupts masked. Each env stores its slot in place ofnext, so it doesn't grow. There's no API change.pt_sleep()waits for one, and its sleep starts then.pt_timer_run()hands on a freed slot, including one freed bypt_timer_cancel()(at the next run, since cancel has noprotothread_t).New tests:
test_timer_heapchecks the heap after every step, with random deadlines and cancels, over 100 seeds.test_timer_fullcovers waiting for a slot.Both fail against a broken slot hand-off and a missing sift-up. Passes locally with gcc and clang-22, several
PT_NWAIT/PT_NTIMERSsettings, ASan/UBSan, C++11, and freestanding C99.🤖 Generated with Claude Code
https://claude.ai/code/session_01SR7v9BVsFrHiEhQBSqZmAs