1 个稳定版本
1.1.1 | 2020年4月3日 |
---|
#1887 在 硬件支持
10KB
66 行
注意
请访问我们的 主页 了解使用方法。谢谢!
lib.rs
:
Libcore 包装器,允许异步/等待
用法
将以下内容放入您的 Cargo.toml 中
[dependencies]
core = { package = "sgx_core_futures", git = "https://github.com/apache/teaclave-sgx-sdk.git" }
原因
目前,无法从 libcore 使用异步/等待。尝试从 no_std
包中调用 .await 将产生以下错误
error[E0433]: failed to resolve: could not find `poll_with_tls_context` in `future`
error[E0433]: failed to resolve: could not find `from_generator` in `future`
这是由于 await 降级为调用函数 ::core::futures::poll_with_tls_context
和 ::core::futures::from_generator
以设置包含当前任务的每个线程的上下文。然而,这些函数并不存在。等效函数在 libstd 中定义。它们设置一个包含正在执行的当前任务的线程局部变量。在轮询未来时,将检索此任务以调用未来的 poll
函数。
如前所述,这些函数的 libstd 版本使用线程局部变量,这仅在 rust 的 libstd 中通过 thread_local!
宏支持 - 而在 libcore 中不存在。然而,有一个替代方案:不稳定的 #[thread_local]
属性,它使用 ELF TLS。请注意,ELF TLS 不可移植到所有目标 - 它需要由操作系统、加载器等支持...
以下是一个线程局部属性在行动中的小例子
#![feature(thread_local)]
use core::cell::Cell;
#[thread_local]
static TLS_CX: Cell<i32> = Cell::new(1);
使用这个技巧,我们可以复制粘贴 libstd 的 poll_with_tls_context
/from_generator
函数的实现,但将 thread_local!
宏替换为 #[thread_local]
宏。很简单。
包装 libcore
这个小技巧不错,但是编译自定义的libcore很繁琐。相反,我们将包装libcore,暴露我们的libcore,它只是重新导出真实libcore的功能,并添加我们自己的额外功能。令人惊讶的是,这可以通过简单地声明一个带有core
依赖项,并将package
属性设置为我们的“真实”crates.io包名来实现。这将欺骗cargo将我们的包装器core作为真实的libcore传递给rustc。
就是这样。这个crate所做的只是重新导出libcore,在将来的模块中添加几个函数。您只需在Cargo.toml中使用以下内容即可使用它,rust将愉快地使用core-futures-tls
,就像它使用了libcore一样。
[dependencies]
core = { package = "sgx_core_futures", git = "https://github.com/apache/teaclave-sgx-sdk.git" }
结束语
虽然这个crate仍然使用TLS,但是应该可以创建一个版本,将线程局部上下文存储在全局中,以供单线程系统(如微控制器)使用。这留给读者作为练习。