]>
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 | |
ea8adc8c | 47 | #[cfg(any(target_os = "redox", target_os = "l4re"))] |
476ff2be SL |
48 | pub use sys::net; |
49 | ||
ea8adc8c | 50 | #[cfg(not(any(target_os = "redox", target_os = "l4re")))] |
476ff2be SL |
51 | pub mod net; |
52 | ||
8bb4bdeb | 53 | #[cfg(feature = "backtrace")] |
ea8adc8c | 54 | #[cfg(any(all(unix, not(target_os = "emscripten")), |
041b39d2 XL |
55 | all(windows, target_env = "gnu"), |
56 | target_os = "redox"))] | |
e9174d1e SL |
57 | pub mod gnu; |
58 | ||
1a4d82fc JJ |
59 | // common error constructors |
60 | ||
85aaf69f SL |
61 | /// A trait for viewing representations from std types |
62 | #[doc(hidden)] | |
63 | pub trait AsInner<Inner: ?Sized> { | |
1a4d82fc JJ |
64 | fn as_inner(&self) -> &Inner; |
65 | } | |
66 | ||
85aaf69f SL |
67 | /// A trait for viewing representations from std types |
68 | #[doc(hidden)] | |
69 | pub trait AsInnerMut<Inner: ?Sized> { | |
70 | fn as_inner_mut(&mut self) -> &mut Inner; | |
71 | } | |
72 | ||
73 | /// A trait for extracting representations from std types | |
74 | #[doc(hidden)] | |
75 | pub trait IntoInner<Inner> { | |
76 | fn into_inner(self) -> Inner; | |
77 | } | |
78 | ||
79 | /// A trait for creating std types from internal representations | |
80 | #[doc(hidden)] | |
81 | pub trait FromInner<Inner> { | |
82 | fn from_inner(inner: Inner) -> Self; | |
83 | } | |
e9174d1e SL |
84 | |
85 | /// Enqueues a procedure to run when the main thread exits. | |
86 | /// | |
87 | /// Currently these closures are only run once the main *Rust* thread exits. | |
88 | /// Once the `at_exit` handlers begin running, more may be enqueued, but not | |
89 | /// infinitely so. Eventually a handler registration will be forced to fail. | |
90 | /// | |
91 | /// Returns `Ok` if the handler was successfully registered, meaning that the | |
92 | /// closure will be run once the main thread exits. Returns `Err` to indicate | |
93 | /// that the closure could not be registered, meaning that it is not scheduled | |
94 | /// to be run. | |
95 | pub fn at_exit<F: FnOnce() + Send + 'static>(f: F) -> Result<(), ()> { | |
96 | if at_exit_imp::push(Box::new(f)) {Ok(())} else {Err(())} | |
97 | } | |
98 | ||
c30ab7b3 SL |
99 | macro_rules! rtabort { |
100 | ($($t:tt)*) => (::sys_common::util::abort(format_args!($($t)*))) | |
101 | } | |
102 | ||
e9174d1e SL |
103 | /// One-time runtime cleanup. |
104 | pub fn cleanup() { | |
105 | static CLEANUP: Once = Once::new(); | |
106 | CLEANUP.call_once(|| unsafe { | |
c30ab7b3 | 107 | sys::args::cleanup(); |
e9174d1e SL |
108 | sys::stack_overflow::cleanup(); |
109 | at_exit_imp::cleanup(); | |
110 | }); | |
111 | } | |
92a42be0 SL |
112 | |
113 | // Computes (value*numer)/denom without overflow, as long as both | |
114 | // (numer*denom) and the overall result fit into i64 (which is the case | |
115 | // for our time conversions). | |
116 | #[allow(dead_code)] // not used on all platforms | |
117 | pub fn mul_div_u64(value: u64, numer: u64, denom: u64) -> u64 { | |
118 | let q = value / denom; | |
119 | let r = value % denom; | |
120 | // Decompose value as (value/denom*denom + value%denom), | |
121 | // substitute into (value*numer)/denom and simplify. | |
122 | // r < denom, so (denom*numer) is the upper bound of (r*numer) | |
123 | q * numer + r * numer / denom | |
124 | } | |
125 | ||
126 | #[test] | |
127 | fn test_muldiv() { | |
128 | assert_eq!(mul_div_u64( 1_000_000_000_001, 1_000_000_000, 1_000_000), | |
129 | 1_000_000_000_001_000); | |
130 | } |