Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a native mutex type #10479

Merged
merged 3 commits into from
Nov 19, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 31 additions & 17 deletions mk/clean.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@
# Cleanup
######################################################################

CLEAN_STAGE_RULES = \
$(foreach stage, $(STAGES), \
$(foreach host, $(CFG_HOST), \
CLEAN_STAGE_RULES := \
$(foreach stage, $(STAGES), \
$(foreach host, $(CFG_HOST), \
clean$(stage)_H_$(host) \
$(foreach target, $(CFG_TARGET), \
$(foreach target, $(CFG_TARGET), \
clean$(stage)_T_$(target)_H_$(host))))

CLEAN_STAGE_RULES := $(CLEAN_STAGE_RULES) \
$(foreach host, $(CFG_HOST), clean-generic-H-$(host))

CLEAN_STAGE_RULES := $(CLEAN_STAGE_RULES) \
$(foreach host, $(CFG_TARGET), clean-generic-T-$(host))

CLEAN_LLVM_RULES = \
$(foreach target, $(CFG_HOST), \
clean-llvm$(target))
Expand All @@ -33,19 +39,6 @@ clean: clean-misc $(CLEAN_STAGE_RULES)

clean-misc:
@$(call E, cleaning)
$(Q)find $(CFG_BUILD)/rustllvm \
$(CFG_BUILD)/rt \
$(CFG_BUILD)/test \
-name '*.[odasS]' -o \
-name '*.so' -o \
-name '*.dylib' -o \
-name '*.dll' -o \
-name '*.def' -o \
-name '*.bc' \
| xargs rm -f
$(Q)find $(CFG_BUILD)\
-name '*.dSYM' \
| xargs rm -Rf
$(Q)rm -f $(RUNTIME_OBJS) $(RUNTIME_DEF)
$(Q)rm -f $(RUSTLLVM_LIB_OBJS) $(RUSTLLVM_OBJS_OBJS) $(RUSTLLVM_DEF)
$(Q)rm -Rf $(DOCS)
Expand All @@ -60,6 +53,27 @@ clean-misc:
$(Q)rm -Rf $(foreach sub, index styles files search javascript, \
$(wildcard doc/*/$(sub)))

define CLEAN_GENERIC

clean-generic-$(2)-$(1):
$(Q)find $(1)/rustllvm \
$(1)/rt \
$(1)/test \
-name '*.[odasS]' -o \
-name '*.so' -o \
-name '*.dylib' -o \
-name '*.dll' -o \
-name '*.def' -o \
-name '*.bc' \
| xargs rm -f
$(Q)find $(1)\
-name '*.dSYM' \
| xargs rm -Rf
endef

$(foreach host, $(CFG_HOST), $(eval $(call CLEAN_GENERIC,$(host),H)))
$(foreach targ, $(CFG_TARGET), $(eval $(call CLEAN_GENERIC,$(targ),T)))

define CLEAN_HOST_STAGE_N

clean$(1)_H_$(2):
Expand Down
4 changes: 2 additions & 2 deletions mk/platform.mk
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ CFG_LIB_GLOB_arm-apple-darwin = lib$(1)-*.dylib
CFG_LIB_DSYM_GLOB_arm-apple-darwin = lib$(1)-*.dylib.dSYM
CFG_GCCISH_CFLAGS_arm-apple-darwin := -Wall -Werror -g -fPIC $(CFG_IOS_FLAGS)
CFG_GCCISH_CXXFLAGS_arm-apple-darwin := -fno-rtti $(CFG_IOS_FLAGS)
CFG_GCCISH_LINK_FLAGS_arm-apple-darwin := -dynamiclib -lpthread -framework CoreServices -Wl,-no_compact_unwind
CFG_GCCISH_LINK_FLAGS_arm-apple-darwin := -dynamiclib -lpthread -framework CoreServices -Wl,-no_compact_unwind
CFG_GCCISH_DEF_FLAG_arm-apple-darwin := -Wl,-exported_symbols_list,
CFG_GCCISH_PRE_LIB_FLAGS_arm-apple-darwin :=
CFG_GCCISH_POST_LIB_FLAGS_arm-apple-darwin :=
Expand Down Expand Up @@ -506,7 +506,7 @@ define CFG_MAKE_TOOLCHAIN
-c -o $$(1) $$(2)
CFG_LINK_C_$(1) = $$(CC_$(1)) \
$$(CFG_GCCISH_LINK_FLAGS) -o $$(1) \
$$(CFG_GCCISH_LINK_FLAGS_$(1))) \
$$(CFG_GCCISH_LINK_FLAGS_$(1)) \
$$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \
$$(call CFG_INSTALL_NAME_$(1),$$(4))
CFG_COMPILE_CXX_$(1) = $$(CXX_$(1)) \
Expand Down
28 changes: 16 additions & 12 deletions mk/rt.mk
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,18 @@ endif
endif

RUNTIME_CXXS_$(1)_$(2) := \
rt/sync/lock_and_signal.cpp \
rt/rust_builtin.cpp \
rt/rust_upcall.cpp \
rt/miniz.cpp \
rt/rust_android_dummy.cpp \
rt/rust_test_helpers.cpp
rt/rust_cxx_glue.cpp

RUNTIME_CS_$(1)_$(2) :=
RUNTIME_CS_$(1)_$(2) := \
rt/rust_builtin.c \
rt/rust_upcall.c \
rt/miniz.c \
rt/rust_android_dummy.c \
rt/rust_test_helpers.c

# stage0 remove this after the next snapshot
%.cpp:
@touch tmp/foo.o

RUNTIME_S_$(1)_$(2) := rt/arch/$$(HOST_$(1))/_context.S \
rt/arch/$$(HOST_$(1))/record_sp.S
Expand All @@ -115,7 +119,7 @@ ALL_OBJ_FILES += $$(RUNTIME_OBJS_$(1)_$(2))
MORESTACK_OBJS_$(1)_$(2) := $$(RT_BUILD_DIR_$(1)_$(2))/arch/$$(HOST_$(1))/morestack.o
ALL_OBJ_FILES += $$(MORESTACK_OBJS_$(1)_$(2))

$$(RT_BUILD_DIR_$(1)_$(2))/%.o: rt/%.cpp $$(MKFILE_DEPS)
$$(RT_BUILD_DIR_$(1)_$(2))/rust_cxx_glue.o: rt/rust_cxx_glue.cpp $$(MKFILE_DEPS)
@$$(call E, compile: $$@)
$$(Q)$$(call CFG_COMPILE_CXX_$(1), $$@, $$(RUNTIME_INCS_$(1)_$(2)) \
$$(SNAP_DEFINES) $$(RUNTIME_CXXFLAGS_$(1)_$(2))) $$<
Expand Down Expand Up @@ -242,13 +246,13 @@ endif
UV_SUPPORT_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),uv_support)
UV_SUPPORT_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/uv_support
UV_SUPPORT_LIB_$(1) := $$(UV_SUPPORT_DIR_$(1))/$$(UV_SUPPORT_NAME_$(1))
UV_SUPPORT_CS_$(1) := rt/rust_uv.cpp
UV_SUPPORT_OBJS_$(1) := $$(UV_SUPPORT_CS_$(1):rt/%.cpp=$$(UV_SUPPORT_DIR_$(1))/%.o)
UV_SUPPORT_CS_$(1) := rt/rust_uv.c
UV_SUPPORT_OBJS_$(1) := $$(UV_SUPPORT_CS_$(1):rt/%.c=$$(UV_SUPPORT_DIR_$(1))/%.o)

$$(UV_SUPPORT_DIR_$(1))/%.o: rt/%.cpp
$$(UV_SUPPORT_DIR_$(1))/%.o: rt/%.c
@$$(call E, compile: $$@)
@mkdir -p $$(@D)
$$(Q)$$(call CFG_COMPILE_CXX_$(1), $$@, \
$$(Q)$$(call CFG_COMPILE_C_$(1), $$@, \
-I $$(S)src/libuv/include \
$$(RUNTIME_CFLAGS_$(1))) $$<

Expand Down
12 changes: 5 additions & 7 deletions src/libstd/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,19 @@ Accessing environment variables is not generally threadsafe.
Serialize access through a global lock.
*/
fn with_env_lock<T>(f: &fn() -> T) -> T {
use unstable::mutex::{Mutex, MUTEX_INIT};
use unstable::finally::Finally;

static mut lock: Mutex = MUTEX_INIT;

unsafe {
return do (|| {
rust_take_env_lock();
lock.lock();
f()
}).finally {
rust_drop_env_lock();
lock.unlock();
};
}

extern {
fn rust_take_env_lock();
fn rust_drop_env_lock();
}
}

/// Returns a vector of (variable, value) pairs for all the environment
Expand Down
54 changes: 32 additions & 22 deletions src/libstd/rt/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,46 +21,60 @@
//! FIXME #7756: This has a lot of C glue for lack of globals.

use option::Option;
#[cfg(test)] use option::{Some, None};
#[cfg(test)] use realstd;
#[cfg(test)] use realargs = realstd::rt::args;

/// One-time global initialization.
pub unsafe fn init(argc: int, argv: **u8) {
imp::init(argc, argv)
}
#[cfg(not(test))]
pub unsafe fn init(argc: int, argv: **u8) { imp::init(argc, argv) }
#[cfg(test)]
pub unsafe fn init(argc: int, argv: **u8) { realargs::init(argc, argv) }

/// One-time global cleanup.
pub fn cleanup() {
imp::cleanup()
}
#[cfg(not(test))] pub fn cleanup() { imp::cleanup() }
#[cfg(test)] pub fn cleanup() { realargs::cleanup() }

/// Take the global arguments from global storage.
pub fn take() -> Option<~[~str]> {
imp::take()
#[cfg(not(test))] pub fn take() -> Option<~[~str]> { imp::take() }
#[cfg(test)] pub fn take() -> Option<~[~str]> {
match realargs::take() {
realstd::option::Some(a) => Some(a),
realstd::option::None => None,
}
}

/// Give the global arguments to global storage.
///
/// It is an error if the arguments already exist.
pub fn put(args: ~[~str]) {
imp::put(args)
}
#[cfg(not(test))] pub fn put(args: ~[~str]) { imp::put(args) }
#[cfg(test)] pub fn put(args: ~[~str]) { realargs::put(args) }

/// Make a clone of the global arguments.
pub fn clone() -> Option<~[~str]> {
imp::clone()
#[cfg(not(test))] pub fn clone() -> Option<~[~str]> { imp::clone() }
#[cfg(test)] pub fn clone() -> Option<~[~str]> {
match realargs::clone() {
realstd::option::Some(a) => Some(a),
realstd::option::None => None,
}
}

#[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(target_os = "freebsd")]
mod imp {
use cast;
use libc;
use option::{Option, Some, None};
use iter::Iterator;
use str;
use unstable::finally::Finally;
use unstable::mutex::{Mutex, MUTEX_INIT};
use util;
use vec;

static mut global_args_ptr: uint = 0;

pub unsafe fn init(argc: int, argv: **u8) {
let args = load_argc_and_argv(argc, argv);
put(args);
Expand Down Expand Up @@ -94,20 +108,22 @@ mod imp {
}

fn with_lock<T>(f: &fn() -> T) -> T {
static mut lock: Mutex = MUTEX_INIT;

do (|| {
unsafe {
rust_take_global_args_lock();
lock.lock();
f()
}
}).finally {
unsafe {
rust_drop_global_args_lock();
lock.unlock();
}
}
}

fn get_global_ptr() -> *mut Option<~~[~str]> {
unsafe { rust_get_global_args_ptr() }
unsafe { cast::transmute(&global_args_ptr) }
}

// Copied from `os`.
Expand All @@ -117,12 +133,6 @@ mod imp {
}
}

extern {
fn rust_take_global_args_lock();
fn rust_drop_global_args_lock();
fn rust_get_global_args_ptr() -> *mut Option<~~[~str]>;
}

#[cfg(test)]
mod tests {
use option::{Some, None};
Expand Down
12 changes: 9 additions & 3 deletions src/libstd/rt/local_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,23 @@ use ptr;
use cell::Cell;
use option::{Option, Some, None};
use unstable::finally::Finally;
use unstable::mutex::{Mutex, MUTEX_INIT};
use tls = rt::thread_local_storage;

static mut RT_TLS_KEY: tls::Key = -1;

/// Initialize the TLS key. Other ops will fail if this isn't executed first.
pub fn init_tls_key() {
static mut lock: Mutex = MUTEX_INIT;
static mut initialized: bool = false;

unsafe {
rust_initialize_rt_tls_key(&mut RT_TLS_KEY);
extern {
fn rust_initialize_rt_tls_key(key: *mut tls::Key);
lock.lock();
if !initialized {
tls::create(&mut RT_TLS_KEY);
initialized = true;
}
lock.unlock();
}
}

Expand Down
20 changes: 12 additions & 8 deletions src/libstd/rt/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use cell::Cell;
use clone::Clone;
use container::Container;
use iter::{Iterator, range};
use libc;
use option::{Some, None};
use os;
use path::GenericPath;
Expand Down Expand Up @@ -361,11 +360,16 @@ pub fn cleanup_task(mut task: ~Task) {

/// Get a port number, starting at 9600, for use in tests
pub fn next_test_port() -> u16 {
use unstable::mutex::{Mutex, MUTEX_INIT};
static mut lock: Mutex = MUTEX_INIT;
static mut next_offset: u16 = 0;
unsafe {
return rust_dbg_next_port(base_port() as libc::uintptr_t) as u16;
}
extern {
fn rust_dbg_next_port(base: libc::uintptr_t) -> libc::uintptr_t;
let base = base_port();
lock.lock();
let ret = base + next_offset;
next_offset += 1;
lock.unlock();
return ret;
}
}

Expand Down Expand Up @@ -395,13 +399,13 @@ The bots run multiple builds at the same time, and these builds
all want to use ports. This function figures out which workspace
it is running in and assigns a port range based on it.
*/
fn base_port() -> uint {
fn base_port() -> u16 {
use os;
use str::StrSlice;
use vec::ImmutableVector;

let base = 9600u;
let range = 1000;
let base = 9600u16;
let range = 1000u16;

let bases = [
("32-opt", base + range * 1),
Expand Down
Loading