2个不稳定版本
使用旧版Rust 2015
0.2.0 | 2018年7月1日 |
---|---|
0.1.0 | 2018年5月13日 |
#40 in #fifo
26KB
318 行
非阻塞轻量级同步结构
提供基于nbcrate的轻量级同步结构。适用于嵌入式系统上的Rust。这是一个no_std
crate,不需要堆分配。
许可证
此crate根据您的要求,以下列许可证之一进行许可
- Apache 2.0
- MIT
lib.rs
:
非阻塞同步结构
此crate设计用于no_std
应用程序,其中无法进行堆分配。因此,它不依赖于标准库,所有分配都是调用者的责任。
互斥锁
这里提供的Mutex
可以用来提供对值的独占访问。由于此库的非阻塞特性,必须小心操作以避免资源饥饿。锁方法需要一个bare_metal::CriticalSection
。
通道
`fifo::channel` 提供了一个单生产者单消费者队列,该队列是 `Sync
` 的,并且可以选择将其拆分为一个 `fifo::Sender
` 和一个 `fifo::Receiver
`,这两个都是 `Send
`。使用 `Channel` 与 `Sender` 和 `Receiver` 一起使用的关键区别在于,`Channel` 需要一个 `bare_metal::CriticalSection
` 才能为其方法提供安全性。而 `Sender` 和 `Receiver` 可以不满足此要求。
Channel 示例
可以使用两种方式使用 `fifo::Channel
`
直接使用
直接使用需要传递一个实现 `fifo::NonReentrant
` 的对象。
extern crate bare_metal;
extern crate nb_sync;
use nb_sync::fifo::Channel;
//In an actual program this would be obtained safely
let cs = unsafe { bare_metal::CriticalSection::new() };
let mut buffer: [Option<u8>; 4] = [None; 4];
let channel = Channel::new(&mut buffer);
channel.send(10, &cs).unwrap();
channel.recv(&cs).unwrap();
拆分为发送者和接收者
这使用了与上一个示例类似的方法,但不需要 `bare_metal::CriticalSection
`。
方法 1:使用可克隆类型的基本 "send" 操作
对于可克隆类型,可以在 `fifo::Sender::send
` 方法中直接使用 `await!
`。
extern crate nb;
extern crate nb_sync;
use nb_sync::fifo::Channel;
let mut buffer: [Option<u8>; 4] = [None; 4];
let mut channel = Channel::new(&mut buffer);
let (mut receiver, mut sender) = channel.split();
let clonable = 5;
// this loop is "await!(sender.send(clonable)).unwrap()"
loop {
match sender.send(clonable) {
Ok(()) => break Ok(()),
Err(nb::Error::WouldBlock) => {},
Err(nb::Error::Other(e)) => break Err(e),
}
}.unwrap();
// recv is also compatible with nb's await! macro
receiver.recv().unwrap();
方法 2:带有完成的发送
可以使用 `fifo::Sender::send_with_completion
` 方法发送不可克隆类型。这是基于 `fifo::Sender::send_lossless
` 方法的。使用 `fifo::SendCompletion
` 使其更直接地与 `await!
` 宏一起使用。它将在发送过程中拥有 `Sender` 和传递的值。当调用 `fifo::SendCompletion::done
` 时,`Sender` 将返回,并附带一个包含原始值的 `Option
`,如果它最终没有发送。
extern crate nb;
extern crate nb_sync;
use nb_sync::fifo::Channel;
struct NonClone {
_0: (),
}
impl NonClone {
fn new() -> Self { NonClone { _0: () } }
}
let mut buffer: [Option<NonClone>; 4] = [None, None, None, None];
let mut channel = Channel::new(&mut buffer);
let (mut receiver, mut sender) = channel.split();
let value = NonClone::new();
let completion = sender.send_with_completion(value);
// Completions can be aborted.
let (s, v) = completion.done();
sender = s;
let value = v.unwrap(); //the original, unsent value is returned here
let mut completion = sender.send_with_completion(value);
// This loop is "await!(completion.poll()).unwrap()"
loop {
match completion.poll() {
Ok(()) => break Ok(()),
Err(nb::Error::WouldBlock) => {},
Err(nb::Error::Other(e)) => break Err(e),
}
}.unwrap();
let (s, v) = completion.done();
sender = s;
assert!(v.is_none()); //the value has been sent.
receiver.recv().unwrap();
依赖项
~42KB