Skip to content

Commit fbdfa4a

Browse files
committed
---
yaml --- r: 142589 b: refs/heads/try2 c: 8eb358b h: refs/heads/master i: 142587: 83f8cc1 v: v3
1 parent 31b736b commit fbdfa4a

File tree

5 files changed

+124
-9
lines changed

5 files changed

+124
-9
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: ca2eebd5dd8ceea1da77b6a6f4fb8c68462a400b
8+
refs/heads/try2: 8eb358bb00f161f9e289de6cad8cfecc4c6eb681
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libstd/rt/comm.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,26 @@ impl<T> ChanOne<T> {
119119
match oldstate {
120120
STATE_BOTH => {
121121
// Port is not waiting yet. Nothing to do
122+
do Local::borrow::<Scheduler> |sched| {
123+
rtdebug!("non-rendezvous send");
124+
sched.metrics.non_rendezvous_sends += 1;
125+
}
122126
}
123127
STATE_ONE => {
128+
do Local::borrow::<Scheduler> |sched| {
129+
rtdebug!("rendezvous send");
130+
sched.metrics.rendezvous_sends += 1;
131+
}
124132
// Port has closed. Need to clean up.
125133
let _packet: ~Packet<T> = cast::transmute(this.inner.void_packet);
126134
recvr_active = false;
127135
}
128136
task_as_state => {
129137
// Port is blocked. Wake it up.
130138
let recvr: ~Coroutine = cast::transmute(task_as_state);
131-
let sched = Local::take::<Scheduler>();
139+
let mut sched = Local::take::<Scheduler>();
140+
rtdebug!("rendezvous send");
141+
sched.metrics.rendezvous_sends += 1;
132142
sched.schedule_task(recvr);
133143
}
134144
}
@@ -170,18 +180,19 @@ impl<T> PortOne<T> {
170180
match oldstate {
171181
STATE_BOTH => {
172182
// Data has not been sent. Now we're blocked.
183+
rtdebug!("non-rendezvous recv");
184+
sched.metrics.non_rendezvous_recvs += 1;
173185
}
174186
STATE_ONE => {
187+
rtdebug!("rendezvous recv");
188+
sched.metrics.rendezvous_recvs += 1;
189+
175190
// Channel is closed. Switch back and check the data.
176191
// NB: We have to drop back into the scheduler event loop here
177192
// instead of switching immediately back or we could end up
178193
// triggering infinite recursion on the scheduler's stack.
179194
let task: ~Coroutine = cast::transmute(task_as_state);
180-
let task = Cell(task);
181-
do sched.event_loop.callback {
182-
let sched = Local::take::<Scheduler>();
183-
sched.resume_task_immediately(task.take());
184-
}
195+
sched.enqueue_task(task);
185196
}
186197
_ => util::unreachable()
187198
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use to_str::ToStr;
12+
13+
pub struct SchedMetrics {
14+
// The number of times executing `run_sched_once`.
15+
turns: uint,
16+
// The number of turns that received a message.
17+
messages_received: uint,
18+
// The number of turns that ran a task from the queue.
19+
tasks_resumed_from_queue: uint,
20+
// The number of turns that found no work to perform.
21+
wasted_turns: uint,
22+
// The number of times the scheduler went to sleep.
23+
sleepy_times: uint,
24+
// Context switches from the scheduler into a task.
25+
context_switches_sched_to_task: uint,
26+
// Context switches from a task into the scheduler.
27+
context_switches_task_to_sched: uint,
28+
// Context switches from a task to a task.
29+
context_switches_task_to_task: uint,
30+
// Message sends that unblock the receiver
31+
rendezvous_sends: uint,
32+
// Message sends that do not unblock the receiver
33+
non_rendezvous_sends: uint,
34+
// Message receives that do not block the receiver
35+
rendezvous_recvs: uint,
36+
// Message receives that block the receiver
37+
non_rendezvous_recvs: uint
38+
}
39+
40+
impl SchedMetrics {
41+
pub fn new() -> SchedMetrics {
42+
SchedMetrics {
43+
turns: 0,
44+
messages_received: 0,
45+
tasks_resumed_from_queue: 0,
46+
wasted_turns: 0,
47+
sleepy_times: 0,
48+
context_switches_sched_to_task: 0,
49+
context_switches_task_to_sched: 0,
50+
context_switches_task_to_task: 0,
51+
rendezvous_sends: 0,
52+
non_rendezvous_sends: 0,
53+
rendezvous_recvs: 0,
54+
non_rendezvous_recvs: 0
55+
}
56+
}
57+
}
58+
59+
impl ToStr for SchedMetrics {
60+
fn to_str(&self) -> ~str {
61+
fmt!("turns: %u\n\
62+
messages_received: %u\n\
63+
tasks_resumed_from_queue: %u\n\
64+
wasted_turns: %u\n\
65+
sleepy_times: %u\n\
66+
context_switches_sched_to_task: %u\n\
67+
context_switches_task_to_sched: %u\n\
68+
context_switches_task_to_task: %u\n\
69+
rendezvous_sends: %u\n\
70+
non_rendezvous_sends: %u\n\
71+
rendezvous_recvs: %u\n\
72+
non_rendezvous_recvs: %u\n\
73+
",
74+
self.turns,
75+
self.messages_received,
76+
self.tasks_resumed_from_queue,
77+
self.wasted_turns,
78+
self.sleepy_times,
79+
self.context_switches_sched_to_task,
80+
self.context_switches_task_to_sched,
81+
self.context_switches_task_to_task,
82+
self.rendezvous_sends,
83+
self.non_rendezvous_sends,
84+
self.rendezvous_recvs,
85+
self.non_rendezvous_recvs
86+
)
87+
}
88+
}

branches/try2/src/libstd/rt/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ pub mod local_ptr;
130130
/// Bindings to pthread/windows thread-local storage.
131131
pub mod thread_local_storage;
132132

133+
pub mod metrics;
134+
133135

134136
/// Set up a default runtime configuration, given compiler-supplied arguments.
135137
///

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use sys;
1313
use cast::transmute;
1414
use cell::Cell;
1515
use clone::Clone;
16+
use to_str::ToStr;
1617

1718
use super::sleeper_list::SleeperList;
1819
use super::work_queue::WorkQueue;
@@ -24,6 +25,7 @@ use super::message_queue::MessageQueue;
2425
use rt::local_ptr;
2526
use rt::local::Local;
2627
use rt::rtio::{IoFactoryObject, RemoteCallback};
28+
use rt::metrics::SchedMetrics;
2729

2830
/// The Scheduler is responsible for coordinating execution of Coroutines
2931
/// on a single thread. When the scheduler is running it is owned by
@@ -63,7 +65,8 @@ pub struct Scheduler {
6365
current_task: Option<~Coroutine>,
6466
/// An action performed after a context switch on behalf of the
6567
/// code running before the context switch
66-
priv cleanup_job: Option<CleanupJob>
68+
priv cleanup_job: Option<CleanupJob>,
69+
metrics: SchedMetrics
6770
}
6871

6972
pub struct SchedHandle {
@@ -115,6 +118,7 @@ pub impl Scheduler {
115118
saved_context: Context::empty(),
116119
current_task: None,
117120
cleanup_job: None,
121+
metrics: SchedMetrics::new()
118122
}
119123
}
120124

@@ -141,20 +145,24 @@ pub impl Scheduler {
141145

142146
let sched = Local::take::<Scheduler>();
143147
assert!(sched.work_queue.is_empty());
148+
rtdebug!("scheduler metrics: %s\n", sched.metrics.to_str());
144149
return sched;
145150
}
146151

147152
fn run_sched_once() {
148153

154+
let mut sched = Local::take::<Scheduler>();
155+
sched.metrics.turns += 1;
156+
149157
// First, check the message queue for instructions.
150158
// XXX: perf. Check for messages without atomics.
151159
// It's ok if we miss messages occasionally, as long as
152160
// we sync and check again before sleeping.
153-
let sched = Local::take::<Scheduler>();
154161
if sched.interpret_message_queue() {
155162
// We performed a scheduling action. There may be other work
156163
// to do yet, so let's try again later.
157164
let mut sched = Local::take::<Scheduler>();
165+
sched.metrics.messages_received += 1;
158166
sched.event_loop.callback(Scheduler::run_sched_once);
159167
Local::put(sched);
160168
return;
@@ -166,6 +174,7 @@ pub impl Scheduler {
166174
// We performed a scheduling action. There may be other work
167175
// to do yet, so let's try again later.
168176
let mut sched = Local::take::<Scheduler>();
177+
sched.metrics.tasks_resumed_from_queue += 1;
169178
sched.event_loop.callback(Scheduler::run_sched_once);
170179
Local::put(sched);
171180
return;
@@ -176,8 +185,10 @@ pub impl Scheduler {
176185
// somebody can wake us up later.
177186
rtdebug!("no work to do");
178187
let mut sched = Local::take::<Scheduler>();
188+
sched.metrics.wasted_turns += 1;
179189
if !sched.sleepy && !sched.no_sleep {
180190
rtdebug!("sleeping");
191+
sched.metrics.sleepy_times += 1;
181192
sched.sleepy = true;
182193
let handle = sched.make_handle();
183194
sched.sleeper_list.push(handle);
@@ -327,6 +338,7 @@ pub impl Scheduler {
327338
assert!(!this.in_task_context());
328339

329340
rtdebug!("scheduling a task");
341+
this.metrics.context_switches_sched_to_task += 1;
330342

331343
// Store the task in the scheduler so it can be grabbed later
332344
this.current_task = Some(task);
@@ -369,6 +381,7 @@ pub impl Scheduler {
369381
assert!(this.in_task_context());
370382

371383
rtdebug!("blocking task");
384+
this.metrics.context_switches_task_to_sched += 1;
372385

373386
unsafe {
374387
let blocked_task = this.current_task.swap_unwrap();
@@ -401,6 +414,7 @@ pub impl Scheduler {
401414
assert!(this.in_task_context());
402415

403416
rtdebug!("switching tasks");
417+
this.metrics.context_switches_task_to_task += 1;
404418

405419
let old_running_task = this.current_task.swap_unwrap();
406420
let f_fake_region = unsafe {

0 commit comments

Comments
 (0)