Skip to content

Commit 0f9e6d9

Browse files
author
Eric Holk
committed
---
yaml --- r: 4774 b: refs/heads/master c: ae89ea2 h: refs/heads/master v: v3
1 parent 62d2519 commit 0f9e6d9

File tree

11 files changed

+52
-55
lines changed

11 files changed

+52
-55
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: efac7c9a197fa3ff3497ce99a2dda8693b3ef683
2+
refs/heads/master: ae89ea223de2fe5e9c9a5cdd2fa85a93828a7daa

trunk/src/lib/comm.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ export _chan;
88
export _port;
99

1010
export mk_port;
11-
export chan_from_unsafe_ptr;
1211
export send;
1312
export recv;
1413
export chan;
@@ -47,7 +46,6 @@ resource port_ptr(po: *rustrt::rust_port) {
4746
type port<~T> = @port_ptr;
4847

4948
obj port_obj<~T>(raw_port : port<T>) {
50-
// FIXME: rename this to chan once chan is not a keyword.
5149
fn mk_chan() -> _chan<T> {
5250
chan::<T>(raw_port)
5351
}

trunk/src/lib/ptr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ fn offset<T>(ptr: *T, count: uint) -> *T {
1010
ret rusti::ptr_offset(ptr, count);
1111
}
1212

13+
fn null<T>() -> *T { ret unsafe::reinterpret_cast(0u); }

trunk/src/lib/task.rs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import comm::_chan;
44
import option::some;
55
import option::none;
66
import option = option::t;
7+
import ptr;
78

89
native "rust" mod rustrt {
910
fn task_sleep(time_in_us: uint);
@@ -19,9 +20,8 @@ native "rust" mod rustrt {
1920
fn set_min_stack(stack_size: uint);
2021

2122
fn new_task() -> task_id;
22-
fn drop_task(id : task_id);
23+
fn drop_task(task : *rust_task);
2324
fn get_task_pointer(id : task_id) -> *rust_task;
24-
fn get_task_context(id : task_id) -> *x86_registers;
2525
fn start_task(id : task_id);
2626
fn get_task_trampoline() -> u32;
2727

@@ -31,10 +31,26 @@ native "rust" mod rustrt {
3131
}
3232

3333
type rust_task = {
34+
id : task,
3435
mutable notify_enabled : u8,
35-
mutable notify_chan : _chan<task_notification>
36+
mutable notify_chan : _chan<task_notification>,
37+
ctx : task_context,
38+
stack_ptr : *u8
3639
};
3740

41+
type task_context = {
42+
regs : x86_registers,
43+
next : *u8
44+
};
45+
46+
resource rust_task_ptr(task : *rust_task) {
47+
rustrt::drop_task(task);
48+
}
49+
50+
fn get_task_ptr(id : task) -> rust_task_ptr {
51+
ret rust_task_ptr(rustrt::get_task_pointer(id));
52+
}
53+
3854
type task = int;
3955
type task_id = task;
4056

@@ -95,23 +111,25 @@ fn spawn_inner(thunk : -fn() -> (),
95111
let id = rustrt::new_task();
96112

97113
// the order of arguments are outptr, taskptr, envptr.
98-
99-
// In LLVM fastcall puts the first two in ecx, edx, and the rest on the
114+
// LLVM fastcall puts the first two in ecx, edx, and the rest on the
100115
// stack.
101-
let regs = rustrt::get_task_context(id);
102116

103117
// set up the task pointer
104-
let task_ptr = rustrt::get_task_pointer(id);
105-
(*regs).edx = cast(task_ptr);
118+
let task_ptr = get_task_ptr(id);
119+
let regs = ptr::addr_of((**task_ptr).ctx.regs);
120+
(*regs).edx = cast(*task_ptr);
121+
(*regs).esp = cast((**task_ptr).stack_ptr);
122+
123+
assert ptr::null() != (**task_ptr).stack_ptr;
106124

107125
let raw_thunk : { code: u32, env: u32 } = cast(thunk);
108126
(*regs).eip = raw_thunk.code;
109127

110128
// set up notifications if they are enabled.
111129
alt notify {
112130
some(c) {
113-
(*task_ptr).notify_enabled = 1u8;
114-
(*task_ptr).notify_chan = c;
131+
(**task_ptr).notify_enabled = 1u8;
132+
(**task_ptr).notify_chan = c;
115133
}
116134
none {}
117135
};
@@ -130,7 +148,7 @@ fn spawn_inner(thunk : -fn() -> (),
130148
// put the return pointer in ecx.
131149
(*regs).ecx = (*regs).esp + 8u32;
132150

133-
*tptr = cast(task_ptr);
151+
*tptr = cast(*task_ptr);
134152
*env = raw_thunk.env;
135153
*ra = rustrt::get_task_trampoline();
136154

@@ -139,11 +157,6 @@ fn spawn_inner(thunk : -fn() -> (),
139157

140158
rustrt::leak(thunk);
141159

142-
// Drop twice because get_task_context and get_task_pounter both bump the
143-
// ref count and expect us to free it.
144-
rustrt::drop_task(id);
145-
rustrt::drop_task(id);
146-
147160
ret id;
148161
}
149162

trunk/src/rt/arch/i386/context.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44

55
#include <stdio.h>
66
#include <stdlib.h>
7+
#include <assert.h>
78

89
extern "C" uint32_t CDECL swap_registers(registers_t *oregs,
910
registers_t *regs)
1011
asm ("swap_registers");
1112

1213
context::context()
1314
{
15+
assert((void*)&regs == (void*)this);
1416
}
1517

1618
void context::swap(context &out)

trunk/src/rt/rust_builtin.cpp

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -712,38 +712,24 @@ unpin_task(rust_task *task) {
712712

713713
extern "C" CDECL rust_task_id
714714
get_task_id(rust_task *task) {
715-
return task->id;
715+
return task->user.id;
716716
}
717717

718718
extern "C" CDECL rust_task_id
719719
new_task(rust_task *task) {
720720
return task->kernel->create_task(task, NULL);
721721
}
722722

723-
extern "C" CDECL registers_t *
724-
get_task_context(rust_task *task, rust_task_id id) {
725-
rust_task *target = task->kernel->get_task_by_id(id);
726-
registers_t *regs = &target->ctx.regs;
727-
// This next line is a little dangerous.. It means we can only safely call
728-
// this when starting a task.
729-
regs->esp = target->rust_sp;
730-
return regs;
731-
}
732-
733723
extern "C" CDECL void
734-
drop_task(rust_task *task, rust_task_id tid) {
735-
rust_task *target = task->kernel->get_task_by_id(tid);
724+
drop_task(rust_task *task, rust_task *target) {
736725
if(target) {
737726
target->deref();
738-
// Deref twice because get_task_by_id does once.
739-
target->deref();
740727
}
741728
}
742729

743730
extern "C" CDECL rust_task *
744731
get_task_pointer(rust_task *task, rust_task_id id) {
745-
rust_task *t = task->kernel->get_task_by_id(id);
746-
return t;
732+
return task->kernel->get_task_by_id(id);
747733
}
748734

749735
extern "C" CDECL void

trunk/src/rt/rust_kernel.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,10 @@ rust_kernel::create_task(rust_task *spawner, const char *name) {
154154
rust_task *t = thread->create_task(spawner, name);
155155
{
156156
scoped_lock with(_kernel_lock);
157-
t->id = max_id++;
158-
task_table.put(t->id, t);
157+
t->user.id = max_id++;
158+
task_table.put(t->user.id, t);
159159
}
160-
return t->id;
160+
return t->user.id;
161161
}
162162

163163
rust_task *

trunk/src/rt/rust_scheduler.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ void
4747
rust_scheduler::activate(rust_task *task) {
4848
context ctx;
4949

50-
task->ctx.next = &ctx;
50+
task->user.ctx.next = &ctx;
5151
DLOG(this, task, "descheduling...");
5252
lock.unlock();
53-
task->ctx.swap(ctx);
53+
task->user.ctx.swap(ctx);
5454
lock.lock();
5555
DLOG(this, task, "task has returned");
5656
}
@@ -226,7 +226,7 @@ rust_scheduler::start_main_loop() {
226226
", state: %s",
227227
scheduled_task->name,
228228
(uintptr_t)scheduled_task,
229-
scheduled_task->rust_sp,
229+
scheduled_task->user.rust_sp,
230230
scheduled_task->state->name);
231231

232232
interrupt_flag = 0;
@@ -244,7 +244,7 @@ rust_scheduler::start_main_loop() {
244244
scheduled_task->name,
245245
(uintptr_t)scheduled_task,
246246
scheduled_task->state->name,
247-
scheduled_task->rust_sp,
247+
scheduled_task->user.rust_sp,
248248
id);
249249

250250
reap_dead_tasks(id);

trunk/src/rt/rust_task.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ rust_task::rust_task(rust_scheduler *sched, rust_task_list *state,
5757
ref_count(1),
5858
stk(NULL),
5959
runtime_sp(0),
60-
rust_sp(0),
6160
gc_alloc_chain(0),
6261
sched(sched),
6362
cache(NULL),
@@ -86,7 +85,7 @@ rust_task::rust_task(rust_scheduler *sched, rust_task_list *state,
8685
user.notify_enabled = 0;
8786

8887
stk = new_stk(sched, this, 0);
89-
rust_sp = stk->limit;
88+
user.rust_sp = stk->limit;
9089
}
9190

9291
rust_task::~rust_task()
@@ -99,15 +98,15 @@ rust_task::~rust_task()
9998
get_chan_by_handle(&user.notify_chan);
10099
if(target) {
101100
task_notification msg;
102-
msg.id = id;
101+
msg.id = user.id;
103102
msg.result = failed ? tr_failure : tr_success;
104103

105104
target->send(&msg);
106105
target->deref();
107106
}
108107
}
109108

110-
kernel->release_task_id(id);
109+
kernel->release_task_id(user.id);
111110

112111
/* FIXME: tighten this up, there are some more
113112
assertions that hold at task-lifecycle events. */
@@ -166,7 +165,7 @@ rust_task::start(uintptr_t spawnee_fn,
166165

167166
I(sched, stk->data != NULL);
168167

169-
char *sp = (char *)rust_sp;
168+
char *sp = (char *)user.rust_sp;
170169

171170
sp -= sizeof(spawn_args);
172171

@@ -178,7 +177,7 @@ rust_task::start(uintptr_t spawnee_fn,
178177
void **f = (void **)&a->f;
179178
*f = (void *)spawnee_fn;
180179

181-
ctx.call((void *)task_start_wrapper, a, sp);
180+
user.ctx.call((void *)task_start_wrapper, a, sp);
182181

183182
this->start();
184183
}
@@ -213,7 +212,7 @@ rust_task::yield(size_t time_in_us) {
213212
yield_timer.reset_us(time_in_us);
214213

215214
// Return to the scheduler.
216-
ctx.next->swap(ctx);
215+
user.ctx.next->swap(user.ctx);
217216
}
218217

219218
void

trunk/src/rt/rust_task.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,11 @@ struct gc_alloc {
3838
// portions of the task structure that are accessible from the standard
3939
// library. This struct must agree with the std::task::rust_task record.
4040
struct rust_task_user {
41+
rust_task_id id;
4142
uint8_t notify_enabled;
4243
chan_handle notify_chan;
44+
context ctx;
45+
uintptr_t rust_sp; // Saved sp when not running.
4346
};
4447

4548
// std::lib::task::task_result
@@ -66,7 +69,6 @@ rust_task : public kernel_owned<rust_task>, rust_cond
6669
// Fields known to the compiler.
6770
stk_seg *stk;
6871
uintptr_t runtime_sp; // Runtime sp while task running.
69-
uintptr_t rust_sp; // Saved sp when not running.
7072
gc_alloc *gc_alloc_chain; // Linked list of GC allocations.
7173
rust_scheduler *sched;
7274
rust_crate_cache *cache;
@@ -82,7 +84,6 @@ rust_task : public kernel_owned<rust_task>, rust_cond
8284
size_t gc_alloc_thresh;
8385
size_t gc_alloc_accum;
8486

85-
rust_task_id id;
8687
rust_port_id next_port_id;
8788

8889
// Keeps track of the last time this task yielded.
@@ -99,8 +100,6 @@ rust_task : public kernel_owned<rust_task>, rust_cond
99100
// List of tasks waiting for this task to finish.
100101
array_list<rust_task *> tasks_waiting_to_join;
101102

102-
context ctx;
103-
104103
// This flag indicates that a worker is either currently running the task
105104
// or is about to run this task.
106105
int running_on;

trunk/src/rt/rustrt.def.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ do_gc
2525
drop_port
2626
drop_task
2727
get_port_id
28-
get_task_context
2928
get_task_id
3029
get_task_pointer
3130
get_task_trampoline

0 commit comments

Comments
 (0)