Skip to content

Commit 0006983

Browse files
committed
---
yaml --- r: 147836 b: refs/heads/try2 c: 576a851 h: refs/heads/master v: v3
1 parent f9e15ca commit 0006983

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+705
-1737
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: a96951048c1420eb751cf401d88d93ec21b5d6ca
8+
refs/heads/try2: 576a85105f0d2dd25e9cef17c234e8b95299b062
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/doc/rust.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3806,6 +3806,25 @@ As a convenience, the logging spec can also be set to a special pseudo-crate,
38063806
`::help`. In this case, when the application starts, the runtime will
38073807
simply output a list of loaded modules containing log expressions, then exit.
38083808

3809+
The Rust runtime itself generates logging information. The runtime's logs are
3810+
generated for a number of artificial modules in the `::rt` pseudo-crate,
3811+
and can be enabled just like the logs for any standard module. The full list
3812+
of runtime logging modules follows.
3813+
3814+
* `::rt::mem` Memory management
3815+
* `::rt::comm` Messaging and task communication
3816+
* `::rt::task` Task management
3817+
* `::rt::dom` Task scheduling
3818+
* `::rt::trace` Unused
3819+
* `::rt::cache` Type descriptor cache
3820+
* `::rt::upcall` Compiler-generated runtime calls
3821+
* `::rt::timer` The scheduler timer
3822+
* `::rt::gc` Garbage collection
3823+
* `::rt::stdlib` Functions used directly by the standard library
3824+
* `::rt::kern` The runtime kernel
3825+
* `::rt::backtrace` Log a backtrace on task failure
3826+
* `::rt::callback` Unused
3827+
38093828
#### Logging Expressions
38103829

38113830
Rust provides several macros to log information. Here's a simple Rust program

branches/try2/src/driver/driver.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ extern mod this = "rustdoc";
1919
#[cfg(rustc)]
2020
extern mod this = "rustc";
2121

22+
#[cfg(rustdoc_ng)]
23+
extern mod this = "rustdoc_ng";
24+
2225
fn main() { this::main() }

branches/try2/src/etc/emacs/rust-mode.el

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,7 @@
5454
;; We don't want to indent out to the open bracket if the
5555
;; open bracket ends the line
5656
(when (not (looking-at "[[:blank:]]*\\(?://.*\\)?$"))
57-
(when (looking-at "[[:space:]]")
58-
(forward-word 1)
59-
(backward-word 1))
57+
(when (looking-at "[[:space:]]") (forward-to-word 1))
6058
(current-column))))
6159

