Skip to content

Commit 44bef5f

Browse files
unknownEric Holk
authored andcommitted
Introduced task handles.
This is the new way to refer to tasks in rust-land. Currently all they do is serve as a key to look up the old rust_task structure. Ideally they won't be ref counted, but baby steps.
1 parent f4f057c commit 44bef5f

14 files changed

+75
-38
lines changed

src/rt/memory_region.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// NB: please do not commit code with this uncommented. It's
55
// hugely expensive and should only be used as a last resort.
66
//
7-
// #define TRACK_ALLOCATIONS
7+
#define TRACK_ALLOCATIONS
88

99
#define MAGIC 0xbadc0ffe
1010

src/rt/rust.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
9393

9494
rust_srv *srv = new rust_srv(env);
9595
rust_kernel *kernel = new rust_kernel(srv, env->num_sched_threads);
96-
rust_task *root_task = kernel->create_task(NULL, "main");
96+
rust_task_id root_id = kernel->create_task(NULL, "main");
97+
rust_task *root_task = kernel->get_task_by_id(root_id);
98+
I(kernel, root_task != NULL);
9799
rust_scheduler *sched = root_task->sched;
98100
command_line_args *args
99101
= new (kernel, "main command line args")

src/rt/rust_builtin.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,8 +408,11 @@ task_yield(rust_task *task) {
408408
}
409409

