Skip to content

Commit f5f5d5a

Browse files
committed
auto merge of #10479 : alexcrichton/rust/native-mutex.rs, r=cmr
This adds a new `std::unstable::mutex` module which contains bindings to the platform-provided mutexes. This module is pretty much entirely unsafe to use, but is critical for the runtime and dropping our C++ dependency. The actual implementation is to do a compare-and-swap on an initially uninitialized pointer. Pthreads does allow for static initialization, so this wouldn't be necessary if we had all the proper headers and whatnot, but windows it looks like will always require some sort of compare-and-swap operation. For now, I didn't want to have to define all the pthreads headers, so I continue to just malloc the pthreads lock/cvar. After this, there's only one remaining C++ component of rust, and that's unwinding.
2 parents ab7fe9d + 508b7b9 commit f5f5d5a

23 files changed

+695
-740
lines changed

mk/clean.mk

+31-17
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,19 @@
1212
# Cleanup
1313
######################################################################
1414

15-
CLEAN_STAGE_RULES = \
16-
$(foreach stage, $(STAGES), \
17-
$(foreach host, $(CFG_HOST), \
15+
CLEAN_STAGE_RULES := \
16+
$(foreach stage, $(STAGES), \
17+
$(foreach host, $(CFG_HOST), \
1818
clean$(stage)_H_$(host) \
19-
$(foreach target, $(CFG_TARGET), \
19+
$(foreach target, $(CFG_TARGET), \
2020
clean$(stage)_T_$(target)_H_$(host))))
2121

22+
CLEAN_STAGE_RULES := $(CLEAN_STAGE_RULES) \
23+
$(foreach host, $(CFG_HOST), clean-generic-H-$(host))
24+
25+
CLEAN_STAGE_RULES := $(CLEAN_STAGE_RULES) \
26+
$(foreach host, $(CFG_TARGET), clean-generic-T-$(host))
27+
2228
CLEAN_LLVM_RULES = \
2329
$(foreach target, $(CFG_HOST), \
2430
clean-llvm$(target))
@@ -33,19 +39,6 @@ clean: clean-misc $(CLEAN_STAGE_RULES)
3339

3440
clean-misc:
3541
@$(call E, cleaning)
36-
$(Q)find $(CFG_BUILD)/rustllvm \
37-
$(CFG_BUILD)/rt \
38-
$(CFG_BUILD)/test \
39-
-name '*.[odasS]' -o \
40-
-name '*.so' -o \
41-
-name '*.dylib' -o \
42-
-name '*.dll' -o \
43-
-name '*.def' -o \
44-
-name '*.bc' \
45-
| xargs rm -f
46-
$(Q)find $(CFG_BUILD)\
47-
-name '*.dSYM' \
48-
| xargs rm -Rf
4942
$(Q)rm -f $(RUNTIME_OBJS) $(RUNTIME_DEF)
5043
$(Q)rm -f $(RUSTLLVM_LIB_OBJS) $(RUSTLLVM_OBJS_OBJS) $(RUSTLLVM_DEF)
5144
$(Q)rm -Rf $(DOCS)
@@ -60,6 +53,27 @@ clean-misc:
6053
$(Q)rm -Rf $(foreach sub, index styles files search javascript, \
6154
$(wildcard doc/*/$(sub)))
6255

56+
define CLEAN_GENERIC
57+
58+
clean-generic-$(2)-$(1):
59+
$(Q)find $(1)/rustllvm \
60+
$(1)/rt \
61+
$(1)/test \
62+
-name '*.[odasS]' -o \
63+
-name '*.so' -o \
64+
-name '*.dylib' -o \
65+
-name '*.dll' -o \
66+
-name '*.def' -o \
67+
-name '*.bc' \
68+
| xargs rm -f
69+
$(Q)find $(1)\
70+
-name '*.dSYM' \
71+
| xargs rm -Rf
72+
endef
73+
74+
$(foreach host, $(CFG_HOST), $(eval $(call CLEAN_GENERIC,$(host),H)))
75+
$(foreach targ, $(CFG_TARGET), $(eval $(call CLEAN_GENERIC,$(targ),T)))
76+
6377
define CLEAN_HOST_STAGE_N
6478

6579
clean$(1)_H_$(2):

mk/platform.mk

+2-2
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ CFG_LIB_GLOB_arm-apple-darwin = lib$(1)-*.dylib
206206
CFG_LIB_DSYM_GLOB_arm-apple-darwin = lib$(1)-*.dylib.dSYM
207207
CFG_GCCISH_CFLAGS_arm-apple-darwin := -Wall -Werror -g -fPIC $(CFG_IOS_FLAGS)
208208
CFG_GCCISH_CXXFLAGS_arm-apple-darwin := -fno-rtti $(CFG_IOS_FLAGS)
209-
CFG_GCCISH_LINK_FLAGS_arm-apple-darwin := -dynamiclib -lpthread -framework CoreServices -Wl,-no_compact_unwind
209+
CFG_GCCISH_LINK_FLAGS_arm-apple-darwin := -dynamiclib -lpthread -framework CoreServices -Wl,-no_compact_unwind
210210
CFG_GCCISH_DEF_FLAG_arm-apple-darwin := -Wl,-exported_symbols_list,
211211
CFG_GCCISH_PRE_LIB_FLAGS_arm-apple-darwin :=
212212
CFG_GCCISH_POST_LIB_FLAGS_arm-apple-darwin :=
@@ -506,7 +506,7 @@ define CFG_MAKE_TOOLCHAIN
506506
-c -o $$(1) $$(2)
507507
CFG_LINK_C_$(1) = $$(CC_$(1)) \
508508
$$(CFG_GCCISH_LINK_FLAGS) -o $$(1) \
509-
$$(CFG_GCCISH_LINK_FLAGS_$(1))) \
509+
$$(CFG_GCCISH_LINK_FLAGS_$(1)) \
510510
$$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \
511511
$$(call CFG_INSTALL_NAME_$(1),$$(4))
512512
CFG_COMPILE_CXX_$(1) = $$(CXX_$(1)) \

mk/rt.mk

+16-12
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,18 @@ endif
9090
endif
9191

9292
RUNTIME_CXXS_$(1)_$(2) := \
93-
rt/sync/lock_and_signal.cpp \
94-
rt/rust_builtin.cpp \
95-
rt/rust_upcall.cpp \
96-
rt/miniz.cpp \
97-
rt/rust_android_dummy.cpp \
98-
rt/rust_test_helpers.cpp
93+
rt/rust_cxx_glue.cpp
9994

100-
RUNTIME_CS_$(1)_$(2) :=
95+
RUNTIME_CS_$(1)_$(2) := \
96+
rt/rust_builtin.c \
97+
rt/rust_upcall.c \
98+
rt/miniz.c \
99+
rt/rust_android_dummy.c \
100+
rt/rust_test_helpers.c
101+
102+
# stage0 remove this after the next snapshot
103+
%.cpp:
104+
@touch tmp/foo.o
101105

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

118-
$$(RT_BUILD_DIR_$(1)_$(2))/%.o: rt/%.cpp $$(MKFILE_DEPS)
122+
$$(RT_BUILD_DIR_$(1)_$(2))/rust_cxx_glue.o: rt/rust_cxx_glue.cpp $$(MKFILE_DEPS)
119123
@$$(call E, compile: $$@)
120124
$$(Q)$$(call CFG_COMPILE_CXX_$(1), $$@, $$(RUNTIME_INCS_$(1)_$(2)) \
121125
$$(SNAP_DEFINES) $$(RUNTIME_CXXFLAGS_$(1)_$(2))) $$<
@@ -242,13 +246,13 @@ endif
242246
UV_SUPPORT_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),uv_support)
243247
UV_SUPPORT_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/uv_support
244248
UV_SUPPORT_LIB_$(1) := $$(UV_SUPPORT_DIR_$(1))/$$(UV_SUPPORT_NAME_$(1))
245-
UV_SUPPORT_CS_$(1) := rt/rust_uv.cpp
246-
UV_SUPPORT_OBJS_$(1) := $$(UV_SUPPORT_CS_$(1):rt/%.cpp=$$(UV_SUPPORT_DIR_$(1))/%.o)
249+
UV_SUPPORT_CS_$(1) := rt/rust_uv.c
250+
UV_SUPPORT_OBJS_$(1) := $$(UV_SUPPORT_CS_$(1):rt/%.c=$$(UV_SUPPORT_DIR_$(1))/%.o)
247251

248-
$$(UV_SUPPORT_DIR_$(1))/%.o: rt/%.cpp
252+
$$(UV_SUPPORT_DIR_$(1))/%.o: rt/%.c
249253
@$$(call E, compile: $$@)
250254
@mkdir -p $$(@D)
251-
$$(Q)$$(call CFG_COMPILE_CXX_$(1), $$@, \
255+
$$(Q)$$(call CFG_COMPILE_C_$(1), $$@, \
252256
-I $$(S)src/libuv/include \
253257
$$(RUNTIME_CFLAGS_$(1))) $$<
254258

src/libstd/os.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -138,21 +138,19 @@ Accessing environment variables is not generally threadsafe.
138138
Serialize access through a global lock.
139139
*/
140140
fn with_env_lock<T>(f: &fn() -> T) -> T {
141+
use unstable::mutex::{Mutex, MUTEX_INIT};
141142
use unstable::finally::Finally;
142143

144+
static mut lock: Mutex = MUTEX_INIT;
145+
143146
unsafe {
144147
return do (|| {
145-
rust_take_env_lock();
148+
lock.lock();
146149
f()
147150
}).finally {
148-
rust_drop_env_lock();
151+
lock.unlock();
149152
};
150153
}
151-
152-
extern {
153-
fn rust_take_env_lock();
154-
fn rust_drop_env_lock();
155-
}
156154
}
157155

158156
/// Returns a vector of (variable, value) pairs for all the environment

src/libstd/rt/args.rs

+32-22
Original file line numberDiff line numberDiff line change
@@ -21,46 +21,60 @@
2121
//! FIXME #7756: This has a lot of C glue for lack of globals.
2222
2323
use option::Option;
24+
#[cfg(test)] use option::{Some, None};
25+
#[cfg(test)] use realstd;
26+
#[cfg(test)] use realargs = realstd::rt::args;
2427

2528
/// One-time global initialization.
26-
pub unsafe fn init(argc: int, argv: **u8) {
27-
imp::init(argc, argv)
28-
}
29+
#[cfg(not(test))]
30+
pub unsafe fn init(argc: int, argv: **u8) { imp::init(argc, argv) }
31+
#[cfg(test)]
32+
pub unsafe fn init(argc: int, argv: **u8) { realargs::init(argc, argv) }
2933

3034
/// One-time global cleanup.
31-
pub fn cleanup() {
32-
imp::cleanup()
33-
}
35+
#[cfg(not(test))] pub fn cleanup() { imp::cleanup() }
36+
#[cfg(test)] pub fn cleanup() { realargs::cleanup() }
3437

3538
/// Take the global arguments from global storage.
36-
pub fn take() -> Option<~[~str]> {
37-
imp::take()
39+
#[cfg(not(test))] pub fn take() -> Option<~[~str]> { imp::take() }
40+
#[cfg(test)] pub fn take() -> Option<~[~str]> {
41+
match realargs::take() {
42+
realstd::option::Some(a) => Some(a),
43+
realstd::option::None => None,
44+
}
3845
}
3946

4047
/// Give the global arguments to global storage.
4148
///
4249
/// It is an error if the arguments already exist.
43-
pub fn put(args: ~[~str]) {
44-
imp::put(args)
45-
}
50+
#[cfg(not(test))] pub fn put(args: ~[~str]) { imp::put(args) }
51+
#[cfg(test)] pub fn put(args: ~[~str]) { realargs::put(args) }
4652

4753
/// Make a clone of the global arguments.
48-
pub fn clone() -> Option<~[~str]> {
49-
imp::clone()
54+
#[cfg(not(test))] pub fn clone() -> Option<~[~str]> { imp::clone() }
55+
#[cfg(test)] pub fn clone() -> Option<~[~str]> {
56+
match realargs::clone() {
57+
realstd::option::Some(a) => Some(a),
58+
realstd::option::None => None,
59+
}
5060
}
5161

5262
#[cfg(target_os = "linux")]
5363
#[cfg(target_os = "android")]
5464
#[cfg(target_os = "freebsd")]
5565
mod imp {
66+
use cast;
5667
use libc;
5768
use option::{Option, Some, None};
5869
use iter::Iterator;
5970
use str;
6071
use unstable::finally::Finally;
72+
use unstable::mutex::{Mutex, MUTEX_INIT};
6173
use util;
6274
use vec;
6375

76+
static mut global_args_ptr: uint = 0;
77+
6478
pub unsafe fn init(argc: int, argv: **u8) {
6579
let args = load_argc_and_argv(argc, argv);
6680
put(args);
@@ -94,20 +108,22 @@ mod imp {
94108
}
95109

96110
fn with_lock<T>(f: &fn() -> T) -> T {
111+
static mut lock: Mutex = MUTEX_INIT;
112+
97113
do (|| {
98114
unsafe {
99-
rust_take_global_args_lock();
115+
lock.lock();
100116
f()
101117
}
102118
}).finally {
103119
unsafe {
104-
rust_drop_global_args_lock();
120+
lock.unlock();
105121
}
106122
}
107123
}
108124

109125
fn get_global_ptr() -> *mut Option<~~[~str]> {
110-
unsafe { rust_get_global_args_ptr() }
126+
unsafe { cast::transmute(&global_args_ptr) }
111127
}
112128

113129
// Copied from `os`.
@@ -117,12 +133,6 @@ mod imp {
117133
}
118134
}
119135

120-
extern {
121-
fn rust_take_global_args_lock();
122-
fn rust_drop_global_args_lock();
123-
fn rust_get_global_args_ptr() -> *mut Option<~~[~str]>;
124-
}
125-
126136
#[cfg(test)]
127137
mod tests {
128138
use option::{Some, None};

src/libstd/rt/local_ptr.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,23 @@ use ptr;
2121
use cell::Cell;
2222
use option::{Option, Some, None};
2323
use unstable::finally::Finally;
24+
use unstable::mutex::{Mutex, MUTEX_INIT};
2425
use tls = rt::thread_local_storage;
2526

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

2829
/// Initialize the TLS key. Other ops will fail if this isn't executed first.
2930
pub fn init_tls_key() {
31+
static mut lock: Mutex = MUTEX_INIT;
32+
static mut initialized: bool = false;
33+
3034
unsafe {
31-
rust_initialize_rt_tls_key(&mut RT_TLS_KEY);
32-
extern {
33-
fn rust_initialize_rt_tls_key(key: *mut tls::Key);
35+
lock.lock();
36+
if !initialized {
37+
tls::create(&mut RT_TLS_KEY);
38+
initialized = true;
3439
}
40+
lock.unlock();
3541
}
3642
}
3743

src/libstd/rt/test.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use cell::Cell;
1414
use clone::Clone;
1515
use container::Container;
1616
use iter::{Iterator, range};
17-
use libc;
1817
use option::{Some, None};
1918
use os;
2019
use path::GenericPath;
@@ -361,11 +360,16 @@ pub fn cleanup_task(mut task: ~Task) {
361360

362361
/// Get a port number, starting at 9600, for use in tests
363362
pub fn next_test_port() -> u16 {
363+
use unstable::mutex::{Mutex, MUTEX_INIT};
364+
static mut lock: Mutex = MUTEX_INIT;
365+
static mut next_offset: u16 = 0;
364366
unsafe {
365-
return rust_dbg_next_port(base_port() as libc::uintptr_t) as u16;
366-
}
367-
extern {
368-
fn rust_dbg_next_port(base: libc::uintptr_t) -> libc::uintptr_t;
367+
let base = base_port();
368+
lock.lock();
369+
let ret = base + next_offset;
370+
next_offset += 1;
371+
lock.unlock();
372+
return ret;
369373
}
370374
}
371375

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

403-
let base = 9600u;
404-
let range = 1000;
407+
let base = 9600u16;
408+
let range = 1000u16;
405409

406410
let bases = [
407411
("32-opt", base + range * 1),

0 commit comments

Comments
 (0)