Conversation
|
Hmmm, VecDeque::new is not const until Rust 1.68. It could be trivially replaced with LinkedList which has a const constructor in 1.63, but it would be a major regression in performance. |
|
There is no need to be worried about the MSRV of const VecDeque::new, because we will be able to raise the MSRV after about two weeks: smol-rs/smol#244 (comment) |
|
OK, did a more comprehensive benchmark run and it's pretty clear that the This PR should be ready for review now. |
|
I don't think we can reasonably make |
d206459 to
13fbe6f
Compare
|
Spoke too soon, added an early-out when the queue is empty to |
|
@james7132 Can you rebase on master? |
13fbe6f to
c4f077f
Compare
Done! |
2b5adca to
d0a1f9e
Compare
Co-authored-by: Ellen Emilia Anna Zscheile <fogti+devel@ytrizja.de>
fogti
left a comment
There was a problem hiding this comment.
overall LGTM.
but as this is a complicated change, it should still be reviewed by others.
cc @smol-rs/admins
notgull
left a comment
There was a problem hiding this comment.
I have to wonder if there's some kind of generic implementation we could do with the onset of GAT types. Like have one type that wraps it in Arc<T> and one type that wraps it in Rc<T>. I would prefer that to the duplicated implementation here.
|
Any chance you can look into using GATs for this one? |
I can definitely try to do so, though I'm not sure how much duplication there actually is with how different the runners are. |
| // SAFETY: All UnsafeCell accesses to sleepers are tightly scoped, and because | ||
| // `LocalExecutor` is !Send, there is no way to have concurrent access to the | ||
| // values in `State`, including the sleepers field. | ||
| let sleepers = unsafe { &mut *self.state.sleepers.get() }; |
There was a problem hiding this comment.
I think this let should be moved above the match, given that it is present in all branches anyways.
There was a problem hiding this comment.
I moved it in to minimize the scope of the UnsafeCell borrows, though I guess it currently does not hurt to move it outside the match.
There was a problem hiding this comment.
Please do so (simply because nothing is gained here by doing this code duplication, the match itself is side-effect-free)
Co-authored-by: Ellen Emilia Anna Zscheile <fogti+devel@ytrizja.de>
Looked into this and every attempt I've made to try to make this work was either much more complex or was unsound due to the UnsafeCell use. |
|
I would be very interested in moving this forward (I hope this to be able to lead to improvements to be possible in downstream https://github.com/hermit-os/kernel), but the conflicts would have to be resolved first. |
|
|
||
| use crate::{AbortOnPanic, AsyncCallOnDrop, Sleepers}; | ||
| #[doc(no_inline)] | ||
| pub use async_task::Task; |
There was a problem hiding this comment.
Why do we pub re-export this from here?
| use std::cell::{Cell, UnsafeCell}; | ||
| use std::collections::VecDeque; | ||
| use std::marker::PhantomData; | ||
| use std::panic::{RefUnwindSafe, UnwindSafe}; | ||
| use std::pin::Pin; | ||
| use std::rc::Rc; | ||
| use std::task::{Poll, Waker}; | ||
| use std::{fmt, mem}; |
There was a problem hiding this comment.
In light of #160, it would be a good idea to only use std where necessary, and use core/alloc when possible.
| // SAFETY: All UnsafeCell accesses to sleepers are tightly scoped, and because | ||
| // `LocalExecutor` is !Send, there is no way to have concurrent access to the | ||
| // values in `State`, including the sleepers field. | ||
| let sleepers = unsafe { &mut *self.state.sleepers.get() }; |
There was a problem hiding this comment.
Please do so (simply because nothing is gained here by doing this code duplication, the match itself is side-effect-free)
|
It would be nice if this implementation could be made |
|
First and foremost, it would be a good idea to split the |
This PR makes
LocalExecutorit's own separate implementation instead of wrapping an Executor, forking it's ownStatetype utilizing unsynchronized!Sendtypes where possible:Arc->Rc,Mutex->RefCell,AtomicPtr->Cell<*mut T>,ConcurrentQueue->VecDeque. This implementation also removes any extra operations that assumes there are other concurrent Runners/Tickers (i.e. local queues, extra notifications).For testing, I've duplicated most of the single-threaded compatible executor tests to ensure there's equivalent coverage on the new independent
LocalExecutor.I've also made an attempt to write this with
UnsafeCellinstead ofRefCell, but this litters a huge amount ofunsafethat might be too much for this crate. The gains here might not be worth it.I previously wrote some additional benchmarks but lost the changes to a stray
git reset --hardwhen benchmarking.The gains here are substantial. Here are the results: