crossbeam icon indicating copy to clipboard operation
crossbeam copied to clipboard

[WIP] Add push/pop lockless

Open Restioson opened this issue 6 years ago • 8 comments

This PR will add non-deadlocking push/pop operations to queues -- they will never deadlock even if a concurrent push/pop stalls for whatever reason indefinitely.

Restioson avatar Apr 24 '19 18:04 Restioson

@Restioson I have a high-level question about your use case with interrupts pushing keyboard events into the queue.

So if your interrupt handler is defined like this:

fn handler(event: KeyboardEvent) {
    queue.push(event);
}

What happens if an event handler (call it A) is interrupted before push is called by another interrupt handler (call it B)? Does that mean keyboard event from A will end up in the queue after event from B?

That sounds wrong to me so I wonder how keyboard drivers handle situations like these? Are you sure this is the way to go?

My guess would be that event handlers shouldn't be interruptable and maybe the hardware guarantees so, but I've no idea if what I'm saying is true.

ghost avatar Apr 29 '19 18:04 ghost

Yes, interrupt handlers cannot be interrupted (interrupts are disabled by the os). This is because if nesting is allowed, excessive nesting depth could cause a stackoverflow. However, the local APIC is able to buffer one IRQ to be dispatched if the cpu has disabled interrupts, which will be dispatched when the cpu re-enables them.

I do believe that I still need the function though, for instance in case the push interrupts a pop from the handler. And nevertheless, it could be useful for others.

Restioson avatar Apr 29 '19 20:04 Restioson

@Restioson Thanks for clarifying!

And just a couple more questions to see if I understood the problem domain correctly:

  1. Is it true that there is only a single consumer?
  2. Is it true that there is only a single producer?
  3. Is it true that even though you're using the queue in the SPSC fashion, you want a MPSC or MPMC interface only to get around Rust's ownership/sharing rules?

ghost avatar Apr 29 '19 21:04 ghost

  1. yes
  2. yes
  3. yes pretty much :) it has to be static unfortunately

Restioson avatar Apr 30 '19 05:04 Restioson

In that case, the way to go would really be https://github.com/crossbeam-rs/crossbeam/pull/338, which is ~5 times faster than ArrayQueue anyway :)

It's unfortunate that the SPSC queue cannot be used in your use case without unsafe {} blocks, but that is really the nature of the problem of interrupts. So my suggestion would be to use static mut variable then...

ghost avatar Apr 30 '19 09:04 ghost

Aren't those slated to be removed? Perhaps a RefCell. I will consider it though. Do you still think that this has a use case?

Restioson avatar Apr 30 '19 14:04 Restioson

Aren't those slated to be removed?

Possibly -- I'm not sure. The alternative to static mut would be a static UnsafeCell<T> variable.

Do you still think that this has a use case?

I don't think so. The SPSC queue is really designed to be wait-free and applicable in embedded systems, device drivers, and similar use cases. Others queues are a bit more high-level and can't provide strong progress guarantees without jumping through hoops or having tricky caveats.

ghost avatar May 11 '19 19:05 ghost

Sorry, I haven't had much time to work on this because of exams... I will get back to it when they are finished though.

Restioson avatar May 16 '19 05:05 Restioson