]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // Copyright 2014 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 | ||
c30ab7b3 SL |
11 | //! Platform-independent platform abstraction |
12 | //! | |
476ff2be | 13 | //! This is the platform-independent portion of the standard library's |
c30ab7b3 SL |
14 | //! platform abstraction layer, whereas `std::sys` is the |
15 | //! platform-specific portion. | |
16 | //! | |
17 | //! The relationship between `std::sys_common`, `std::sys` and the | |
18 | //! rest of `std` is complex, with dependencies going in all | |
19 | //! directions: `std` depending on `sys_common`, `sys_common` | |
20 | //! depending on `sys`, and `sys` depending on `sys_common` and `std`. | |
21 | //! Ideally `sys_common` would be split into two and the dependencies | |
22 | //! between them all would form a dag, facilitating the extraction of | |
23 | //! `std::sys` from the standard library. | |
24 | ||
1a4d82fc | 25 | #![allow(missing_docs)] |
32a655c1 | 26 | #![allow(missing_debug_implementations)] |
1a4d82fc | 27 | |
e9174d1e SL |
28 | use sync::Once; |
29 | use sys; | |
c34b1796 | 30 | |
e9174d1e | 31 | pub mod at_exit_imp; |
8bb4bdeb | 32 | #[cfg(feature = "backtrace")] |
1a4d82fc JJ |
33 | pub mod backtrace; |
34 | pub mod condvar; | |
e9174d1e | 35 | pub mod io; |
c30ab7b3 | 36 | pub mod memchr; |
1a4d82fc | 37 | pub mod mutex; |
9346a6ac AL |
38 | pub mod poison; |
39 | pub mod remutex; | |
1a4d82fc | 40 | pub mod rwlock; |
1a4d82fc JJ |
41 | pub mod thread; |
42 | pub mod thread_info; | |
43 | pub mod thread_local; | |
e9174d1e | 44 | pub mod util; |
85aaf69f | 45 | pub mod wtf8; |
1a4d82fc | 46 | |
476ff2be SL |
47 | #[cfg(target_os = "redox")] |
48 | pub use sys::net; | |
49 | ||
50 | #[cfg(not(target_os = "redox"))] | |
51 | pub mod net; | |
52 | ||
8bb4bdeb | 53 | #[cfg(feature = "backtrace")] |
7453a54e | 54 | #[cfg(any(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "emscripten"))), |
e9174d1e SL |
55 | all(windows, target_env = "gnu")))] |
56 | pub mod gnu; | |
57 | ||
1a4d82fc JJ |
58 | // common error constructors |
59 | ||
85aaf69f SL |
60 | /// A trait for viewing representations from std types |
61 | #[doc(hidden)] | |
62 | pub trait AsInner<Inner: ?Sized> { | |
1a4d82fc JJ |
63 | fn as_inner(&self) -> &Inner; |
64 | } | |
65 | ||
85aaf69f SL |
66 | /// A trait for viewing representations from std types |
67 | #[doc(hidden)] | |
68 | pub trait AsInnerMut<Inner: ?Sized> { | |
69 | fn as_inner_mut(&mut self) -> &mut Inner; | |
70 | } | |
71 | ||
72 | /// A trait for extracting representations from std types | |
73 | #[doc(hidden)] | |
74 | pub trait IntoInner<Inner> { | |
75 | fn into_inner(self) -> Inner; | |
76 | } | |
77 | ||
78 | /// A trait for creating std types from internal representations | |
79 | #[doc(hidden)] | |
80 | pub trait FromInner<Inner> { | |
81 | fn from_inner(inner: Inner) -> Self; | |
82 | } | |
e9174d1e SL |
83 | |
84 | /// Enqueues a procedure to run when the main thread exits. | |
85 | /// | |
86 | /// Currently these closures are only run once the main *Rust* thread exits. | |
87 | /// Once the `at_exit` handlers begin running, more may be enqueued, but not | |
88 | /// infinitely so. Eventually a handler registration will be forced to fail. | |
89 | /// | |
90 | /// Returns `Ok` if the handler was successfully registered, meaning that the | |
91 | /// closure will be run once the main thread exits. Returns `Err` to indicate | |
92 | /// that the closure could not be registered, meaning that it is not scheduled | |
93 | /// to be run. | |
94 | pub fn at_exit<F: FnOnce() + Send + 'static>(f: F) -> Result<(), ()> { | |
95 | if at_exit_imp::push(Box::new(f)) {Ok(())} else {Err(())} | |
96 | } | |
97 | ||
c30ab7b3 SL |
98 | macro_rules! rtabort { |
99 | ($($t:tt)*) => (::sys_common::util::abort(format_args!($($t)*))) | |
100 | } | |
101 | ||
e9174d1e SL |
102 | /// One-time runtime cleanup. |
103 | pub fn cleanup() { | |
104 | static CLEANUP: Once = Once::new(); | |
105 | CLEANUP.call_once(|| unsafe { | |
c30ab7b3 | 106 | sys::args::cleanup(); |
e9174d1e SL |
107 | sys::stack_overflow::cleanup(); |
108 | at_exit_imp::cleanup(); | |
109 | }); | |
110 | } | |
92a42be0 SL |
111 | |
112 | // Computes (value*numer)/denom without overflow, as long as both | |
113 | // (numer*denom) and the overall result fit into i64 (which is the case | |
114 | // for our time conversions). | |
115 | #[allow(dead_code)] // not used on all platforms | |
116 | pub fn mul_div_u64(value: u64, numer: u64, denom: u64) -> u64 { | |
117 | let q = value / denom; | |
118 | let r = value % denom; | |
119 | // Decompose value as (value/denom*denom + value%denom), | |
120 | // substitute into (value*numer)/denom and simplify. | |
121 | // r < denom, so (denom*numer) is the upper bound of (r*numer) | |
122 | q * numer + r * numer / denom | |
123 | } | |
124 | ||
125 | #[test] | |
126 | fn test_muldiv() { | |
127 | assert_eq!(mul_div_u64( 1_000_000_000_001, 1_000_000_000, 1_000_000), | |
128 | 1_000_000_000_001_000); | |
129 | } |