-
Notifications
You must be signed in to change notification settings - Fork 185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
use_file: switch to futex on Linux and to nanosleep
on other targets
#490
Conversation
db54f2c
to
ebecd9c
Compare
I don't think we should split how we do synchronization between the different targets. It adds a bunch of complexity for little gain. No contention occurs in the common case. Also, see #453 (comment). If we want something better than |
All other Not only IIUC implementation for the remaining targets uses pthread mutex under the hood, so with this PR we can continue to use pthread mutex, since it was primarily problematic on Linux and not other targets. Considering that non-Linux targets only open file in the critical section, I think we can even remove locking completely and replace it with a simple sleep-based loop similar to what I drafted in #478, without any |
Hm, if we are fine with a sleep-based loop for non-Linux targets, I guess we could eliminate the split by using sleep-based implementation of the |
The main benefit of |
The use of futex wait/wake operations in this PR is very straightforward, it's essentially a textbook-level example, so I don't think the new code requires any particular maintenance. I removed the code split and dependency on pthread mutex. What do you think about the new code? |
nanosleep
on other targets
I think this increases the complexity of the implementation without a concrete benefit. This implementation is longer and harder for me to understand than the If you don't want to use |
I think its reasonable to get rid of locking for initializing the file descriptor. It's not clear to me if a |
If we are to close eyes on the
It's essentially what I did in this PR. On non-Linux targets there is no locking, but on Linux we need some kind of locking because
|
I mean we would be using |
Looking at this, I actually think that splitting the code is fine, as we can share common abstractions (if any) between |
I would say the contents/complexity of the |
Ah, I somewhat misunderstood your idea. I guess it could work, but I think it will be more code and (to my taste) less straightforward. Plus, as you note yourself, this approach will always result in 2 file descriptors being continuously opened instead of 1.
Amount of common abstractions depends on whether we use pthread (or
I guess perceived complexity depends on how familiar reader is with futexes. Maybe I can amend this by adding comments explaining what exactly |
Looking at the man page for futex I found this:
This makes me think that futexes (whike very cool) are not really designed for general use, but rather as a way to allow things like |
Futex is certainly a very low-level API (with certain esoteric corners) which is usually used as a fundamental building block for higher-level synchronization structures. But it's not like it does not get directly used to implement custom synchronization primitives in production code (e.g. some people use it to implement an io-uring-like IPC API on top of shared memory). IMO it's an extremely good fit solution for our problem. |
@josephlr |
I will merge this for now to make it easier to work on other stuff. We can revert or change it before v0.3 release, since I will be waiting for other people's review before cutting it. |
Why was it urgent to merge this? This is quite a big change to merge without review and I think the lack of review is mostly because nobody agrees we should do this. I think we should figure out a way to make progress on the other things that this was blocking without having this change merged. |
Neither you, nor Joe were active on GitHub for quite some time. I wanted to work on the PR backlog and had some time for that. I don't want to deal with potential merge conflicts in multiple PRs while a work on other features. As we discussed with Joe, the merges are not final and will be reviewed and maybe changed before v0.3 release. |
All non-Linux targets only open file in the critical section, so we probably can remove all synchronization and replace it with a sleep-based wait loop.
On Linux initialization thread may spend a lot of time in the critical section because of
wait_until_rng_ready
. On entropy-starved (and especially virtualized) systems we may spend tens of seconds in it, so we need a proper synchronization between initializing and waiting threads. Luckily, the futex API is a great fit in this case and allows us to efficiently handle the synchronization.