Git Product home page Git Product logo

Comments (17)

fereidani avatar fereidani commented on July 28, 2024 3

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.

fereidani avatar fereidani commented on July 28, 2024 2

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.

fereidani avatar fereidani commented on July 28, 2024 1

@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.

fereidani avatar fereidani commented on July 28, 2024 1

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.

fereidani avatar fereidani commented on July 28, 2024

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.

fereidani avatar fereidani commented on July 28, 2024

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.

fereidani avatar fereidani commented on July 28, 2024

We can use an enum to merge these public structures into 4 types. but there will be an unknown performance impact.

from kanal.

zzau13 avatar zzau13 commented on July 28, 2024

Its usage is a:

  • Sender with send -> Result<(), DroppedRecvError>
  • Receiver impl Future<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.

zzau13 avatar zzau13 commented on July 28, 2024

Fails

from kanal.

fereidani avatar fereidani commented on July 28, 2024

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.

fereidani avatar fereidani commented on July 28, 2024

you also need to convert the sender and use the sync API: tx.to_sync().send($f());

from kanal.

zzau13 avatar zzau13 commented on July 28, 2024

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.

zzau13 avatar zzau13 commented on July 28, 2024

Deadlock here https://github.com/botika/unblock/actions/runs/3926025840/jobs/6711368954

from kanal.

fereidani avatar fereidani commented on July 28, 2024

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.

zzau13 avatar zzau13 commented on July 28, 2024

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.

fereidani avatar fereidani commented on July 28, 2024

seems fixed with the latest commit: https://github.com/fereidani/unblock/actions/runs/3941226089/jobs/6743356805

from kanal.

zzau13 avatar zzau13 commented on July 28, 2024

Looks good in my test. Can you bump version?

from kanal.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.