Skip to content

Commit 1249850

Browse files
committed
---
yaml --- r: 139830 b: refs/heads/try2 c: 93757d8 h: refs/heads/master v: v3
1 parent 0925306 commit 1249850

File tree

2 files changed

+80
-75
lines changed

2 files changed

+80
-75
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: a2e5827866876e9bafcf1f4e94f4e354e500420a
8+
refs/heads/try2: 93757d81853302408dd30a3ad1a4102eae26b7c5
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libcore/rt/sched.rs

Lines changed: 79 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,11 @@
1111
use option::*;
1212
use sys;
1313
use cast::transmute;
14-
use libc::c_void;
15-
use ptr::mut_null;
1614

1715
use super::work_queue::WorkQueue;
1816
use super::stack::{StackPool, StackSegment};
1917
use super::rtio::{EventLoop, EventLoopObject};
2018
use super::context::Context;
21-
use tls = super::thread_local_storage;
2219

2320
#[cfg(test)] use super::uvio::UvEventLoop;
2421
#[cfg(test)] use unstable::run_in_bare_thread;
@@ -110,18 +107,13 @@ pub impl Scheduler {
110107
}
111108

112109
fn install(~self, f: &fn(&mut Scheduler)) -> ~Scheduler {
113-
let mut tlsched = ThreadLocalScheduler::new();
114-
tlsched.put_scheduler(self);
115-
{
116-
let sched = tlsched.get_scheduler();
117-
f(sched);
110+
do local::install(self) {
111+
local::borrow(f)
118112
}
119-
return tlsched.take_scheduler();
120113
}
121114

122115
fn local(f: &fn(&mut Scheduler)) {
123-
let mut tlsched = ThreadLocalScheduler::new();
124-
f(tlsched.get_scheduler());
116+
local::borrow(f)
125117
}
126118

127119
// * Scheduler-context operations
@@ -329,15 +321,15 @@ pub impl Task {
329321
// This is the first code to execute after the initial
330322
// context switch to the task. The previous context may
331323
// have asked us to do some cleanup.
332-
let mut sched = ThreadLocalScheduler::new();
333-
let sched = sched.get_scheduler();
334-
sched.run_cleanup_job();
324+
do Scheduler::local |sched| {
325+
sched.run_cleanup_job();
326+
}
335327

336328
start();
337329

338-
let mut sched = ThreadLocalScheduler::new();
339-
let sched = sched.get_scheduler();
340-
sched.terminate_current_task();
330+
do Scheduler::local |sched| {
331+
sched.terminate_current_task();
332+
}
341333
};
342334
return wrapper;
343335
}
@@ -352,90 +344,103 @@ pub impl Task {
352344
}
353345
}
354346

