]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/sgx/abi/usercalls/mod.rs
SGX target: implement synchronization primitives and threading
[rust.git] / src / libstd / sys / sgx / abi / usercalls / mod.rs
1 // Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 pub use fortanix_sgx_abi::*;
12
13 use io::{Error as IoError, Result as IoResult};
14
15 mod alloc;
16 #[macro_use]
17 mod raw;
18
19 pub fn launch_thread() -> IoResult<()> {
20     unsafe { raw::launch_thread().from_sgx_result() }
21 }
22
23 pub fn exit(panic: bool) -> ! {
24     unsafe { raw::exit(panic) }
25 }
26
27 pub fn wait(event_mask: u64, timeout: u64) -> IoResult<u64> {
28     unsafe { raw::wait(event_mask, timeout).from_sgx_result() }
29 }
30
31 pub fn send(event_set: u64, tcs: Option<Tcs>) -> IoResult<()> {
32     unsafe { raw::send(event_set, tcs).from_sgx_result() }
33 }
34
35 pub fn alloc(size: usize, alignment: usize) -> IoResult<*mut u8> {
36     unsafe { raw::alloc(size, alignment).from_sgx_result() }
37 }
38
39 pub use self::raw::free;
40
41 fn check_os_error(err: Result) -> i32 {
42     // FIXME: not sure how to make sure all variants of Error are covered
43     if err == Error::NotFound as _ ||
44        err == Error::PermissionDenied as _ ||
45        err == Error::ConnectionRefused as _ ||
46        err == Error::ConnectionReset as _ ||
47        err == Error::ConnectionAborted as _ ||
48        err == Error::NotConnected as _ ||
49        err == Error::AddrInUse as _ ||
50        err == Error::AddrNotAvailable as _ ||
51        err == Error::BrokenPipe as _ ||
52        err == Error::AlreadyExists as _ ||
53        err == Error::WouldBlock as _ ||
54        err == Error::InvalidInput as _ ||
55        err == Error::InvalidData as _ ||
56        err == Error::TimedOut as _ ||
57        err == Error::WriteZero as _ ||
58        err == Error::Interrupted as _ ||
59        err == Error::Other as _ ||
60        err == Error::UnexpectedEof as _ ||
61        ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&err)
62     {
63         err
64     } else {
65         panic!("Usercall: returned invalid error value {}", err)
66     }
67 }
68
69 trait FromSgxResult {
70     type Return;
71
72     fn from_sgx_result(self) -> IoResult<Self::Return>;
73 }
74
75 impl<T> FromSgxResult for (Result, T) {
76     type Return = T;
77
78     fn from_sgx_result(self) -> IoResult<Self::Return> {
79         if self.0 == RESULT_SUCCESS {
80             Ok(self.1)
81         } else {
82             Err(IoError::from_raw_os_error(check_os_error(self.0)))
83         }
84     }
85 }
86
87 impl FromSgxResult for Result {
88     type Return = ();
89
90     fn from_sgx_result(self) -> IoResult<Self::Return> {
91         if self == RESULT_SUCCESS {
92             Ok(())
93         } else {
94             Err(IoError::from_raw_os_error(check_os_error(self)))
95         }
96     }
97 }