Repository navigation
Pool workers sleep until woken, and UUIDs are random v4 without a lock - #596
Merged
Merged
Conversation
…at a time Every pool thread on Windows ran sleepy_robin, whose wait was a Sleep(1) and whose wake did nothing: an idle worker woke every tick of the system timer to look for work, and picked work up, or came back from a fiber's timed wait, only at a tick. The viewer's window asks for 1 ms ticks, so each idle pool thread woke about a thousand times a second; Windows 11 gives a process whose window is hidden the whole 15.6 ms tick whatever it asked for. sleepy_robin now waits on an auto-reset event, which a fiber made ready from another thread sets, and where a fiber's timed wait sets a deadline, on a high resolution waitable timer, which the tick does not round. Short of either handle it uses round_robin's own wait and wake, so no path sleeps a tick. Only a timer that will not be set falls back to a wait the tick rounds, which a wake still ends at once. Measured in threadpool_test at Windows' default tick, before and after: an idle worker ran 758,090 cycles in a quarter second, now 0; a 2 ms timed wait on a worker overran by a median 13.4 ms, now 0.4 ms. rye/aldb has an event-based sleepy_robin of its own, whose deadlines go through millisecond WaitForSingleObject timeouts the tick rounds, and its own tests/threadpool_test.cpp: whichever lands second merges the two, and this scheduler is the one to keep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…read without a lock LLUUID::generate made a version 1 UUID -- the time, a clock sequence and the network card's address -- and handed out its MD5. The time and the clock sequence lived in statics no lock guarded, so threads generating at once read the same tick and made the same UUID: eight threads making 25,000 each made about 140,000 distinct of 200,000, every run. Its one lock, an LLMutex on the branch where the clock had not moved, asserted if a coroutine reached it, and was made lazily on whichever thread got there first. A UUID is now 122 random bits with RFC 9562's version 4 and variant, from the system's cryptographic generator (BCryptGenRandom, getrandom, arc4random_buf) through a buffer each thread keeps: nothing shared between threads, and a call into the system for every sixteen UUIDs. uuid_time_t, cmpTime, getSystemTime, getCurrentTime and LLUUID::mMutex are gone; the machine ID and the hashed unique ID still read getNodeID. bcrypt joins the Windows system libraries. combine and the name-based generate(string) keep their MD5: combine is what the server makes an upload's asset ID with, and every caller of generate(string) names files or keys from it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 48 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
RyeMutt
marked this pull request as ready for review
October 28, 2026 02:59
This was referenced Oct 28, 2026
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.
Two follow-ups to the lock-type sweep (#591), one commit each.
Pool workers sleep until work or a deadline wakes them
On Windows every pool thread ran
sleepy_robin, whose wait wasSleep(1)and whose wake did nothing. An idle worker woke every tick of the system timer to look for work, and picked work up, or came back from a fiber's timed wait, only on a tick. The viewer's window asks for 1 ms ticks, so each idle pool thread woke about a thousand times a second. Windows 11 gives a process whose window is hidden the full 15.6 ms tick, whatever it asked for.sleepy_robinnow waits on an auto-reset event, which a fiber made ready from another thread sets. Where a fiber's timed wait sets a deadline, it also waits on a high-resolution waitable timer, which the tick does not round. If either handle can't be created it usesround_robin's own wait and wake, so no path sleeps a tick.Measured in
threadpool_testat Windows' default tick:Conflict ahead: #586 (
rye/aldb) has its own event-basedsleepy_robin, whose deadlines go through millisecondWaitForSingleObjecttimeouts that the tick rounds, and its owntests/threadpool_test.cpp. Whichever lands second merges the two; this scheduler is the one to keep.Generated UUIDs are random v4, made on any thread without a lock
LLUUID::generatemade a version 1 UUID (the time, a clock sequence and the network card's address) and handed out its MD5. The time and clock sequence lived in statics no lock guarded, so threads generating at once made the same UUID: eight threads making 25,000 each produced only about 140,000 distinct UUIDs out of 200,000, on every run. Its one lock was anLLMutexon a rare branch, which asserted if a coroutine reached it.A UUID is now 122 random bits with RFC 9562's version 4 and variant, from the system's cryptographic generator (
BCryptGenRandom,getrandom,arc4random_buf) through a buffer each thread keeps.uuid_time_t,cmpTime,getSystemTime,getCurrentTimeandLLUUID::mMutexare gone.getNodeIDstays for the machine ID and hashed unique ID, andbcryptjoins the Windows system libraries.combineand the name-basedgenerate(string)keep MD5. The server usescombineto make an upload's asset ID, andgenerate(string)'s callers name files and keys with it.Testing
vs2026-osRelWithDebInfo: built on top of what Locks follow one rule: LLCoros where a coroutine reaches, LLMutex where only threads do #591 merged, with no warnings. The viewer links, and 336/336 tests pass across the llcommon, llcorehttp, alscript, llui, newview, llmessage and llinventory binaries.threadpool_testpassed 10 runs in random order (0 idle cycles every run, median overrun 0.40–0.43 ms), andlluuid_testpassed 5.🤖 Generated with Claude Code