#同步原语 #互斥锁 #同步 #读写锁 #异步 #操作系统 #无标准库

无标准库 maitake-sync

Maitake 提供的无标准库异步同步原语

3 个版本

0.1.2 2024 年 7 月 18 日
0.1.1 2024 年 1 月 27 日
0.1.0 2023 年 9 月 4 日

#99并发

Download history 3/week @ 2024-04-22 45/week @ 2024-04-29 10/week @ 2024-05-20 5/week @ 2024-06-03 49/week @ 2024-06-10 8/week @ 2024-06-17 3/week @ 2024-07-01 13/week @ 2024-07-08 156/week @ 2024-07-15 32/week @ 2024-07-22 67/week @ 2024-07-29 22/week @ 2024-08-05

278 每月下载量
用于 2 crates

MIT 许可证

710KB
11K SLoC

maitake-sync

🎶🍄 "跳舞蘑菇" — 来自 maitake 的异步同步原语

crates.io Documentation Documentation (HEAD) MIT licensed Test Status Sponsor @hawkw on GitHub Sponsors

这是什么?

这个库是针对基于 core::taskcore::future 的异步 Rust 软件同步原语集合,重点支持 #![no_std] 项目。它最初是作为 maitake 的一部分开发的,这是一个“异步运行时构建工具包”,用于在 myceliummnemOS 操作系统中使用,但也可能对其他项目也很有用。

要了解 maitake-sync 背后的故事,请参阅 公告帖子

注意

这是一个爱好项目。我在业余时间工作,仅供个人使用。我很高兴与更广泛的 Rust 社区分享它,并且欢迎 贡献错误报告。然而,请记住,我正在为了乐趣而开发这个库,如果它不再有趣...嗯,你明白我的意思。

无论如何,请随意使用和享受这个 crate,并尽可能多地做出贡献!

同步原语是用于实现任务之间同步的工具:控制哪些任务可以在任何时候运行,以及它们的运行顺序,并协调任务对共享资源的访问。通常,这种同步涉及某种形式的等待。在异步系统中,同步原语允许任务通过向运行时调度器让步来等待,以便其他任务可以在它们等待时运行。

maitake-sync之旅

以下提供了以下同步原语

  • Mutex:一个较为队列化的、异步的互斥锁,用于保护共享数据
  • RwLock:一个较为队列化的、异步的读写锁,允许对共享数据进行并发读访问,同时确保写访问是独占的
  • Semaphore:一个异步的计数信号量,用于限制可能并发运行的任务数量
  • WaitCell,一个存储单个等待任务的Waker的单元,以便任务可以被另一个任务唤醒
  • WaitQueue,一个等待任务的队列,按照先进先出的顺序唤醒任务
  • WaitMap,与键关联的一组等待任务,其中任务可以通过其键被唤醒

此外,util模块包含了一组用于实现同步原语的通用实用工具,而spin模块包含基于旋转的同步原语的实现。

使用注意事项

maitake-sync主要用于裸机项目,如操作系统、操作系统组件和嵌入式系统。这些裸机系统通常不使用Rust标准库,因此maitake-sync默认支持#![no_std],并且在liballoc不可用的系统中对liballoc的使用进行了功能标志。

对原子操作的支持

一般来说,maitake-sync是一个平台无关的库。它不直接与底层硬件交互,也不使用特定于平台的特性。然而,maitake-sync实现的一个方面可能会在不同的目标架构间略有不同:maitake-sync依赖于整数原子操作。有时,需要对特定宽度的整数进行原子操作(例如,AtomicU64),这可能不是所有架构都支持的。

为了处理缺乏64位整数原子操作的架构,maitake-sync 使用了Taiki Endo开发的 portable-atomic 包。当硬件不支持大于平台指针宽度的整数原子操作时,该包将填充这些操作。

在大多数情况下,maitake-sync 的用户不需要了解它使用 portable-atomic。如果为目标架构编译 maitake-sync,该架构支持64位原子操作(如 x86_64aarch64),则会自动使用原生原子操作。同样,如果为目标编译 maitake,该目标具有任何大小整数的原子比较和交换操作,但缺乏64位原子操作(例如32位x86目标如 i686,或具有原子操作的32位ARM目标),则会自动使用 portable-atomic 填充。最后,当为目标架构编译,这些架构因为始终是单核而缺乏原子操作,例如MSP430或AVR微控制器时,portable-atomic 仅使用暂时禁用中断的非同步操作。

用户必须注意 portable-atomic 的情况仅在编译的目标缺乏原子操作但不保证始终是单核时。这包括ARMv6-M(《code>thumbv6m)、v6之前的ARM(例如,《code>thumbv4t,《code>thumbv5te)和没有A扩展的RISC-V目标。在这些架构上,如果已知特定目标硬件是单核,用户必须手动启用 RUSTFLAGS 配置 --cfg portable_atomic_unsafe_assume_single_core。启用此cfg是不安全的,因为它会在使用这些架构的多核系统上导致不安全的行为。

有关一些单核系统的额外配置的详细信息,这些配置确定了 portable-atomic 进入临界区时将禁用的特定中断集,请参阅此处

功能

以下功能可用(此列表不完整;您可以扩展它。)

功能 默认 说明
alloc true 启用 liballoc 依赖
no-cache-pad false 抑制 CachePadded 结构的缓存填充。当此功能未启用时,大小将基于目标平台确定。
tracing false 启用对 tracing 诊断的支持。需要 liballoc
core-error false 启用 maitake-sync 错误类型对 core::error::Error 特质的实现。需要夜间Rust工具链。

依赖

~1–26MB
~366K SLoC