forked from crystal-lang/crystal
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add fiber safety to crystal/once (crystal-lang#15370)
Removes the global `Mutex` (previously only used when the `preview_mt` flag is defined) that would prevent concurrent initializers to run in parallel, while still being able to detect reentrancy. It works by keeping a list of pending operations (one per `flag` pointer) protected by a global lock that doesn't block other initializers from running. Using a linked-list of stack allocated structs may sound inefficient compared to a `Hash` but there should usually not be many concurrent / parallel / nested lazy initializations that following a few pointers would be significant compared to calculating a hash and (re)allocating memory. This isn't very important for the initialization of class vars and constants which happens sequentially at the start of the program, before we even start threads. But we plan to reuse the feature to implement lazy initializers for class variables (crystal-lang#14905) which can kick in at any time. Introduces the `Crystal::Once` namespace. The initialization entry is now `Crystal::Once.init` instead of `Crystal.once_init`. Reverts the once flag to be a bool so we keep a single implementation. This avoids having two implementations and it will simplify the call site when we protect class getter/property macros with lazy initializers: the flag is always `Bool`, not either `Crystal::Once::State` or `Bool` depending on the compiler. ## CREDITS @BlobCodes (David Keller <davidkeller@tuta.io>) wrote the initial implementation in crystal-lang/crystal@master...BlobCodes:crystal:perf/crystal-once-v2. I mostly removed the fences (SpinLock already deals with memory order), made it compatible with both the enum or bool variants, where the enum allows to skip over checking the operations when processing —maybe not very significant? I shall read his code much more carefully now 🙇 Co-authored-by: David Keller <davidkeller@tuta.io>
- Loading branch information
1 parent
1cf95a8
commit 9b7fd8d
Showing
7 changed files
with
120 additions
and
113 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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