]>
git.proxmox.com Git - rustc.git/blob - src/libstd/sys_common/mod.rs
1 //! Platform-independent platform abstraction
3 //! This is the platform-independent portion of the standard library's
4 //! platform abstraction layer, whereas `std::sys` is the
5 //! platform-specific portion.
7 //! The relationship between `std::sys_common`, `std::sys` and the
8 //! rest of `std` is complex, with dependencies going in all
9 //! directions: `std` depending on `sys_common`, `sys_common`
10 //! depending on `sys`, and `sys` depending on `sys_common` and `std`.
11 //! Ideally `sys_common` would be split into two and the dependencies
12 //! between them all would form a dag, facilitating the extraction of
13 //! `std::sys` from the standard library.
15 #![allow(missing_docs)]
16 #![allow(missing_debug_implementations)]
18 use crate::sync
::Once
;
21 macro_rules
! rtabort
{
22 ($
($t
:tt
)*) => (crate::sys_common
::util
::abort(format_args
!($
($t
)*)))
25 macro_rules
! rtassert
{
26 ($e
:expr
) => (if !$e
{
27 rtabort
!(concat
!("assertion failed: ", stringify
!($e
)));
31 #[allow(unused_macros)] // not used on all platforms
32 macro_rules
! rtunwrap
{
33 ($ok
:ident
, $e
:expr
) => (match $e
{
36 let err
= err
.as_ref().map(|_
|()); // map Ok/Some which might not be Debug
37 rtabort
!(concat
!("unwrap failed: ", stringify
!($e
), " = {:?}"), err
)
48 #[cfg(any(doc, // see `mod os`, docs are generated for multiple platforms
51 target_os
= "cloudabi",
53 target_arch
= "wasm32",
54 all(target_vendor
= "fortanix", target_env
= "sgx")))]
69 if #[cfg(any(target_os = "cloudabi",
72 all(target_arch
= "wasm32", not(target_os
= "emscripten")),
73 all(target_vendor
= "fortanix", target_env
= "sgx")))] {
74 pub use crate::sys
::net
;
80 // common error constructors
82 /// A trait for viewing representations from std types
84 pub trait AsInner
<Inner
: ?Sized
> {
85 fn as_inner(&self) -> &Inner
;
88 /// A trait for viewing representations from std types
90 pub trait AsInnerMut
<Inner
: ?Sized
> {
91 fn as_inner_mut(&mut self) -> &mut Inner
;
94 /// A trait for extracting representations from std types
96 pub trait IntoInner
<Inner
> {
97 fn into_inner(self) -> Inner
;
100 /// A trait for creating std types from internal representations
102 pub trait FromInner
<Inner
> {
103 fn from_inner(inner
: Inner
) -> Self;
106 /// Enqueues a procedure to run when the main thread exits.
108 /// Currently these closures are only run once the main *Rust* thread exits.
109 /// Once the `at_exit` handlers begin running, more may be enqueued, but not
110 /// infinitely so. Eventually a handler registration will be forced to fail.
112 /// Returns `Ok` if the handler was successfully registered, meaning that the
113 /// closure will be run once the main thread exits. Returns `Err` to indicate
114 /// that the closure could not be registered, meaning that it is not scheduled
116 pub fn at_exit
<F
: FnOnce() + Send
+ '
static>(f
: F
) -> Result
<(), ()> {
117 if at_exit_imp
::push(Box
::new(f
)) {Ok(())}
else {Err(())}
120 /// One-time runtime cleanup.
122 static CLEANUP
: Once
= Once
::new();
123 CLEANUP
.call_once(|| unsafe {
124 sys
::args
::cleanup();
125 sys
::stack_overflow
::cleanup();
126 at_exit_imp
::cleanup();
130 // Computes (value*numer)/denom without overflow, as long as both
131 // (numer*denom) and the overall result fit into i64 (which is the case
132 // for our time conversions).
133 #[allow(dead_code)] // not used on all platforms
134 pub fn mul_div_u64(value
: u64, numer
: u64, denom
: u64) -> u64 {
135 let q
= value
/ denom
;
136 let r
= value
% denom
;
137 // Decompose value as (value/denom*denom + value%denom),
138 // substitute into (value*numer)/denom and simplify.
139 // r < denom, so (denom*numer) is the upper bound of (r*numer)
140 q
* numer
+ r
* numer
/ denom
145 assert_eq
!(mul_div_u64( 1_000_000_000_001, 1_000_000_000, 1_000_000),
146 1_000_000_000_001_000);