355-
// NB: This is a type so we can use make use of the &self region.
356-
struct ThreadLocalScheduler(tls::Key);
347+
mod local {
348+
349+
//! Access to the thread-local Scheduler
350+
351+
use ptr::mut_null;
352+
use libc::c_void;
353+
use cast::transmute;
354+
355+
use super::Scheduler;
356+
use tls = super::super::thread_local_storage;
357+
#[cfg(test)] use super::super::uvio::UvEventLoop;
357358

358-
impl ThreadLocalScheduler {
359-
fn new() -> ThreadLocalScheduler {
359+
/// Give the Scheduler to thread-local storage
360+
pub fn put(sched: ~Scheduler) {
360361
unsafe {
361-
// NB: This assumes that the TLS key has been created prior.
362-
// Currently done in rust_start.
363-
let key: *mut c_void = rust_get_sched_tls_key();
364-
let key: &mut tls::Key = transmute(key);
365-
ThreadLocalScheduler(*key)
362+
let key = tls_key();
363+
let void_sched: *mut c_void = transmute::<~Scheduler, *mut c_void>(sched);
364+
tls::set(key, void_sched);
366365
}
367366
}
368367

369-
fn put_scheduler(&mut self, scheduler: ~Scheduler) {
368+
/// Take ownership of the Scheduler from thread-local storage
369+
pub fn take() -> ~Scheduler {
370370
unsafe {
371-
let key = match self { &ThreadLocalScheduler(key) => key };
372-
let value: *mut c_void = transmute::<~Scheduler, *mut c_void>(scheduler);
373-
tls::set(key, value);
371+
let key = tls_key();
372+
let void_sched: *mut c_void = tls::get(key);
373+
assert!(void_sched.is_not_null());
374+
let sched = transmute::<*mut c_void, ~Scheduler>(void_sched);
375+
tls::set(key, mut_null());
376+
return sched;
374377
}
375378
}
376379

377-
fn get_scheduler(&mut self) -> &'self mut Scheduler {
380+
/// Give the Scheduler to thread-local storage for the duration of the block
381+
pub fn install(sched: ~Scheduler, f: &fn()) -> ~Scheduler {
382+
put(sched);
383+
f();
384+
return take();
385+
}
386+
387+
/// Borrow a mutable reference to the thread-local Scheduler
388+
/// # Safety Note
389+
/// Because this leaves the Scheduler in thread-local storage it is possible
390+
/// For the Scheduler pointer to be aliased
391+
pub fn borrow(f: &fn(&mut Scheduler)) {
378392
unsafe {
379-
let key = match self { &ThreadLocalScheduler(key) => key };
380-
let mut value: *mut c_void = tls::get(key);
381-
assert!(value.is_not_null());
393+
let key = tls_key();
394+
let mut void_sched: *mut c_void = tls::get(key);
395+
assert!(void_sched.is_not_null());
382396
{
383-
let value_ptr = &mut value;
397+
let void_sched_ptr = &mut void_sched;
384398
let sched: &mut ~Scheduler = {
385-
transmute::<&mut *mut c_void, &mut ~Scheduler>(value_ptr)
399+
transmute::<&mut *mut c_void, &mut ~Scheduler>(void_sched_ptr)
386400
};
387401
let sched: &mut Scheduler = &mut **sched;
388-
return sched;
402+
f(sched);
389403
}
390404
}
391405
}
392406

393-
fn take_scheduler(&mut self) -> ~Scheduler {
407+
fn tls_key() -> tls::Key {
394408
unsafe {
395-
let key = match self { &ThreadLocalScheduler(key) => key };
396-
let value: *mut c_void = tls::get(key);
397-
assert!(value.is_not_null());
398-
let sched = transmute(value);
399-
tls::set(key, mut_null());
400-
return sched;
409+
let key: *mut c_void = rust_get_sched_tls_key();
410+
let key: &mut tls::Key = transmute(key);
411+
return *key;
401412
}
402413
}
403-
}
404-
405-
extern {
406-
fn rust_get_sched_tls_key() -> *mut c_void;
407-
}
408-
409-
#[test]
410-
fn thread_local_scheduler_smoke_test() {
411-
let scheduler = ~UvEventLoop::new_scheduler();
412-
let mut tls_scheduler = ThreadLocalScheduler::new();
413-
tls_scheduler.put_scheduler(scheduler);
414-
{
415-
let _scheduler = tls_scheduler.get_scheduler();
416-
}
417-
let _scheduler = tls_scheduler.take_scheduler();
418-
}
419414

420-
#[test]
421-
fn thread_local_scheduler_two_instances() {
422-
let scheduler = ~UvEventLoop::new_scheduler();
423-
let mut tls_scheduler = ThreadLocalScheduler::new();
424-
tls_scheduler.put_scheduler(scheduler);
425-
{
415+
extern {
416+
fn rust_get_sched_tls_key() -> *mut c_void;
417+
}
426418

427-
let _scheduler = tls_scheduler.get_scheduler();
419+
#[test]
420+
fn thread_local_scheduler_smoke_test() {
421+
let scheduler = ~UvEventLoop::new_scheduler();
422+
put(scheduler);
423+
let _scheduler = take();
428424
}
429-
{
430-
let scheduler = tls_scheduler.take_scheduler();
431-
tls_scheduler.put_scheduler(scheduler);
425+
426+
#[test]
427+
fn thread_local_scheduler_two_instances() {
428+
let scheduler = ~UvEventLoop::new_scheduler();
429+
put(scheduler);
430+
let _scheduler = take();
431+
let scheduler = ~UvEventLoop::new_scheduler();
432+
put(scheduler);
433+
let _scheduler = take();
432434
}
433435

434-
let mut tls_scheduler = ThreadLocalScheduler::new();
435-
{
436-
let _scheduler = tls_scheduler.get_scheduler();
436+
#[test]
437+
fn install_borrow_smoke_test() {
438+
let scheduler = ~UvEventLoop::new_scheduler();
439+
let _scheduler = do install(scheduler) {
440+
do borrow |_sched| {
441+
}
442+
};
437443
}
438-
let _scheduler = tls_scheduler.take_scheduler();
439444
}
440445

441446
#[test]

0 commit comments

Comments
 (0)