Skip to content

Commit e9e886e

Browse files
author
Eric Holk
committed
---
yaml --- r: 3479 b: refs/heads/master c: 63dcd32 h: refs/heads/master i: 3477: eca40e1 3475: b456ce0 3471: b2f052e v: v3
1 parent 2d13f41 commit e9e886e

File tree

9 files changed

+68
-18
lines changed

9 files changed

+68
-18
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: afabde19dcdae41fa60df37b4aa049f4dfe6ee5f
2+
refs/heads/master: 63dcd325b909051f53682dc6ddb2d6768ffbbba3

trunk/src/lib/task.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ native "rust" mod rustrt {
22
fn task_sleep(uint time_in_us);
33
fn task_yield();
44
fn task_join(task t);
5+
fn pin_task();
6+
fn unpin_task();
57
}
68

79
/**
@@ -21,6 +23,14 @@ fn join(task t) {
2123
ret rustrt::task_join(t);
2224
}
2325

26+
fn pin() {
27+
rustrt::pin_task();
28+
}
29+
30+
fn unpin() {
31+
rustrt::unpin_task();
32+
}
33+
2434
// Local Variables:
2535
// mode: rust;
2636
// fill-column: 78;

trunk/src/rt/rust_builtin.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,15 @@ ivec_copy_from_buf(rust_task *task, type_desc *ty, rust_ivec *v, void *ptr,
700700
v->payload.ptr->fill = new_size;
701701
}
702702

703+
extern "C" void
704+
pin_task(rust_task *task) {
705+
task->pin();
706+
}
707+
708+
extern "C" void
709+
unpin_task(rust_task *task) {
710+
task->unpin();
711+
}
703712

704713
//
705714
// Local Variables:

trunk/src/rt/rust_scheduler.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,12 @@ rust_scheduler::number_of_live_tasks() {
8383
* Delete any dead tasks.
8484
*/
8585
void
86-
rust_scheduler::reap_dead_tasks() {
86+
rust_scheduler::reap_dead_tasks(int id) {
8787
I(this, kernel->scheduler_lock.lock_held_by_current_thread());
8888
for (size_t i = 0; i < dead_tasks.length(); ) {
8989
rust_task *task = dead_tasks[i];
9090
// Make sure this task isn't still running somewhere else...
91-
if (task->ref_count == 0 && task->can_schedule()) {
91+
if (task->ref_count == 0 && task->can_schedule(id)) {
9292
I(this, task->tasks_waiting_to_join.is_empty());
9393
dead_tasks.remove(task);
9494
DLOG(this, task,
@@ -124,7 +124,7 @@ void rust_scheduler::drain_incoming_message_queue(bool process) {
124124
* Returns NULL if no tasks can be scheduled.
125125
*/
126126
rust_task *
127-
rust_scheduler::schedule_task() {
127+
rust_scheduler::schedule_task(int id) {
128128
I(this, this);
129129
// FIXME: in the face of failing tasks, this is not always right.
130130
// I(this, n_live_tasks() > 0);
@@ -133,7 +133,7 @@ rust_scheduler::schedule_task() {
133133
// Look around for a runnable task, starting at k.
134134
for(size_t j = 0; j < running_tasks.length(); ++j) {
135135
size_t i = (j + k) % running_tasks.length();
136-
if (running_tasks[i]->can_schedule()) {
136+
if (running_tasks[i]->can_schedule(id)) {
137137
return (rust_task *)running_tasks[i];
138138
}
139139
}
@@ -202,7 +202,7 @@ rust_scheduler::start_main_loop(int id) {
202202

203203
drain_incoming_message_queue(true);
204204

205-
rust_task *scheduled_task = schedule_task();
205+
rust_task *scheduled_task = schedule_task(id);
206206

207207
// The scheduler busy waits until a task is available for scheduling.
208208
// Eventually we'll want a smarter way to do this, perhaps sleep
@@ -239,10 +239,9 @@ rust_scheduler::start_main_loop(int id) {
239239
DLOG(this, task,
240240
"Running task %p on worker %d",
241241
scheduled_task, id);
242-
I(this, !scheduled_task->active);
243-
scheduled_task->active = true;
242+
scheduled_task->running_on = id;
244243
activate(scheduled_task);
245-
scheduled_task->active = false;
244+
scheduled_task->running_on = -1;
246245

247246
DLOG(this, task,
248247
"returned from task %s @0x%" PRIxPTR
@@ -253,7 +252,7 @@ rust_scheduler::start_main_loop(int id) {
253252
scheduled_task->rust_sp,
254253
id);
255254

256-
reap_dead_tasks();
255+
reap_dead_tasks(id);
257256
}
258257

259258
DLOG(this, dom,
@@ -272,7 +271,7 @@ rust_scheduler::start_main_loop(int id) {
272271
} else {
273272
drain_incoming_message_queue(true);
274273
}
275-
reap_dead_tasks();
274+
reap_dead_tasks(id);
276275
}
277276

278277
DLOG(this, dom, "finished main-loop %d (dom.rval = %d)", id, rval);

trunk/src/rt/rust_scheduler.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ struct rust_scheduler : public kernel_owned<rust_scheduler>,
7979
rust_crate_cache *get_cache();
8080
size_t number_of_live_tasks();
8181

82-
void reap_dead_tasks();
83-
rust_task *schedule_task();
82+
void reap_dead_tasks(int id);
83+
rust_task *schedule_task(int id);
8484

8585
int start_main_loop(int id);
8686

trunk/src/rt/rust_task.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ rust_task::rust_task(rust_scheduler *sched, rust_task_list *state,
7070
list_index(-1),
7171
rendezvous_ptr(0),
7272
handle(NULL),
73-
active(false),
73+
running_on(-1),
74+
pinned_on(-1),
7475
local_region(&sched->srv->local_region),
7576
synchronized_region(&sched->srv->synchronized_region)
7677
{
@@ -471,9 +472,11 @@ rust_task::get_handle() {
471472
return handle;
472473
}
473474

474-
bool rust_task::can_schedule()
475+
bool rust_task::can_schedule(int id)
475476
{
476-
return yield_timer.has_timed_out() && !active;
477+
return yield_timer.has_timed_out() &&
478+
running_on == -1 &&
479+
(pinned_on == -1 || pinned_on == id);
477480
}
478481

479482
void *
@@ -524,6 +527,14 @@ rust_task::free(void *mem, memory_region::memory_region_type type) {
524527
return;
525528
}
526529

530+
void rust_task::pin() {
531+
pinned_on = running_on;
532+
}
533+
534+
void rust_task::unpin() {
535+
pinned_on = -1;
536+
}
537+
527538
//
528539
// Local Variables:
529540
// mode: C++

trunk/src/rt/rust_task.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ rust_task : public maybe_proxy<rust_task>,
7777

7878
// This flag indicates that a worker is either currently running the task
7979
// or is about to run this task.
80-
volatile bool active;
80+
int running_on;
81+
int pinned_on;
8182

8283
memory_region local_region;
8384
memory_region synchronized_region;
@@ -143,14 +144,17 @@ rust_task : public maybe_proxy<rust_task>,
143144
frame_glue_fns *get_frame_glue_fns(uintptr_t fp);
144145
rust_crate_cache * get_crate_cache();
145146

146-
bool can_schedule();
147+
bool can_schedule(int worker);
147148

148149
void *malloc(size_t size, memory_region::memory_region_type type);
149150
void *calloc(size_t size);
150151
void *calloc(size_t size, memory_region::memory_region_type type);
151152
void *realloc(void *mem, size_t size,
152153
memory_region::memory_region_type type);
153154
void free(void *mem, memory_region::memory_region_type type);
155+
156+
void pin();
157+
void unpin();
154158
};
155159

156160
//

trunk/src/rt/rustrt.def.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ ivec_on_heap
1515
ivec_reserve
1616
ivec_to_ptr
1717
last_os_error
18+
pin_task
19+
unpin_task
1820
rand_free
1921
rand_new
2022
rand_next

trunk/src/test/run-pass/task-pin.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// xfail-stage0
2+
3+
/**
4+
Exercises task pinning and unpinning. Doesn't really ensure it
5+
works, just makes sure it runs.
6+
*/
7+
8+
use std;
9+
10+
import std::task;
11+
12+
fn main() {
13+
task::pin();
14+
task::unpin();
15+
}

0 commit comments

Comments
 (0)