diff options
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/Cargo.toml | 2 | ||||
| -rw-r--r-- | src/libstd/collections/hash/set.rs | 6 | ||||
| -rw-r--r-- | src/libstd/f32.rs | 10 | ||||
| -rw-r--r-- | src/libstd/f64.rs | 10 | ||||
| -rw-r--r-- | src/libstd/ffi/os_str.rs | 1 | ||||
| -rw-r--r-- | src/libstd/sys/sgx/alloc.rs | 16 | ||||
| -rw-r--r-- | src/libstd/sys/sgx/mod.rs | 9 | ||||
| -rw-r--r-- | src/libstd/sys/sgx/rwlock.rs | 42 | ||||
| -rw-r--r-- | src/libstd/sys/sgx/stdio.rs | 18 | ||||
| -rw-r--r-- | src/libstd/sys/unix/time.rs | 27 | ||||
| -rw-r--r-- | src/libstd/sys/wasi/fs.rs | 173 | ||||
| -rw-r--r-- | src/libstd/sys/windows/time.rs | 24 | ||||
| -rw-r--r-- | src/libstd/sys_common/os_str_bytes.rs | 2 |
13 files changed, 187 insertions, 153 deletions
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 875483518e8..86ad334d886 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -19,7 +19,7 @@ panic_unwind = { path = "../libpanic_unwind", optional = true } panic_abort = { path = "../libpanic_abort" } core = { path = "../libcore" } libc = { version = "0.2.51", default-features = false, features = ['rustc-dep-of-std'] } -compiler_builtins = { version = "0.1.8" } +compiler_builtins = { version = "0.1.9" } profiler_builtins = { path = "../libprofiler_builtins", optional = true } unwind = { path = "../libunwind" } rustc-demangle = { version = "0.1.10", features = ['rustc-dep-of-std'] } diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 89d5b2ff30f..b9fcc2365fa 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -627,7 +627,11 @@ impl<T, S> HashSet<T, S> /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn is_subset(&self, other: &HashSet<T, S>) -> bool { - self.iter().all(|v| other.contains(v)) + if self.len() <= other.len() { + self.iter().all(|v| other.contains(v)) + } else { + false + } } /// Returns `true` if the set is a superset of another, diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 2952c6aea00..133540ed6b9 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -193,11 +193,11 @@ impl f32 { } /// Returns a number composed of the magnitude of `self` and the sign of - /// `y`. + /// `sign`. /// - /// Equal to `self` if the sign of `self` and `y` are the same, otherwise + /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise /// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of - /// `y` is returned. + /// `sign` is returned. /// /// # Examples /// @@ -216,8 +216,8 @@ impl f32 { #[inline] #[must_use] #[stable(feature = "copysign", since = "1.35.0")] - pub fn copysign(self, y: f32) -> f32 { - unsafe { intrinsics::copysignf32(self, y) } + pub fn copysign(self, sign: f32) -> f32 { + unsafe { intrinsics::copysignf32(self, sign) } } /// Fused multiply-add. Computes `(self * a) + b` with only one rounding diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 3c3a35573ad..87467aeed8b 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -171,11 +171,11 @@ impl f64 { } /// Returns a number composed of the magnitude of `self` and the sign of - /// `y`. + /// `sign`. /// - /// Equal to `self` if the sign of `self` and `y` are the same, otherwise + /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise /// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of - /// `y` is returned. + /// `sign` is returned. /// /// # Examples /// @@ -194,8 +194,8 @@ impl f64 { #[inline] #[must_use] #[stable(feature = "copysign", since = "1.35.0")] - pub fn copysign(self, y: f64) -> f64 { - unsafe { intrinsics::copysignf64(self, y) } + pub fn copysign(self, sign: f64) -> f64 { + unsafe { intrinsics::copysignf64(self, sign) } } /// Fused multiply-add. Computes `(self * a) + b` with only one rounding diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 01e7a57cd00..13aee783750 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -960,6 +960,7 @@ impl IntoInner<Buf> for OsString { } impl AsInner<Slice> for OsStr { + #[inline] fn as_inner(&self) -> &Slice { &self.inner } diff --git a/src/libstd/sys/sgx/alloc.rs b/src/libstd/sys/sgx/alloc.rs index 98eb8397436..b385d567dd8 100644 --- a/src/libstd/sys/sgx/alloc.rs +++ b/src/libstd/sys/sgx/alloc.rs @@ -1,4 +1,4 @@ -use crate::alloc::{GlobalAlloc, Layout, System}; +use crate::alloc::{self, GlobalAlloc, Layout, System}; use super::waitqueue::SpinMutex; @@ -30,3 +30,17 @@ unsafe impl GlobalAlloc for System { DLMALLOC.lock().realloc(ptr, layout.size(), layout.align(), new_size) } } + +// The following functions are needed by libunwind. These symbols are named +// in pre-link args for the target specification, so keep that in sync. +#[cfg(not(test))] +#[no_mangle] +pub unsafe extern "C" fn __rust_c_alloc(size: usize, align: usize) -> *mut u8 { + alloc::alloc(Layout::from_size_align_unchecked(size, align)) +} + +#[cfg(not(test))] +#[no_mangle] +pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usize) { + alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align)) +} diff --git a/src/libstd/sys/sgx/mod.rs b/src/libstd/sys/sgx/mod.rs index b0679f65f0d..a99a534f41e 100644 --- a/src/libstd/sys/sgx/mod.rs +++ b/src/libstd/sys/sgx/mod.rs @@ -130,6 +130,15 @@ pub unsafe fn abort_internal() -> ! { abi::usercalls::exit(true) } +// This function is needed by the panic runtime. The symbol is named in +// pre-link args for the target specification, so keep that in sync. +#[cfg(not(test))] +#[no_mangle] +// NB. used by both libunwind and libpanic_abort +pub unsafe extern "C" fn __rust_abort() { + abort_internal(); +} + pub fn hashmap_random_keys() -> (u64, u64) { fn rdrand64() -> u64 { unsafe { diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs index 09b5ffb1996..30c47e44eef 100644 --- a/src/libstd/sys/sgx/rwlock.rs +++ b/src/libstd/sys/sgx/rwlock.rs @@ -1,10 +1,4 @@ -#[cfg(not(test))] -use crate::alloc::{self, Layout}; use crate::num::NonZeroUsize; -#[cfg(not(test))] -use crate::slice; -#[cfg(not(test))] -use crate::str; use super::waitqueue::{ try_lock_or_false, NotifiedTcs, SpinMutex, SpinMutexGuard, WaitQueue, WaitVariable, @@ -165,10 +159,11 @@ impl RWLock { pub unsafe fn destroy(&self) {} } +// The following functions are needed by libunwind. These symbols are named +// in pre-link args for the target specification, so keep that in sync. #[cfg(not(test))] const EINVAL: i32 = 22; -// used by libunwind port #[cfg(not(test))] #[no_mangle] pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 { @@ -198,39 +193,6 @@ pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 { return 0; } -// the following functions are also used by the libunwind port. They're -// included here to make sure parallel codegen and LTO don't mess things up. -#[cfg(not(test))] -#[no_mangle] -pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) { - if s < 0 { - return; - } - let buf = slice::from_raw_parts(m as *const u8, s as _); - if let Ok(s) = str::from_utf8(&buf[..buf.iter().position(|&b| b == 0).unwrap_or(buf.len())]) { - eprint!("{}", s); - } -} - -#[cfg(not(test))] -#[no_mangle] -// NB. used by both libunwind and libpanic_abort -pub unsafe extern "C" fn __rust_abort() { - crate::sys::abort_internal(); -} - -#[cfg(not(test))] -#[no_mangle] -pub unsafe extern "C" fn __rust_c_alloc(size: usize, align: usize) -> *mut u8 { - alloc::alloc(Layout::from_size_align_unchecked(size, align)) -} - -#[cfg(not(test))] -#[no_mangle] -pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usize) { - alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align)) -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/libstd/sys/sgx/stdio.rs b/src/libstd/sys/sgx/stdio.rs index f2c6892bfb7..a575401f5f6 100644 --- a/src/libstd/sys/sgx/stdio.rs +++ b/src/libstd/sys/sgx/stdio.rs @@ -2,6 +2,10 @@ use fortanix_sgx_abi as abi; use crate::io; use crate::sys::fd::FileDesc; +#[cfg(not(test))] +use crate::slice; +#[cfg(not(test))] +use crate::str; pub struct Stdin(()); pub struct Stdout(()); @@ -62,3 +66,17 @@ pub fn is_ebadf(err: &io::Error) -> bool { pub fn panic_output() -> Option<impl io::Write> { super::abi::panic::SgxPanicOutput::new() } + +// This function is needed by libunwind. The symbol is named in pre-link args +// for the target specification, so keep that in sync. +#[cfg(not(test))] +#[no_mangle] +pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) { + if s < 0 { + return; + } + let buf = slice::from_raw_parts(m as *const u8, s as _); + if let Ok(s) = str::from_utf8(&buf[..buf.iter().position(|&b| b == 0).unwrap_or(buf.len())]) { + eprint!("{}", s); + } +} diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs index 127ae6aa104..e21c32cd91b 100644 --- a/src/libstd/sys/unix/time.rs +++ b/src/libstd/sys/unix/time.rs @@ -114,7 +114,8 @@ impl Hash for Timespec { #[cfg(any(target_os = "macos", target_os = "ios"))] mod inner { use crate::fmt; - use crate::sync::Once; + use crate::mem; + use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use crate::sys::cvt; use crate::sys_common::mul_div_u64; use crate::time::Duration; @@ -229,18 +230,30 @@ mod inner { Some(mul_div_u64(nanos, info.denom as u64, info.numer as u64)) } - fn info() -> &'static libc::mach_timebase_info { + fn info() -> libc::mach_timebase_info { static mut INFO: libc::mach_timebase_info = libc::mach_timebase_info { numer: 0, denom: 0, }; - static ONCE: Once = Once::new(); + static STATE: AtomicUsize = AtomicUsize::new(0); unsafe { - ONCE.call_once(|| { - libc::mach_timebase_info(&mut INFO); - }); - &INFO + // If a previous thread has filled in this global state, use that. + if STATE.load(SeqCst) == 2 { + return INFO; + } + + // ... otherwise learn for ourselves ... + let mut info = mem::zeroed(); + libc::mach_timebase_info(&mut info); + + // ... and attempt to be the one thread that stores it globally for + // all other threads + if STATE.compare_exchange(0, 1, SeqCst, SeqCst).is_ok() { + INFO = info; + STATE.store(2, SeqCst); + } + return info; } } } diff --git a/src/libstd/sys/wasi/fs.rs b/src/libstd/sys/wasi/fs.rs index 7b1c2bd79cc..589593299d6 100644 --- a/src/libstd/sys/wasi/fs.rs +++ b/src/libstd/sys/wasi/fs.rs @@ -1,5 +1,4 @@ -use crate::collections::HashMap; -use crate::ffi::{OsStr, OsString}; +use crate::ffi::{CStr, CString, OsStr, OsString}; use crate::fmt; use crate::io::{self, IoVec, IoVecMut, SeekFrom}; use crate::iter; @@ -7,11 +6,10 @@ use crate::mem::{self, ManuallyDrop}; use crate::os::wasi::ffi::{OsStrExt, OsStringExt}; use crate::path::{Path, PathBuf}; use crate::ptr; -use crate::sync::atomic::{AtomicPtr, Ordering::SeqCst}; use crate::sync::Arc; use crate::sys::fd::{DirCookie, WasiFd}; use crate::sys::time::SystemTime; -use crate::sys::{cvt_wasi, unsupported}; +use crate::sys::unsupported; use crate::sys_common::FromInner; pub use crate::sys_common::fs::copy; @@ -230,7 +228,11 @@ impl DirEntry { } pub fn metadata(&self) -> io::Result<FileAttr> { - metadata_at(&self.inner.dir.fd, 0, OsStr::from_bytes(&self.name).as_ref()) + metadata_at( + &self.inner.dir.fd, + 0, + OsStr::from_bytes(&self.name).as_ref(), + ) } pub fn file_type(&self) -> io::Result<FileType> { @@ -377,8 +379,8 @@ impl OpenOptions { impl File { pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> { - let (dir, file) = open_parent(path)?; - open_at(&dir, file, opts) + let (dir, file) = open_parent(path, libc::__WASI_RIGHT_PATH_OPEN)?; + open_at(&dir, &file, opts) } pub fn open_at(&self, path: &Path, opts: &OpenOptions) -> io::Result<File> { @@ -475,7 +477,7 @@ impl DirBuilder { } pub fn mkdir(&self, p: &Path) -> io::Result<()> { - let (dir, file) = open_parent(p)?; + let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_CREATE_DIRECTORY)?; dir.create_directory(file.as_os_str().as_bytes()) } } @@ -506,13 +508,13 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> { } pub fn unlink(p: &Path) -> io::Result<()> { - let (dir, file) = open_parent(p)?; + let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_UNLINK_FILE)?; dir.unlink_file(file.as_os_str().as_bytes()) } pub fn rename(old: &Path, new: &Path) -> io::Result<()> { - let (old, old_file) = open_parent(old)?; - let (new, new_file) = open_parent(new)?; + let (old, old_file) = open_parent(old, libc::__WASI_RIGHT_PATH_RENAME_SOURCE)?; + let (new, new_file) = open_parent(new, libc::__WASI_RIGHT_PATH_RENAME_TARGET)?; old.rename( old_file.as_os_str().as_bytes(), &new, @@ -527,13 +529,13 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> { } pub fn rmdir(p: &Path) -> io::Result<()> { - let (dir, file) = open_parent(p)?; + let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_REMOVE_DIRECTORY)?; dir.remove_directory(file.as_os_str().as_bytes()) } pub fn readlink(p: &Path) -> io::Result<PathBuf> { - let (dir, file) = open_parent(p)?; - read_link(&dir, file) + let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_READLINK)?; + read_link(&dir, &file) } fn read_link(fd: &WasiFd, file: &Path) -> io::Result<PathBuf> { @@ -568,13 +570,13 @@ fn read_link(fd: &WasiFd, file: &Path) -> io::Result<PathBuf> { } pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> { - let (dst, dst_file) = open_parent(dst)?; + let (dst, dst_file) = open_parent(dst, libc::__WASI_RIGHT_PATH_SYMLINK)?; dst.symlink(src.as_os_str().as_bytes(), dst_file.as_os_str().as_bytes()) } pub fn link(src: &Path, dst: &Path) -> io::Result<()> { - let (src, src_file) = open_parent(src)?; - let (dst, dst_file) = open_parent(dst)?; + let (src, src_file) = open_parent(src, libc::__WASI_RIGHT_PATH_LINK_SOURCE)?; + let (dst, dst_file) = open_parent(dst, libc::__WASI_RIGHT_PATH_LINK_TARGET)?; src.link( libc::__WASI_LOOKUP_SYMLINK_FOLLOW, src_file.as_os_str().as_bytes(), @@ -584,13 +586,13 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> { } pub fn stat(p: &Path) -> io::Result<FileAttr> { - let (dir, file) = open_parent(p)?; - metadata_at(&dir, libc::__WASI_LOOKUP_SYMLINK_FOLLOW, file) + let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_FILESTAT_GET)?; + metadata_at(&dir, libc::__WASI_LOOKUP_SYMLINK_FOLLOW, &file) } pub fn lstat(p: &Path) -> io::Result<FileAttr> { - let (dir, file) = open_parent(p)?; - metadata_at(&dir, 0, file) + let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_FILESTAT_GET)?; + metadata_at(&dir, 0, &file) } fn metadata_at( @@ -621,72 +623,69 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> { Ok(File { fd }) } -// FIXME: we shouldn't implement this. It'd be much better to share this between -// libc (the wasi-sysroot) and Rust as the logic here is likely far more tricky -// than what we're executing below. For now this is a stopgap to enable this -// module, but we should add an official API in upstream wasi-libc which looks -// like this. -// -// In the meantime this is highly unlikely to be correct. It allows some basic -// testing but is not at all robust. -fn open_parent(p: &Path) -> io::Result<(&'static WasiFd, &Path)> { - let map = preopened_map(); - for ancestor in p.ancestors() { - if let Some(fd) = map.get(ancestor) { - let tail = p.strip_prefix(ancestor).unwrap(); - let tail = if tail == Path::new("") { - ".".as_ref() - } else { - tail - }; - return Ok((fd, tail)) - } - } - let msg = format!("failed to find a preopened file descriptor to open {:?}", p); - return Err(io::Error::new(io::ErrorKind::Other, msg)); - - type Preopened = HashMap<PathBuf, ManuallyDrop<WasiFd>>; - fn preopened_map() -> &'static Preopened { - static PTR: AtomicPtr<Preopened> = AtomicPtr::new(ptr::null_mut()); - unsafe { - let ptr = PTR.load(SeqCst); - if !ptr.is_null() { - return &*ptr; - } - - let mut map = Box::new(HashMap::new()); - for fd in 3.. { - let mut buf = mem::zeroed(); - if cvt_wasi(libc::__wasi_fd_prestat_get(fd, &mut buf)).is_err() { - break; - } - if buf.pr_type != libc::__WASI_PREOPENTYPE_DIR { - continue; - } - let len = buf.u.dir.pr_name_len; - let mut v = vec![0u8; len]; - let res = cvt_wasi(libc::__wasi_fd_prestat_dir_name( - fd, - v.as_mut_ptr() as *mut i8, - v.len(), - )); - if res.is_err() { - continue; - } - let path = PathBuf::from(OsString::from_vec(v)); - map.insert(path, ManuallyDrop::new(WasiFd::from_raw(fd))); - } - let ptr = Box::into_raw(map); - match PTR.compare_exchange(ptr::null_mut(), ptr, SeqCst, SeqCst) { - Ok(_) => &*ptr, - - // If we lost the race for initialization clean up the map we - // made and just use the one that's already there - Err(other) => { - drop(Box::from_raw(ptr)); - &*other - } - } +/// Attempts to open a bare path `p`. +/// +/// WASI has no fundamental capability to do this. All syscalls and operations +/// are relative to already-open file descriptors. The C library, however, +/// manages a map of preopened file descriptors to their path, and then the C +/// library provides an API to look at this. In other words, when you want to +/// open a path `p`, you have to find a previously opened file descriptor in a +/// global table and then see if `p` is relative to that file descriptor. +/// +/// This function, if successful, will return two items: +/// +/// * The first is a `ManuallyDrop<WasiFd>`. This represents a preopened file +/// descriptor which we don't have ownership of, but we can use. You shouldn't +/// actually drop the `fd`. +/// +/// * The second is a path that should be a part of `p` and represents a +/// relative traversal from the file descriptor specified to the desired +/// location `p`. +/// +/// If successful you can use the returned file descriptor to perform +/// file-descriptor-relative operations on the path returned as well. The +/// `rights` argument indicates what operations are desired on the returned file +/// descriptor, and if successful the returned file descriptor should have the +/// appropriate rights for performing `rights` actions. +/// +/// Note that this can fail if `p` doesn't look like it can be opened relative +/// to any preopened file descriptor. +fn open_parent( + p: &Path, + rights: libc::__wasi_rights_t, +) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> { + let p = CString::new(p.as_os_str().as_bytes())?; + unsafe { + let mut ret = ptr::null(); + let fd = __wasilibc_find_relpath(p.as_ptr(), rights, 0, &mut ret); + if fd == -1 { + let msg = format!( + "failed to find a preopened file descriptor \ + through which {:?} could be opened", + p + ); + return Err(io::Error::new(io::ErrorKind::Other, msg)); } + let path = Path::new(OsStr::from_bytes(CStr::from_ptr(ret).to_bytes())); + + // FIXME: right now `path` is a pointer into `p`, the `CString` above. + // When we return `p` is deallocated and we can't use it, so we need to + // currently separately allocate `path`. If this becomes an issue though + // we should probably turn this into a closure-taking interface or take + // `&CString` and then pass off `&Path` tied to the same lifetime. + let path = path.to_path_buf(); + + return Ok((ManuallyDrop::new(WasiFd::from_raw(fd as u32)), path)); + } + + // FIXME(rust-lang/libc#1314) use the `libc` crate for this when the API + // there is published + extern "C" { + pub fn __wasilibc_find_relpath( + path: *const libc::c_char, + rights_base: libc::__wasi_rights_t, + rights_inheriting: libc::__wasi_rights_t, + relative_path: *mut *const libc::c_char, + ) -> libc::c_int; } } diff --git a/src/libstd/sys/windows/time.rs b/src/libstd/sys/windows/time.rs index 4c9d2aee157..e0f0e3a1a45 100644 --- a/src/libstd/sys/windows/time.rs +++ b/src/libstd/sys/windows/time.rs @@ -173,7 +173,7 @@ fn intervals2dur(intervals: u64) -> Duration { mod perf_counter { use super::{NANOS_PER_SEC}; - use crate::sync::Once; + use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use crate::sys_common::mul_div_u64; use crate::sys::c; use crate::sys::cvt; @@ -210,13 +210,25 @@ mod perf_counter { fn frequency() -> c::LARGE_INTEGER { static mut FREQUENCY: c::LARGE_INTEGER = 0; - static ONCE: Once = Once::new(); + static STATE: AtomicUsize = AtomicUsize::new(0); unsafe { - ONCE.call_once(|| { - cvt(c::QueryPerformanceFrequency(&mut FREQUENCY)).unwrap(); - }); - FREQUENCY + // If a previous thread has filled in this global state, use that. + if STATE.load(SeqCst) == 2 { + return FREQUENCY; + } + + // ... otherwise learn for ourselves ... + let mut frequency = 0; + cvt(c::QueryPerformanceFrequency(&mut frequency)).unwrap(); + + // ... and attempt to be the one thread that stores it globally for + // all other threads + if STATE.compare_exchange(0, 1, SeqCst, SeqCst).is_ok() { + FREQUENCY = frequency; + STATE.store(2, SeqCst); + } + return frequency; } } diff --git a/src/libstd/sys_common/os_str_bytes.rs b/src/libstd/sys_common/os_str_bytes.rs index 7cc93477a73..a4961974d89 100644 --- a/src/libstd/sys_common/os_str_bytes.rs +++ b/src/libstd/sys_common/os_str_bytes.rs @@ -236,9 +236,11 @@ pub trait OsStrExt { #[stable(feature = "rust1", since = "1.0.0")] impl OsStrExt for OsStr { + #[inline] fn from_bytes(slice: &[u8]) -> &OsStr { unsafe { mem::transmute(slice) } } + #[inline] fn as_bytes(&self) -> &[u8] { &self.as_inner().inner } |