410410
extern "C" CDECL intptr_t
411-
task_join(rust_task *task, rust_task *join_task) {
411+
task_join(rust_task *task, rust_task_id tid) {
412412
// If the other task is already dying, we don't have to wait for it.
413+
rust_task *join_task = task->kernel->get_task_by_id(tid);
414+
// FIXME: find task exit status and return that.
415+
if(!join_task) return 0;
413416
join_task->lock.lock();
414417
if (join_task->dead() == false) {
415418
join_task->tasks_waiting_to_join.push(task);

src/rt/rust_chan.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,17 @@ void rust_chan::disassociate() {
7373
* Attempt to send data to the associated port.
7474
*/
7575
void rust_chan::send(void *sptr) {
76-
scoped_lock with(port->lock);
77-
78-
buffer.enqueue(sptr);
79-
8076
if (!is_associated()) {
8177
W(kernel, is_associated(),
8278
"rust_chan::transmit with no associated port.");
8379
return;
8480
}
8581

82+
I(kernel, port != NULL);
83+
scoped_lock with(port->lock);
84+
85+
buffer.enqueue(sptr);
86+
8687
A(kernel, !buffer.is_empty(),
8788
"rust_chan::transmit with nothing to send.");
8889

src/rt/rust_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ struct stk_seg;
6464
struct type_desc;
6565
struct frame_glue_fns;
6666

67+
typedef intptr_t rust_task_id;
68+
6769
#ifndef __i386__
6870
#error "Target CPU not supported."
6971
#endif

src/rt/rust_kernel.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ rust_kernel::rust_kernel(rust_srv *srv, size_t num_threads) :
99
_region(srv, true),
1010
_log(srv, NULL),
1111
srv(srv),
12+
max_id(0),
1213
num_threads(num_threads),
1314
rval(0),
1415
live_tasks(0),
@@ -133,10 +134,31 @@ int rust_kernel::start_task_threads()
133134
return rval;
134135
}
135136

136-
rust_task *
137+
rust_task_id
137138
rust_kernel::create_task(rust_task *spawner, const char *name) {
138139
rust_scheduler *thread = threads[rand(&rctx) % num_threads];
139-
return thread->create_task(spawner, name);
140+
rust_task *t = thread->create_task(spawner, name);
141+
{
142+
scoped_lock with(_kernel_lock);
143+
t->id = max_id++;
144+
task_table.put(t->id, t);
145+
}
146+
return t->id;
147+
}
148+
149+
rust_task *
150+
rust_kernel::get_task_by_id(rust_task_id id) {
151+
scoped_lock with(_kernel_lock);
152+
rust_task *task = NULL;
153+
// get leaves task unchanged if not found.
154+
task_table.get(id, &task);
155+
return task;
156+
}
157+
158+
void
159+
rust_kernel::release_task_id(rust_task_id id) {
160+
scoped_lock with(_kernel_lock);
161+
task_table.remove(id);
140162
}
141163

142164
void rust_kernel::wakeup_schedulers() {

src/rt/rust_kernel.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ class rust_kernel {
2626
void create_schedulers();
2727
void destroy_schedulers();
2828

29-
public:
29+
rust_task_id max_id;
30+
hash_map<rust_task_id, rust_task *> task_table;
3031

32+
public:
3133
const size_t num_threads;
3234
int rval;
3335

@@ -56,7 +58,9 @@ class rust_kernel {
5658
void win32_require(LPCTSTR fn, BOOL ok);
5759
#endif
5860

59-
rust_task *create_task(rust_task *spawner, const char *name);
61+
rust_task_id create_task(rust_task *spawner, const char *name);
62+
rust_task *get_task_by_id(rust_task_id id);
63+
void release_task_id(rust_task_id tid);
6064
};
6165

6266
#endif /* RUST_KERNEL_H */

src/rt/rust_scheduler.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ struct rust_scheduler : public kernel_owned<rust_scheduler>,
5151
rust_kernel *kernel;
5252
int32_t list_index;
5353

54-
hash_map<rust_task *, rust_task *> _task_proxies;
55-
hash_map<rust_port *, rust_port *> _port_proxies;
56-
5754
const int id;
5855

5956
lock_and_signal lock;

src/rt/rust_task.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ rust_task::~rust_task()
9595
DLOG(sched, task, "~rust_task %s @0x%" PRIxPTR ", refcnt=%d",
9696
name, (uintptr_t)this, ref_count);
9797

98+
kernel->release_task_id(id);
99+
98100
/* FIXME: tighten this up, there are some more
99101
assertions that hold at task-lifecycle events. */
100102
I(sched, ref_count == 0); // ||

src/rt/rust_task.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ struct gc_alloc {
3434
}
3535
};
3636

37-
3837
struct
3938
rust_task : public kernel_owned<rust_task>, rust_cond
4039
{
@@ -59,6 +58,8 @@ rust_task : public kernel_owned<rust_task>, rust_cond
5958
size_t gc_alloc_thresh;
6059
size_t gc_alloc_accum;
6160

61+
rust_task_id id;
62+
6263
// Keeps track of the last time this task yielded.
6364
timer yield_timer;
6465

src/rt/rust_upcall.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,11 @@ void upcall_del_chan(rust_task *task, rust_chan *chan) {
140140
* has its own copy of the channel.
141141
*/
142142
extern "C" CDECL rust_chan *
143-
upcall_clone_chan(rust_task *task, rust_task *target,
143+
upcall_clone_chan(rust_task *task, rust_task_id tid,
144144
rust_chan *chan) {
145+
// FIXME: This should be removed.
145146
LOG_UPCALL_ENTRY(task);
147+
rust_task *target = task->kernel->get_task_by_id(tid);
146148
return chan->clone(target);
147149
}
148150

@@ -203,9 +205,9 @@ upcall_fail(rust_task *task,
203205
* Called whenever a task's ref count drops to zero.
204206
*/
205207
extern "C" CDECL void
206-
upcall_kill(rust_task *task, rust_task *target) {
208+
upcall_kill(rust_task *task, rust_task_id tid) {
207209
LOG_UPCALL_ENTRY(task);
208-
210+
rust_task *target = task->kernel->get_task_by_id(tid);
209211
target->kill();
210212
}
211213

@@ -322,9 +324,9 @@ upcall_new_str(rust_task *task, char const *s, size_t fill) {
322324
}
323325

324326
extern "C" CDECL rust_str *
325-
upcall_dup_str(rust_task *task, rust_task *target, rust_str *str) {
327+
upcall_dup_str(rust_task *task, rust_task_id tid, rust_str *str) {
326328
LOG_UPCALL_ENTRY(task);
327-
329+
rust_task *target = task->kernel->get_task_by_id(tid);
328330
return make_str(target, (char const *)str->data, str->fill);
329331
}
330332

@@ -482,27 +484,30 @@ upcall_get_type_desc(rust_task *task,
482484
return td;
483485
}
484486

485-
extern "C" CDECL rust_task *
487+
extern "C" CDECL rust_task_id
486488
upcall_new_task(rust_task *spawner, rust_vec *name) {
487489
// name is a rust string structure.
488490
LOG_UPCALL_ENTRY(spawner);
489-
rust_task *task =
491+
rust_task_id tid =
490492
spawner->kernel->create_task(spawner, (const char *)name->data);
493+
rust_task *task = spawner->kernel->get_task_by_id(tid);
491494
task->ref();
492-
return task;
495+
return tid;
493496
}
494497

495498
extern "C" CDECL void
496-
upcall_take_task(rust_task *task, rust_task *target) {
499+
upcall_take_task(rust_task *task, rust_task_id tid) {
497500
LOG_UPCALL_ENTRY(task);
501+
rust_task *target = task->kernel->get_task_by_id(tid);
498502
if(target) {
499503
target->ref();
500504
}
501505
}
502506

503507
extern "C" CDECL void
504-
upcall_drop_task(rust_task *task, rust_task *target) {
508+
upcall_drop_task(rust_task *task, rust_task_id tid) {
505509
LOG_UPCALL_ENTRY(task);
510+
rust_task *target = task->kernel->get_task_by_id(tid);
506511
if(target) {
507512
target->deref();
508513
}
@@ -526,13 +531,14 @@ upcall_drop_chan(rust_task *task, rust_chan *target) {
526531

527532
extern "C" CDECL rust_task *
528533
upcall_start_task(rust_task *spawner,
529-
rust_task *task,
534+
rust_task_id tid,
530535
uintptr_t spawnee_fn,
531536
uintptr_t args,
532537
size_t args_sz) {
533538
LOG_UPCALL_ENTRY(spawner);
534539

535540
rust_scheduler *sched = spawner->sched;
541+
rust_task *task = spawner->kernel->get_task_by_id(tid);
536542
DLOG(sched, task,
537543
"upcall start_task(task %s @0x%" PRIxPTR
538544
", spawnee 0x%" PRIxPTR ")",

src/rt/test/rust_test_runtime.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ void task_entry() {
4545

4646
void
4747
rust_task_test::worker::run() {
48-
rust_task *root_task = kernel->create_task(NULL, "main");
48+
rust_task_id root_id = kernel->create_task(NULL, "main");
49+
rust_task *root_task = kernel->get_task_by_id(root_id);
4950
root_task->start((uintptr_t)&task_entry, (uintptr_t)NULL);
5051
root_task->sched->start_main_loop();
5152
}

src/rt/util/hash_map.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// -*- c++ -*-
12
/**
23
* A C++ wrapper around uthash.
34
*/

src/test/run-pass/task-comm-10.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,23 @@ import std::comm;
44

55
fn start(pcc: *u8) {
66
let c = comm::chan_from_unsafe_ptr(pcc);
7-
let p;
7+
let p = comm::mk_port[str]();
8+
c.send(p.mk_chan().unsafe_ptr());
89

910
let a;
1011
let b;
11-
p = comm::mk_port[str]();
12-
c.send(p.mk_chan().unsafe_ptr());
1312
a = p.recv();
1413
log_err a;
1514
b = p.recv();
1615
log_err b;
1716
}
1817

1918
fn main() {
20-
let p : comm::_port[*u8];
21-
let child;
22-
23-
p = comm::mk_port();
24-
child = spawn start(p.mk_chan().unsafe_ptr());
25-
let pc; let c;
19+
let p = comm::mk_port[*u8]();
20+
let child = spawn start(p.mk_chan().unsafe_ptr());
2621

27-
pc = p.recv();
28-
c = comm::chan_from_unsafe_ptr(pc);
22+
let pc = p.recv();
23+
let c = comm::chan_from_unsafe_ptr(pc);
2924
c.send("A");
3025
c.send("B");
3126
task::yield();

0 commit comments

Comments
 (0)