Skip to content

Commit e8bf078

Browse files
committed
Remove the C++ lock_and_signal type
A the same time this purges all runtime support needed for statically initialized mutexes, moving all users over to the new Mutex type instead.
1 parent 24eb1b4 commit e8bf078

13 files changed

+92
-536
lines changed

mk/rt.mk

-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ endif
9090
endif
9191

9292
RUNTIME_CXXS_$(1)_$(2) := \
93-
rt/sync/lock_and_signal.cpp \
9493
rt/rust_builtin.cpp \
9594
rt/rust_upcall.cpp \
9695
rt/miniz.cpp \

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

+31-22
Original file line numberDiff line numberDiff line change
@@ -21,32 +21,42 @@
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")]
@@ -58,9 +68,12 @@ mod imp {
5868
use iter::Iterator;
5969
use str;
6070
use unstable::finally::Finally;
71+
use unstable::mutex::{Mutex, MUTEX_INIT};
6172
use util;
6273
use vec;
6374

75+
static mut global_args_ptr: uint = 0;
76+
6477
pub unsafe fn init(argc: int, argv: **u8) {
6578
let args = load_argc_and_argv(argc, argv);
6679
put(args);
@@ -94,20 +107,22 @@ mod imp {
94107
}
95108

96109
fn with_lock<T>(f: &fn() -> T) -> T {
110+
static mut lock: Mutex = MUTEX_INIT;
111+
97112
do (|| {
98113
unsafe {
99-
rust_take_global_args_lock();
114+
lock.lock();
100115
f()
101116
}
102117
}).finally {
103118
unsafe {
104-
rust_drop_global_args_lock();
119+
lock.unlock();
105120
}
106121
}
107122
}
108123

109124
fn get_global_ptr() -> *mut Option<~~[~str]> {
110-
unsafe { rust_get_global_args_ptr() }
125+
unsafe { cast::transmute(&global_args_ptr) }
111126
}
112127

113128
// Copied from `os`.
@@ -117,12 +132,6 @@ mod imp {
117132
}
118133
}
119134

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-
126135
#[cfg(test)]
127136
mod tests {
128137
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),

src/libstd/task/mod.rs

+12-22
Original file line numberDiff line numberDiff line change
@@ -1141,22 +1141,10 @@ fn test_spawn_sched_childs_on_default_sched() {
11411141
po.recv();
11421142
}
11431143
1144-
#[cfg(test)]
1145-
mod testrt {
1146-
use libc;
1147-
1148-
extern {
1149-
pub fn rust_dbg_lock_create() -> *libc::c_void;
1150-
pub fn rust_dbg_lock_destroy(lock: *libc::c_void);
1151-
pub fn rust_dbg_lock_lock(lock: *libc::c_void);
1152-
pub fn rust_dbg_lock_unlock(lock: *libc::c_void);
1153-
pub fn rust_dbg_lock_wait(lock: *libc::c_void);
1154-
pub fn rust_dbg_lock_signal(lock: *libc::c_void);
1155-
}
1156-
}
1157-
11581144
#[test]
11591145
fn test_spawn_sched_blocking() {
1146+
use unstable::mutex::Mutex;
1147+
11601148
unsafe {
11611149
11621150
// Testing that a task in one scheduler can block in foreign code
@@ -1165,16 +1153,18 @@ fn test_spawn_sched_blocking() {
11651153
let (start_po, start_ch) = stream();
11661154
let (fin_po, fin_ch) = stream();
11671155
1168-
let lock = testrt::rust_dbg_lock_create();
1156+
let mut lock = Mutex::new();
1157+
let lock2 = Cell::new(lock.clone());
11691158
11701159
do spawn_sched(SingleThreaded) {
1171-
testrt::rust_dbg_lock_lock(lock);
1160+
let mut lock = lock2.take();
1161+
lock.lock();
11721162
11731163
start_ch.send(());
11741164
11751165
// Block the scheduler thread
1176-
testrt::rust_dbg_lock_wait(lock);
1177-
testrt::rust_dbg_lock_unlock(lock);
1166+
lock.wait();
1167+
lock.unlock();
11781168
11791169
fin_ch.send(());
11801170
};
@@ -1201,11 +1191,11 @@ fn test_spawn_sched_blocking() {
12011191
let child_ch = setup_po.recv();
12021192
child_ch.send(20);
12031193
pingpong(&parent_po, &child_ch);
1204-
testrt::rust_dbg_lock_lock(lock);
1205-
testrt::rust_dbg_lock_signal(lock);
1206-
testrt::rust_dbg_lock_unlock(lock);
1194+
lock.lock();
1195+
lock.signal();
1196+
lock.unlock();
12071197
fin_po.recv();
1208-
testrt::rust_dbg_lock_destroy(lock);
1198+
lock.destroy();
12091199
}
12101200
}
12111201
}

src/libstd/unstable/dynamic_lib.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,17 @@ pub mod dl {
154154
}
155155

156156
pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> {
157+
use unstable::mutex::{Mutex, MUTEX_INIT};
158+
static mut lock: Mutex = MUTEX_INIT;
159+
157160
unsafe {
158161
// dlerror isn't thread safe, so we need to lock around this entire
159162
// sequence. `atomically` asserts that we don't do anything that
160163
// would cause this task to be descheduled, which could deadlock
161164
// the scheduler if it happens while the lock is held.
162165
// FIXME #9105 use a Rust mutex instead of C++ mutexes.
163166
do atomically {
164-
rust_take_dlerror_lock();
167+
lock.lock();
165168
let _old_error = dlerror();
166169

167170
let result = f();
@@ -172,7 +175,7 @@ pub mod dl {
172175
} else {
173176
Err(str::raw::from_c_str(last_error))
174177
};
175-
rust_drop_dlerror_lock();
178+
lock.unlock();
176179
ret
177180
}
178181
}
@@ -192,11 +195,6 @@ pub mod dl {
192195
Local = 0,
193196
}
194197

195-
extern {
196-
fn rust_take_dlerror_lock();
197-
fn rust_drop_dlerror_lock();
198-
}
199-
200198
#[link_name = "dl"]
201199
extern {
202200
fn dlopen(filename: *libc::c_char, flag: libc::c_int) -> *libc::c_void;

0 commit comments

Comments
 (0)