Skip to content

Commit

Permalink
Use const fn to abstract away the contents of UnsafeCell & friends.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed May 27, 2015
1 parent 6e8e4f8 commit 377b090
Show file tree
Hide file tree
Showing 76 changed files with 417 additions and 525 deletions.
4 changes: 2 additions & 2 deletions src/libcollectionstest/vec.rs
Expand Up @@ -399,7 +399,7 @@ fn test_map_in_place_zero_sized() {

#[test]
fn test_map_in_place_zero_drop_count() {
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use std::sync::atomic::{AtomicUsize, Ordering};

#[derive(Clone, PartialEq, Debug)]
struct Nothing;
Expand All @@ -413,7 +413,7 @@ fn test_map_in_place_zero_drop_count() {
}
}
const NUM_ELEMENTS: usize = 2;
static DROP_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);

let v = repeat(Nothing).take(NUM_ELEMENTS).collect::<Vec<_>>();

Expand Down
47 changes: 20 additions & 27 deletions src/libcore/atomic.rs
Expand Up @@ -76,7 +76,6 @@ use marker::Sync;

use intrinsics;
use cell::UnsafeCell;
use marker::PhantomData;

use default::Default;

Expand All @@ -87,8 +86,8 @@ pub struct AtomicBool {
}

impl Default for AtomicBool {
fn default() -> AtomicBool {
ATOMIC_BOOL_INIT
fn default() -> Self {
Self::new(Default::default())
}
}

Expand All @@ -101,8 +100,8 @@ pub struct AtomicIsize {
}

impl Default for AtomicIsize {
fn default() -> AtomicIsize {
ATOMIC_ISIZE_INIT
fn default() -> Self {
Self::new(Default::default())
}
}

Expand All @@ -115,8 +114,8 @@ pub struct AtomicUsize {
}

impl Default for AtomicUsize {
fn default() -> AtomicUsize {
ATOMIC_USIZE_INIT
fn default() -> Self {
Self::new(Default::default())
}
}

Expand All @@ -125,8 +124,7 @@ unsafe impl Sync for AtomicUsize {}
/// A raw pointer type which can be safely shared between threads.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct AtomicPtr<T> {
p: UnsafeCell<usize>,
_marker: PhantomData<*mut T>,
p: UnsafeCell<*mut T>,
}

impl<T> Default for AtomicPtr<T> {
Expand Down Expand Up @@ -175,16 +173,13 @@ pub enum Ordering {

/// An `AtomicBool` initialized to `false`.
#[stable(feature = "rust1", since = "1.0.0")]
pub const ATOMIC_BOOL_INIT: AtomicBool =
AtomicBool { v: UnsafeCell { value: 0 } };
pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
/// An `AtomicIsize` initialized to `0`.
#[stable(feature = "rust1", since = "1.0.0")]
pub const ATOMIC_ISIZE_INIT: AtomicIsize =
AtomicIsize { v: UnsafeCell { value: 0 } };
pub const ATOMIC_ISIZE_INIT: AtomicIsize = AtomicIsize::new(0);
/// An `AtomicUsize` initialized to `0`.
#[stable(feature = "rust1", since = "1.0.0")]
pub const ATOMIC_USIZE_INIT: AtomicUsize =
AtomicUsize { v: UnsafeCell { value: 0, } };
pub const ATOMIC_USIZE_INIT: AtomicUsize = AtomicUsize::new(0);

// NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
const UINT_TRUE: usize = !0;
Expand All @@ -202,9 +197,8 @@ impl AtomicBool {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(v: bool) -> AtomicBool {
let val = if v { UINT_TRUE } else { 0 };
AtomicBool { v: UnsafeCell::new(val) }
pub const fn new(v: bool) -> AtomicBool {
AtomicBool { v: UnsafeCell::new(-(v as isize) as usize) }
}

/// Loads a value from the bool.
Expand Down Expand Up @@ -445,7 +439,7 @@ impl AtomicIsize {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(v: isize) -> AtomicIsize {
pub const fn new(v: isize) -> AtomicIsize {
AtomicIsize {v: UnsafeCell::new(v)}
}

Expand Down Expand Up @@ -633,7 +627,7 @@ impl AtomicUsize {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(v: usize) -> AtomicUsize {
pub const fn new(v: usize) -> AtomicUsize {
AtomicUsize { v: UnsafeCell::new(v) }
}

Expand Down Expand Up @@ -821,9 +815,8 @@ impl<T> AtomicPtr<T> {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(p: *mut T) -> AtomicPtr<T> {
AtomicPtr { p: UnsafeCell::new(p as usize),
_marker: PhantomData }
pub const fn new(p: *mut T) -> AtomicPtr<T> {
AtomicPtr { p: UnsafeCell::new(p) }
}

/// Loads a value from the pointer.
Expand All @@ -848,7 +841,7 @@ impl<T> AtomicPtr<T> {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn load(&self, order: Ordering) -> *mut T {
unsafe {
atomic_load(self.p.get(), order) as *mut T
atomic_load(self.p.get() as *mut usize, order) as *mut T
}
}

Expand All @@ -875,7 +868,7 @@ impl<T> AtomicPtr<T> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn store(&self, ptr: *mut T, order: Ordering) {
unsafe { atomic_store(self.p.get(), ptr as usize, order); }
unsafe { atomic_store(self.p.get() as *mut usize, ptr as usize, order); }
}

/// Stores a value into the pointer, returning the old value.
Expand All @@ -897,7 +890,7 @@ impl<T> AtomicPtr<T> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
unsafe { atomic_swap(self.p.get(), ptr as usize, order) as *mut T }
unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T }
}

/// Stores a value into the pointer if the current value is the same as the expected value.
Expand Down Expand Up @@ -925,7 +918,7 @@ impl<T> AtomicPtr<T> {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn compare_and_swap(&self, old: *mut T, new: *mut T, order: Ordering) -> *mut T {
unsafe {
atomic_compare_and_swap(self.p.get(), old as usize,
atomic_compare_and_swap(self.p.get() as *mut usize, old as usize,
new as usize, order) as *mut T
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/libcore/cell.rs
Expand Up @@ -170,7 +170,7 @@ impl<T:Copy> Cell<T> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn new(value: T) -> Cell<T> {
pub const fn new(value: T) -> Cell<T> {
Cell {
value: UnsafeCell::new(value),
}
Expand Down Expand Up @@ -302,7 +302,7 @@ impl<T> RefCell<T> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn new(value: T) -> RefCell<T> {
pub const fn new(value: T) -> RefCell<T> {
RefCell {
value: UnsafeCell::new(value),
borrow: Cell::new(UNUSED),
Expand Down Expand Up @@ -663,7 +663,7 @@ impl<T> UnsafeCell<T> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn new(value: T) -> UnsafeCell<T> {
pub const fn new(value: T) -> UnsafeCell<T> {
UnsafeCell { value: value }
}

Expand Down
1 change: 1 addition & 0 deletions src/libcore/lib.rs
Expand Up @@ -74,6 +74,7 @@
#![feature(concat_idents)]
#![feature(reflect)]
#![feature(custom_attribute)]
#![feature(const_fn)]

#[macro_use]
mod macros;
Expand Down
10 changes: 6 additions & 4 deletions src/libcoretest/atomic.rs
Expand Up @@ -70,13 +70,15 @@ fn int_xor() {
assert_eq!(x.load(SeqCst), 0xf731 ^ 0x137f);
}

static S_BOOL : AtomicBool = ATOMIC_BOOL_INIT;
static S_INT : AtomicIsize = ATOMIC_ISIZE_INIT;
static S_UINT : AtomicUsize = ATOMIC_USIZE_INIT;
static S_FALSE: AtomicBool = AtomicBool::new(false);
static S_TRUE: AtomicBool = AtomicBool::new(true);
static S_INT: AtomicIsize = AtomicIsize::new(0);
static S_UINT: AtomicUsize = AtomicUsize::new(0);

#[test]
fn static_init() {
assert!(!S_BOOL.load(SeqCst));
assert!(!S_FALSE.load(SeqCst));
assert!(S_TRUE.load(SeqCst));
assert!(S_INT.load(SeqCst) == 0);
assert!(S_UINT.load(SeqCst) == 0);
}
6 changes: 3 additions & 3 deletions src/liblog/lib.rs
Expand Up @@ -184,7 +184,7 @@ use std::mem;
use std::env;
use std::rt;
use std::slice;
use std::sync::{Once, ONCE_INIT, StaticMutex, MUTEX_INIT};
use std::sync::{Once, StaticMutex};

use directive::LOG_LEVEL_NAMES;

Expand All @@ -200,7 +200,7 @@ pub const MAX_LOG_LEVEL: u32 = 255;
/// The default logging level of a crate if no other is specified.
const DEFAULT_LOG_LEVEL: u32 = 1;

static LOCK: StaticMutex = MUTEX_INIT;
static LOCK: StaticMutex = StaticMutex::new();

/// An unsafe constant that is the maximum logging level of any module
/// specified. This is the first line of defense to determining whether a
Expand Down Expand Up @@ -367,7 +367,7 @@ pub struct LogLocation {
/// module's log statement should be emitted or not.
#[doc(hidden)]
pub fn mod_enabled(level: u32, module: &str) -> bool {
static INIT: Once = ONCE_INIT;
static INIT: Once = Once::new();
INIT.call_once(init);

// It's possible for many threads are in this function, only one of them
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/infer/region_inference/graphviz.rs
Expand Up @@ -32,7 +32,7 @@ use std::env;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
use std::sync::atomic::{AtomicBool, Ordering};
use syntax::ast;

fn print_help_message() {
Expand Down Expand Up @@ -76,7 +76,7 @@ pub fn maybe_print_constraints_for<'a, 'tcx>(region_vars: &RegionVarBindings<'a,
let output_path = {
let output_template = match requested_output {
Ok(ref s) if &**s == "help" => {
static PRINTED_YET: AtomicBool = ATOMIC_BOOL_INIT;
static PRINTED_YET: AtomicBool = AtomicBool::new(false);
if !PRINTED_YET.load(Ordering::SeqCst) {
print_help_message();
PRINTED_YET.store(true, Ordering::SeqCst);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/back/write.rs
Expand Up @@ -1005,8 +1005,8 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
}

unsafe fn configure_llvm(sess: &Session) {
use std::sync::{Once, ONCE_INIT};
static INIT: Once = ONCE_INIT;
use std::sync::Once;
static INIT: Once = Once::new();

// Copy what clang does by turning on loop vectorization at O2 and
// slp vectorization at O3
Expand Down
1 change: 1 addition & 0 deletions src/librustc_trans/lib.rs
Expand Up @@ -39,6 +39,7 @@
#![feature(path_ext)]
#![feature(fs)]
#![feature(path_relative_from)]
#![feature(std_misc)]

#![allow(trivial_casts)]

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/trans/base.rs
Expand Up @@ -2653,8 +2653,8 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)

// Before we touch LLVM, make sure that multithreading is enabled.
unsafe {
use std::sync::{Once, ONCE_INIT};
static INIT: Once = ONCE_INIT;
use std::sync::Once;
static INIT: Once = Once::new();
static mut POISONED: bool = false;
INIT.call_once(|| {
if llvm::LLVMStartMultithreaded() != 1 {
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/dynamic_lib.rs
Expand Up @@ -211,8 +211,8 @@ mod dl {
pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
F: FnOnce() -> T,
{
use sync::{StaticMutex, MUTEX_INIT};
static LOCK: StaticMutex = MUTEX_INIT;
use sync::StaticMutex;
static LOCK: StaticMutex = StaticMutex::new();
unsafe {
// dlerror isn't thread safe, so we need to lock around this entire
// sequence
Expand Down
8 changes: 4 additions & 4 deletions src/libstd/env.rs
Expand Up @@ -23,8 +23,8 @@ use ffi::{OsStr, OsString};
use fmt;
use io;
use path::{Path, PathBuf};
use sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT, Ordering};
use sync::{StaticMutex, MUTEX_INIT};
use sync::atomic::{AtomicIsize, Ordering};
use sync::StaticMutex;
use sys::os as os_imp;

/// Returns the current working directory as a `PathBuf`.
Expand Down Expand Up @@ -70,7 +70,7 @@ pub fn set_current_dir<P: AsRef<Path>>(p: P) -> io::Result<()> {
os_imp::chdir(p.as_ref())
}

static ENV_LOCK: StaticMutex = MUTEX_INIT;
static ENV_LOCK: StaticMutex = StaticMutex::new();

/// An iterator over a snapshot of the environment variables of this process.
///
Expand Down Expand Up @@ -475,7 +475,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
os_imp::current_exe()
}

static EXIT_STATUS: AtomicIsize = ATOMIC_ISIZE_INIT;
static EXIT_STATUS: AtomicIsize = AtomicIsize::new(0);

/// Sets the process exit code
///
Expand Down
32 changes: 16 additions & 16 deletions src/libstd/io/lazy.rs
Expand Up @@ -11,31 +11,31 @@
use prelude::v1::*;

use boxed;
use cell::UnsafeCell;
use cell::Cell;
use rt;
use sync::{StaticMutex, Arc};

pub struct Lazy<T> {
pub lock: StaticMutex,
pub ptr: UnsafeCell<*mut Arc<T>>,
pub init: fn() -> Arc<T>,
lock: StaticMutex,
ptr: Cell<*mut Arc<T>>,
init: fn() -> Arc<T>,
}

unsafe impl<T> Sync for Lazy<T> {}

macro_rules! lazy_init {
($init:expr) => (::io::lazy::Lazy {
lock: ::sync::MUTEX_INIT,
ptr: ::cell::UnsafeCell { value: 0 as *mut _ },
init: $init,
})
}

impl<T: Send + Sync + 'static> Lazy<T> {
pub const fn new(init: fn() -> Arc<T>) -> Lazy<T> {
Lazy {
lock: StaticMutex::new(),
ptr: Cell::new(0 as *mut _),
init: init
}
}

pub fn get(&'static self) -> Option<Arc<T>> {
let _g = self.lock.lock();
let ptr = self.ptr.get();
unsafe {
let ptr = *self.ptr.get();
if ptr.is_null() {
Some(self.init())
} else if ptr as usize == 1 {
Expand All @@ -53,14 +53,14 @@ impl<T: Send + Sync + 'static> Lazy<T> {
// `Arc`.
let registered = rt::at_exit(move || {
let g = self.lock.lock();
let ptr = *self.ptr.get();
*self.ptr.get() = 1 as *mut _;
let ptr = self.ptr.get();
self.ptr.set(1 as *mut _);
drop(g);
drop(Box::from_raw(ptr))
});
let ret = (self.init)();
if registered.is_ok() {
*self.ptr.get() = boxed::into_raw(Box::new(ret.clone()));
self.ptr.set(boxed::into_raw(Box::new(ret.clone())));
}
return ret
}
Expand Down

0 comments on commit 377b090

Please sign in to comment.