Comments (17)
I have an idea for a completely lock-free design for an unbuffered Oneshot channel.
I'm in the process of implementing it. In my calculations in the case of the one-shot channel application, it heavily outperforms Kanal's MPMC channel.
from kanal.
Thanks for finding the bug, it was a mistype by me.
I need to review the code once more and finish the documentation, then I run the benchmarks and release. I think the release will be in 2 or 3 days.
Feel free to close the issue, if you think it's solved.
from kanal.
@botika implementation added to the library but I will not release it to crates.io until we run some tests on it and complete the documentation.
Implementation is completely lock-free and will use only 8 bytes heap allocation on 64-bit systems to move data in between.
I added only the unbuffered one-shot so send is blocking/suspending operation too if the sender reaches the send function first which is not common when using one-shot channels.
Oneshot implementation benefits from the stack-to-stack copy that the MPMC
channel is using too and there is no need to copy data again from the heap of the one-shot channel like other implementations.
from kanal.
unfortunately, I can't reproduce either Miri error or deadlock, I'm going to write a fuzzer to see if it's possible to reproduce the problem that you are encountering, I'm stopping the pre8 release until this problem is solved.
If you discover any new information about the bug please share.
from kanal.
Great idea, Let me think about the API and the possibility of implementation for a few days. Other community members can discuss and think about it too.
I want to be sure that we can implement it in the same crate as Kanal. I don't like to add unnecessary complexity to the crate.
from kanal.
I want to add these points to the issue, buffered one-shot and blocking one-shot channels are completely different in design.
To implement correctly, they should be implemented separately, and I'm unsure that Kanal is the right place to implement those.
to implement those I think we need:
4 public functions to generate channel's sides.
8 public structures for communication
AsyncOneShotSender
AsyncOneShotReceiver
AsyncOneShotBufferedSender
AsyncOneShotBufferedReceiver
SyncOneShotSender
SyncOneShotReceiver
SyncOneShotBufferedSender
SyncOneShotBufferedReceiver
from kanal.
We can use an enum to merge these public structures into 4 types. but there will be an unknown performance impact.
from kanal.
Its usage is a:
Sender
withsend -> Result<(), DroppedRecvError>
Receiver
implFuture<Output = Result<(), DroppedSenderErrorAndNotSent>>
Exactly what I want for this. https://github.com/botika/unblock/blob/master/src/lib.rs#L132-L137
Send Sender
to worker thread and return Receiver
.
from kanal.
Fails
- zzau13/unblock#8,
OneShotReceiverFuture<T>
withoutT: Unpin
whenPin
from kanal.
OneshotReceiverFuture<T>
in Kanal is not Unpin, which means it relies on it to be pinned to a memory location as it is doing stack-to-stack transfer to its field.
here you have two options:
using something like:
// Safety: OneShotReceiverFuture will not be moved out of Join in any condition
let fut = unsafe { self.as_mut().map_unchecked_mut(|this| &mut this.0) };
Poll::Ready(
match fut.poll(cx) {
Poll::Ready(t) => t,
Poll::Pending => return Poll::Pending,
}
.map_err(|_| Error),
)
or doing the job with pin-project
or pin-project-lite
without any unsafe, which I recommend the second one.
from kanal.
you also need to convert the sender and use the sync API: tx.to_sync().send($f());
from kanal.
Looks good. But it has Miri error when test multiple thread:
MIRIFLAGS="-Zmiri-symbolic-alignment-check -Zmiri-ignore-leaks" cargo miri test --all-features
...
test test_thread ... error: Undefined Behavior: trying to retag from <wildcard> for SharedReadWrite permission at alloc1885061[0x8], but no exposed tags have suitable permission in the borrow stack for this location
--> /home/lucky/.cargo/git/checkouts/kanal-35bf5e2ecaf10304/d3702c0/src/signal.rs:224:9
|
224 | (*this).ptr.copy(d);
| ^^^^^^^^^^^^^^^^^^^
| |
| trying to retag from <wildcard> for SharedReadWrite permission at alloc1885061[0x8], but no exposed tags have suitable permission in the borrow stack for this location
| this error occurs as part of retag at alloc1885061[0x8..0x10]
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
= note: BACKTRACE:
= note: inside `kanal::signal::Signal::<()>::send_copy` at /home/lucky/.cargo/git/checkouts/kanal-35bf5e2ecaf10304/d3702c0/src/signal.rs:224:9
= note: inside `kanal::signal::SignalTerminator::<()>::send_copy` at /home/lucky/.cargo/git/checkouts/kanal-35bf5e2ecaf10304/d3702c0/src/signal.rs:268:9
= note: inside `kanal::oneshot::OneshotSender::<()>::send` at /home/lucky/.cargo/git/checkouts/kanal-35bf5e2ecaf10304/d3702c0/src/oneshot.rs:244:33
note: inside closure at /home/lucky/workspace/unblock/src/lib.rs:149:21
--> /home/lucky/workspace/unblock/src/lib.rs:185:9
|
185 | run!(f in self)
| ^^^^^^^^^^^^^^^
= note: inside `<[closure@unblock::Executor::spawn<(), fn() {sleep}>::{closure#0}] as std::ops::FnOnce<()>>::call_once - shim(vtable)` at /home/lucky/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:510:5
= note: inside `<std::boxed::Box<dyn std::ops::FnOnce() + std::marker::Send> as std::ops::FnOnce<()>>::call_once` at /home/lucky/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:2000:9
note: inside `unblock::Executor::main_loop` at /home/lucky/workspace/unblock/src/lib.rs:198:17
--> /home/lucky/workspace/unblock/src/lib.rs:198:17
|
198 | runnable();
| ^^^^^^^^^^
note: inside closure at /home/lucky/workspace/unblock/src/lib.rs:242:36
--> /home/lucky/workspace/unblock/src/lib.rs:242:36
|
242 | .spawn(move || self.main_loop())
| ^^^^^^^^^^^^^^^^
= note: this error originates in the macro `run` (in Nightly builds, run with -Z macro-backtrace for more info)
from kanal.
Deadlock here https://github.com/botika/unblock/actions/runs/3926025840/jobs/6711368954
from kanal.
I'm receiving error[E0425]: cannot find value 'EXECUTOR' in this scope
error with Miri on your library, but it's passing the test for me. could you please retest with the latest commit?
from kanal.
Need lazy
feature for use in miri. Deadlock sometimes in slow systems https://github.com/botika/unblock/actions/runs/3934312687/jobs/6728941431
MIRIFLAGS="-Zmiri-symbolic-alignment-check -Zmiri-ignore-leaks" cargo miri test --no-default-features --features mt,kanal,lazy
In my machine (ryzen 9) is all ok
from kanal.
seems fixed with the latest commit: https://github.com/fereidani/unblock/actions/runs/3941226089/jobs/6743356805
from kanal.
Looks good in my test. Can you bump version?
from kanal.
Related Issues (20)
- Async can't utilize `KanalPtr` as effective as Sync HOT 1
- Are kanal functions cancel-safe? HOT 9
- Miri error when forgetting Box<T> HOT 2
- oneshot deadlock in 0.1.0-pre8 HOT 4
- Intrusive variants HOT 3
- Feature: implement recv_timeout for AsyncReceiver HOT 2
- Kanal is slower than crossbeam HOT 1
- Incorrect Send and Sync bounds HOT 2
- Oneshot: Data race detected HOT 4
- Unsound implementation of `as_sync` HOT 3
- Usage example
- Feature: Provide a select! macro HOT 6
- Slow usize send when using `MiMalloc` HOT 1
- mixing sync and async context HOT 2
- `Stream` that take ownership of the `Receiver` HOT 1
- OneshotSender is not Sync HOT 1
- API design for oneshot sender
- Oneshot: UB triggered when using Axum HOT 2
- Sink impl for AsyncSender?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from kanal.