Skip to content

3-mutex-example: Deadlock #1

@jamesmunns

Description

@jamesmunns

@mwkroening wrote in ferrous-systems/async-on-embedded#5:

I am porting the examples to the Blue Pill (STM32F103C8T6).

In example 3-mutex I only get the following output:

B: before lock
A: before write

The expected output:

B: before lock
A: before write
A: after releasing the lock
A: yield
B: 42
DONE

The Microcontroller is currently waiting for events with the following back trace:

#0  0x08004d5e in __wfe ()
#1  0x08001390 in cortex_m::asm::wfe ()
    at /home/mkroening/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.2/src/asm.rs:97
#2  0x08000b02 in <async_cortex_m::unsync::mutex::MutexGuard<T> as core::ops::drop::Drop>::drop (self=0x20004d24)
    at /home/mkroening/Development/rust-embedded/async-on-embedded/async-cortex-m/src/unsync/mutex.rs:97
#3  0x08000ad0 in core::ptr::drop_in_place ()
    at /home/mkroening/.rustup/toolchains/nightly-2020-04-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/ptr/mod.rs:177
#4  0x080012f2 in core::mem::drop (_x=...)
    at /home/mkroening/.rustup/toolchains/nightly-2020-04-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/mem/mod.rs:880
#5  0x080016de in _3_mutex::__cortex_m_rt_main::{{closure}} ()
    at examples/3-mutex.rs:47
#6  0x080006dc in <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll (self=..., cx=0x20004f0c)
    at /home/mkroening/.rustup/toolchains/nightly-2020-04-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/future/mod.rs:66
#7  0x08000634 in core::future::poll_with_context (f=..., cx=...)
    at /home/mkroening/.rustup/toolchains/nightly-2020-04-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/future/mod.rs:84
#8  0x08001bc2 in async_cortex_m::executor::Node$LT$dyn$u20$core..future..future..Future$u2b$Output$u20$$u3d$$u20$$LP$$RP$$GT$::new::_$u7b$$u7b$closure$u7d$$u7d$::h309ac6bb8a264efb ()
    at /home/mkroening/Development/rust-embedded/async-on-embedded/async-cortex-m/src/executor.rs:162
#9  0x0800078e in <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll (self=..., cx=0x20004f0c)
    at /home/mkroening/.rustup/toolchains/nightly-2020-04-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/future/mod.rs:66
#10 0x08001ebe in async_cortex_m::executor::Executor::block_on (
    self=0x20000098 <async_cortex_m::executor::current::EXECUTOR>, f=...)
    at /home/mkroening/Development/rust-embedded/async-on-embedded/async-cortex-m/src/executor.rs:107
#11 0x08001586 in async_cortex_m::task::block_on (f=...)
    at /home/mkroening/Development/rust-embedded/async-on-embedded/async-cortex-m/src/task.rs:17
#12 0x08001972 in _3_mutex::__cortex_m_rt_main (
    X=0x20000000 <_3_mutex::__cortex_m_rt_main_trampoline::X>)
    at examples/3-mutex.rs:57
#13 0x08001912 in main () at examples/3-mutex.rs:38

The issue seems to be waiting for events after notifying any waker when dropping the MutexGuard:
https://github.com/ferrous-systems/async-on-embedded/blob/341fa1c2a0e4a23dbe51fa2665d730175fa57b00/async-cortex-m/src/unsync/mutex.rs#L96-L97

I think this behavior (introduced in a008306) is not intended, as in other synchronization primitives we signal events instead after notifying wakers:
https://github.com/ferrous-systems/async-on-embedded/blob/341fa1c2a0e4a23dbe51fa2665d730175fa57b00/async-cortex-m/src/task.rs#L45-L46
https://github.com/ferrous-systems/async-on-embedded/blob/341fa1c2a0e4a23dbe51fa2665d730175fa57b00/async-cortex-m/src/unsync/channel.rs#L139-L140
https://github.com/ferrous-systems/async-on-embedded/blob/341fa1c2a0e4a23dbe51fa2665d730175fa57b00/async-cortex-m/src/unsync/channel.rs#L164-L165

I'll follow up with a PR.

What do you think?

Note that the corresponding example from the "async/await on embedded Rust" blog post does not suffer from this, as B explicitly yields after the drop, signaling events that way.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions