zephyr::sync

Module channel

Source
Expand description

Close-to-Zephyr channels

This module attempts to provide a mechanism as close as possible to crossbeam-channel as we can get, directly using Zephyr primitives.

The channels are built around k_queue in Zephyr. As is the case with most Zephyr types, these are typically statically allocated. Similar to the other close-to-zephyr primitives, this means that there is a constructor that can directly take one of these primitives.

In other words, zephyr::sys::Queue is a Rust friendly implementation of k_queue in Zephyr. This module provides Sender and Receiver, which can be cloned and behave as if they had an internal Arc inside them, but without the overhead of an actual Arc.

§IRQ safety

These channels are usable from IRQ context on Zephyr in very limited situations. Notably, all of the following must be true:

  • The channel has been created with bounded(), which pre-allocates all of the messages.
  • If the type T has a Drop implementation, this implementation can be called from IRQ context.
  • Only try_send or try_recv are used on the channel.

The requirement for Drop is only strictly true if the IRQ handler calls try_recv and drops received message. If the message is always sent over another channel or otherwise not dropped, it might be safe to use these messages.

§Dropping of Sender/Receiver

Crossbeam channels support detecting when all senders or all receivers have been dropped on a channel, which will cause the handles on the other end to error, including waking up current threads waiting on those channels.

At this time, this isn’t implementable in Zephyr, as there is no API to wake up all threads blocked on a given k_queue. As such, this scenario is not supported. What actually happens is that when all senders or receivers on a channel are dropped, operations on the other end of the channel may just block (or queue forever with unbounded queues). If all handles (both sender and receiver) are dropped, the last drop will cause a panic. It maybe be better to just leak the entire channel, as any data associated with the channels would be leaked at this point, including the underlying Zephyr k_queue. Until APIs are added to Zephyr to allow the channel information to be safely freed, these can’t actually be freed.

Structs§

Functions§

  • Create a multi-producer multi-consumer channel with bounded capacity.
  • Wait loop
  • Create a multi-producer multi-consumer channel of unbounded capacity.
  • Create a multi-producer multi-consumer channel of unbounded capacity, using an existing Queue object.