6260
(defun rust-mode-indent-line ()

branches/try2/src/libextra/time.rs

Lines changed: 10 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,17 @@
1212

1313
use std::io::Reader;
1414
use std::io::mem::BufReader;
15-
use std::libc;
1615
use std::num;
1716
use std::str;
1817

1918
static NSEC_PER_SEC: i32 = 1_000_000_000_i32;
2019

21-
mod rustrt {
20+
pub mod rustrt {
2221
use super::Tm;
2322

2423
extern {
24+
pub fn rust_get_time(sec: &mut i64, nsec: &mut i32);
25+
pub fn rust_precise_time_ns(ns: &mut u64);
2526
pub fn rust_tzset();
2627
pub fn rust_gmtime(sec: i64, nsec: i32, result: &mut Tm);
2728
pub fn rust_localtime(sec: i64, nsec: i32, result: &mut Tm);
@@ -30,31 +31,6 @@ mod rustrt {
3031
}
3132
}
3233

33-
#[cfg(unix, not(target_os = "macos"))]
34-
mod imp {
35-
use std::libc::{c_int, timespec};
36-
37-
// Apparently android provides this in some other library?
38-
#[cfg(not(target_os = "android"))]
39-
#[link(name = "rt")]
40-
extern {}
41-
42-
extern {
43-
pub fn clock_gettime(clk_id: c_int, tp: *mut timespec) -> c_int;
44-
}
45-
46-
}
47-
#[cfg(target_os = "macos")]
48-
mod imp {
49-
use std::libc::{timeval, timezone, c_int, mach_timebase_info};
50-
51-
extern {
52-
pub fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int;
53-
pub fn mach_absolute_time() -> u64;
54-
pub fn mach_timebase_info(info: *mut mach_timebase_info) -> c_int;
55-
}
56-
}
57-
5834
/// A record specifying a time value in seconds and nanoseconds.
5935
6036

@@ -88,45 +64,11 @@ impl Ord for Timespec {
8864
*/
8965
pub fn get_time() -> Timespec {
9066
unsafe {
91-
let (sec, nsec) = os_get_time();
67+
let mut sec = 0i64;
68+
let mut nsec = 0i32;
69+
rustrt::rust_get_time(&mut sec, &mut nsec);
9270
return Timespec::new(sec, nsec);
9371
}
94-
95-
#[cfg(windows)]
96-
unsafe fn os_get_time() -> (i64, i32) {
97-
static NANOSECONDS_FROM_1601_TO_1970: u64 = 11644473600000000;
98-
99-
let mut time = libc::FILETIME {
100-
dwLowDateTime: 0,
101-
dwHighDateTime: 0,
102-
};
103-
libc::GetSystemTimeAsFileTime(&mut time);
104-
105-
// A FILETIME contains a 64-bit value representing the number of
106-
// hectonanosecond (100-nanosecond) intervals since 1601-01-01T00:00:00Z.
107-
// http://support.microsoft.com/kb/167296/en-us
108-
let ns_since_1601 = ((time.dwHighDateTime as u64 << 32) |
109-
(time.dwLowDateTime as u64 << 0)) / 10;
110-
let ns_since_1970 = ns_since_1601 - NANOSECONDS_FROM_1601_TO_1970;
111-
112-
((ns_since_1970 / 1000000) as i64,
113-
((ns_since_1970 % 1000000) * 1000) as i32)
114-
}
115-
116-
#[cfg(target_os = "macos")]
117-
unsafe fn os_get_time() -> (i64, i32) {
118-
use std::ptr;
119-
let mut tv = libc::timeval { tv_sec: 0, tv_usec: 0 };
120-
imp::gettimeofday(&mut tv, ptr::mut_null());
121-
(tv.tv_sec as i64, tv.tv_usec * 1000)
122-
}
123-
124-
#[cfg(not(target_os = "macos"), not(windows))]
125-
unsafe fn os_get_time() -> (i64, i32) {
126-
let mut tv = libc::timespec { tv_sec: 0, tv_nsec: 0 };
127-
imp::clock_gettime(libc::CLOCK_REALTIME, &mut tv);
128-
(tv.tv_sec as i64, tv.tv_nsec as i32)
129-
}
13072
}
13173

13274

@@ -135,38 +77,10 @@ pub fn get_time() -> Timespec {
13577
* in nanoseconds since an unspecified epoch.
13678
*/
13779
pub fn precise_time_ns() -> u64 {
138-
return os_precise_time_ns();
139-
140-
#[cfg(windows)]
141-
fn os_precise_time_ns() -> u64 {
142-
let mut ticks_per_s = 0;
143-
assert_eq!(unsafe {
144-
libc::QueryPerformanceFrequency(&mut ticks_per_s)
145-
}, 1);
146-
let ticks_per_s = if ticks_per_s == 0 {1} else {ticks_per_s};
147-
let mut ticks = 0;
148-
assert_eq!(unsafe {
149-
libc::QueryPerformanceCounter(&mut ticks)
150-
}, 1);
151-
152-
return (ticks as u64 * 1000000000) / (ticks_per_s as u64);
153-
}
154-
155-
#[cfg(target_os = "macos")]
156-
fn os_precise_time_ns() -> u64 {
157-
let time = unsafe { imp::mach_absolute_time() };
158-
let mut info = libc::mach_timebase_info { numer: 0, denom: 0 };
159-
unsafe { imp::mach_timebase_info(&mut info); }
160-
return time * ((info.numer / info.denom) as u64);
161-
}
162-
163-
#[cfg(not(windows), not(target_os = "macos"))]
164-
fn os_precise_time_ns() -> u64 {
165-
let mut ts = libc::timespec { tv_sec: 0, tv_nsec: 0 };
166-
unsafe {
167-
imp::clock_gettime(libc::CLOCK_MONOTONIC, &mut ts);
168-
}
169-
return (ts.tv_sec as u64) * 1000000000 + (ts.tv_nsec as u64)
80+
unsafe {
81+
let mut ns = 0u64;
82+
rustrt::rust_precise_time_ns(&mut ns);
83+
ns
17084
}
17185
}
17286

branches/try2/src/libgreen/lib.rs

Lines changed: 15 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,18 @@
2525
// NB this does *not* include globs, please keep it that way.
2626
#[feature(macro_rules)];
2727

28-
// Allow check-stage0-green for now
29-
#[cfg(test, stage0)] extern mod green;
30-
3128
use std::os;
3229
use std::rt::crate_map;
30+
use std::rt::local::Local;
3331
use std::rt::rtio;
32+
use std::rt::task::Task;
3433
use std::rt::thread::Thread;
3534
use std::rt;
3635
use std::sync::atomics::{SeqCst, AtomicUint, INIT_ATOMIC_UINT};
3736
use std::sync::deque;
3837
use std::task::TaskOpts;
3938
use std::util;
4039
use std::vec;
41-
use std::sync::arc::UnsafeArc;
4240

4341
use sched::{Shutdown, Scheduler, SchedHandle, TaskFromFriend, NewNeighbor};
4442
use sleeper_list::SleeperList;
@@ -120,6 +118,14 @@ pub fn run(main: proc()) -> int {
120118
os::set_exit_status(rt::DEFAULT_ERROR_CODE);
121119
}
122120

121+
// Once the main task has exited and we've set our exit code, wait for all
122+
// spawned sub-tasks to finish running. This is done to allow all schedulers
123+
// to remain active while there are still tasks possibly running.
124+
unsafe {
125+
let mut task = Local::borrow(None::<Task>);
126+
task.get().wait_for_other_tasks();
127+
}
128+
123129
// Now that we're sure all tasks are dead, shut down the pool of schedulers,
124130
// waiting for them all to return.
125131
pool.shutdown();
@@ -158,17 +164,6 @@ pub struct SchedPool {
158164
priv deque_pool: deque::BufferPool<~task::GreenTask>,
159165
priv sleepers: SleeperList,
160166
priv factory: fn() -> ~rtio::EventLoop,
161-
priv task_state: TaskState,
162-
priv tasks_done: Port<()>,
163-
}
164-
165-
/// This is an internal state shared among a pool of schedulers. This is used to
166-
/// keep track of how many tasks are currently running in the pool and then
167-
/// sending on a channel once the entire pool has been drained of all tasks.
168-
#[deriving(Clone)]
169-
struct TaskState {
170-
cnt: UnsafeArc<AtomicUint>,
171-
done: SharedChan<()>,
172167
}
173168

174169
impl SchedPool {
@@ -187,7 +182,6 @@ impl SchedPool {
187182
assert!(nscheds > 0);
188183

189184
// The pool of schedulers that will be returned from this function
190-
let (p, state) = TaskState::new();
191185
let mut pool = SchedPool {
192186
threads: ~[],
193187
handles: ~[],
@@ -198,8 +192,6 @@ impl SchedPool {
198192
deque_pool: deque::BufferPool::new(),
199193
next_friend: 0,
200194
factory: factory,
201-
task_state: state,
202-
tasks_done: p,
203195
};
204196

205197
// Create a work queue for each scheduler, ntimes. Create an extra
@@ -218,30 +210,21 @@ impl SchedPool {
218210
(pool.factory)(),
219211
worker,
220212
pool.stealers.clone(),
221-
pool.sleepers.clone(),
222-
pool.task_state.clone());
213+
pool.sleepers.clone());
223214
pool.handles.push(sched.make_handle());
224215
let sched = sched;
225-
pool.threads.push(do Thread::start { sched.bootstrap(); });
216+
pool.threads.push(do Thread::start {
217+
sched.bootstrap();
218+
});
226219
}
227220

228221
return pool;
229222
}
230223

231-
/// Creates a new task configured to run inside of this pool of schedulers.
232-
/// This is useful to create a task which can then be sent to a specific
233-
/// scheduler created by `spawn_sched` (and possibly pin it to that
234-
/// scheduler).
235224
pub fn task(&mut self, opts: TaskOpts, f: proc()) -> ~GreenTask {
236225
GreenTask::configure(&mut self.stack_pool, opts, f)
237226
}
238227

239-
/// Spawns a new task into this pool of schedulers, using the specified
240-
/// options to configure the new task which is spawned.
241-
///
242-
/// New tasks are spawned in a round-robin fashion to the schedulers in this
243-
/// pool, but tasks can certainly migrate among schedulers once they're in
244-
/// the pool.
245228
pub fn spawn(&mut self, opts: TaskOpts, f: proc()) {
246229
let task = self.task(opts, f);
247230

@@ -279,8 +262,7 @@ impl SchedPool {
279262
(self.factory)(),
280263
worker,
281264
self.stealers.clone(),
282-
self.sleepers.clone(),
283-
self.task_state.clone());
265+
self.sleepers.clone());
284266
let ret = sched.make_handle();
285267
self.handles.push(sched.make_handle());
286268
let sched = sched;
@@ -289,28 +271,9 @@ impl SchedPool {
289271
return ret;
290272
}
291273

292-
/// Consumes the pool of schedulers, waiting for all tasks to exit and all
293-
/// schedulers to shut down.
294-
///
295-
/// This function is required to be called in order to drop a pool of
296-
/// schedulers, it is considered an error to drop a pool without calling
297-
/// this method.
298-
///
299-
/// This only waits for all tasks in *this pool* of schedulers to exit, any
300-
/// native tasks or extern pools will not be waited on
301274
pub fn shutdown(mut self) {
302275
self.stealers = ~[];
303276

304-
// Wait for everyone to exit. We may have reached a 0-task count
305-
// multiple times in the past, meaning there could be several buffered
306-
// messages on the `tasks_done` port. We're guaranteed that after *some*
307-
// message the current task count will be 0, so we just receive in a
308-
// loop until everything is totally dead.
309-
while self.task_state.active() {
310-
self.tasks_done.recv();
311-
}
312-
313-
// Now that everyone's gone, tell everything to shut down.
314277
for mut handle in util::replace(&mut self.handles, ~[]).move_iter() {
315278
handle.send(Shutdown);
316279
}
@@ -320,31 +283,6 @@ impl SchedPool {
320283
}
321284
}
322285

323-
impl TaskState {
324-
fn new() -> (Port<()>, TaskState) {
325-
let (p, c) = SharedChan::new();
326-
(p, TaskState {
327-
cnt: UnsafeArc::new(AtomicUint::new(0)),
328-
done: c,
329-
})
330-
}
331-
332-
fn increment(&mut self) {
333-
unsafe { (*self.cnt.get()).fetch_add(1, SeqCst); }
334-
}
335-
336-
fn active(&self) -> bool {
337-
unsafe { (*self.cnt.get()).load(SeqCst) != 0 }
338-
}
339-
340-
fn decrement(&mut self) {
341-
let prev = unsafe { (*self.cnt.get()).fetch_sub(1, SeqCst) };
342-
if prev == 1 {
343-
self.done.send(());
344-
}
345-
}
346-
}
347-
348286
impl Drop for SchedPool {
349287
fn drop(&mut self) {
350288
if self.threads.len() > 0 {

0 commit comments

Comments
 (0)