Fixed a problem where spawn arguments were getting lost again. Also, fixed up stack alignment, which closes #496

This commit is contained in:
Eric Holk 2011-06-15 18:16:17 -07:00
parent c4f9bd9470
commit 67360ae618
10 changed files with 55 additions and 39 deletions

View File

@ -36,10 +36,14 @@ void context::swap(context &out)
void context::call(void *f, void *arg, void *stack) {
// set up the trampoline frame
uint32_t *sp = (uint32_t *)stack;
// Shift the stack pointer so the alignment works out right.
sp = align_down(sp) - 2;
*--sp = (uint32_t)this;
*--sp = (uint32_t)arg;
*--sp = 0xdeadbeef; //(uint32_t)ctx_trampoline1;
*--sp = 0xdeadbeef;
*--sp = 0xca11ab1e;
regs.esp = (uint32_t)sp;
regs.eip = (uint32_t)f;

View File

@ -32,4 +32,12 @@ public:
void call(void *f, void *arg, void *sp);
};
template<typename T>
T align_down(T sp)
{
// There is no platform we care about that needs more than a
// 16-byte alignment.
return (T)((int)sp & ~(16 - 1));
}
#endif

View File

@ -93,8 +93,7 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
DLOG(dom, dom, "startup: arg[%d] = '%s'", i, args->argv[i]);
}
dom->root_task->start(main_fn,
(uintptr_t)args->args, sizeof(args->args));
dom->root_task->start(main_fn, (uintptr_t)args->args);
int ret = dom->start_main_loop();
delete args;

View File

@ -17,6 +17,7 @@
static size_t const min_stk_bytes = 0x300000;
// static size_t const min_stk_bytes = 0x10000;
// Task stack segments. Heap allocated and chained together.
static stk_seg*
@ -152,25 +153,24 @@ void task_start_wrapper(spawn_args *a)
void
rust_task::start(uintptr_t spawnee_fn,
uintptr_t args,
size_t callsz)
uintptr_t args)
{
LOGPTR(dom, "from spawnee", spawnee_fn);
I(dom, stk->data != NULL);
char *sp = (char *)stk->limit;
char *sp = (char *)rust_sp;
sp -= sizeof(spawn_args);
spawn_args *a = (spawn_args *)sp;
a->task = this;
a->a3 = 0xca11ab1e;
a->a3 = 0;
a->a4 = args;
void **f = (void **)&a->f;
*f = (void *)spawnee_fn;
ctx.call((void *)task_start_wrapper, a, sp);
yield_timer.reset(0);

View File

@ -60,8 +60,7 @@ rust_task : public maybe_proxy<rust_task>,
~rust_task();
void start(uintptr_t spawnee_fn,
uintptr_t args,
size_t callsz);
uintptr_t args);
void grow(size_t n_frame_bytes);
bool running();
bool blocked();

View File

@ -509,14 +509,6 @@ upcall_new_task(rust_task *spawner, rust_vec *name) {
return task;
}
static uintptr_t
align_down(uintptr_t sp)
{
// There is no platform we care about that needs more than a
// 16-byte alignment.
return sp & ~(16 - 1);
}
extern "C" CDECL rust_task *
upcall_start_task(rust_task *spawner,
rust_task *task,
@ -538,12 +530,11 @@ upcall_start_task(rust_task *spawner,
// The args tuple is stack-allocated. We need to move it over to the new
// stack.
task->rust_sp -= args_sz;
uintptr_t child_arg = (uintptr_t)task->rust_sp;
memcpy((void*)task->rust_sp, (void*)args, args_sz);
uintptr_t start_args[] = {0, 0, 0, task->rust_sp};
task->rust_sp = align_down(task->rust_sp);
task->start(spawnee_fn, (uintptr_t)start_args, sizeof(start_args));
task->start(spawnee_fn, child_arg);
return task;
}
@ -567,6 +558,8 @@ upcall_new_thread(rust_task *task, const char *name) {
return child_task_proxy;
}
#if 0 /* TODO: this code will be re-enabled once we have multithreading. */
#if defined(__WIN32__)
static DWORD WINAPI rust_thread_start(void *ptr)
#elif defined(__GNUC__)
@ -587,6 +580,8 @@ static void *rust_thread_start(void *ptr)
return 0;
}
#endif
/**
* Called after a new domain is created. Here we create a new thread and
* and start the domain main loop.
@ -597,6 +592,7 @@ upcall_start_thread(rust_task *task,
uintptr_t spawnee_fn,
size_t callsz) {
LOG_UPCALL_ENTRY(task);
#if 0
rust_dom *parenet_dom = task->dom;
rust_handle<rust_task> *child_task_handle = child_task_proxy->handle();
LOG(task, task,
@ -616,6 +612,7 @@ upcall_start_thread(rust_task *task,
pthread_create(&thread, &parenet_dom->attr, rust_thread_start,
(void *) child_task->dom);
#endif
#endif // 0
return child_task_proxy;
}

View File

@ -52,7 +52,7 @@ rust_task_test::worker::run() {
rust_handle<rust_dom> *handle =
kernel->create_domain("test");
rust_dom *domain = handle->referent();
domain->root_task->start((uintptr_t)&task_entry, (uintptr_t)NULL, 0);
domain->root_task->start((uintptr_t)&task_entry, (uintptr_t)NULL);
domain->start_main_loop();
kernel->destroy_domain(domain);
}

View File

@ -5,12 +5,12 @@
fn main() {
let port[int] p = port();
spawn child(chan(p));
let task t = spawn child(chan(p));
let int y;
p |> y;
log_err "received";
log_err y;
//assert (y == 10);
assert (y == 10);
}
fn child(chan[int] c) {
@ -18,4 +18,3 @@ fn child(chan[int] c) {
c <| 10;
log_err "value sent"
}

View File

@ -1,14 +1,18 @@
// xfail-stage0
// xfail-stage1
// xfail-stage2
// xfail-stage3
// -*- rust -*-
fn main() { auto t = spawn child(10); }
fn child(int i) { log_err i; }
use std;
fn main() {
auto t = spawn child(10);
std::task::join(t)
}
fn child(int i) {
log_err i;
assert(i == 10);
}
// Local Variables:
// mode: rust;
// fill-column: 78;

View File

@ -1,11 +1,8 @@
// xfail-stage0
// xfail-stage1
// xfail-stage2
// xfail-stage3
// -*- rust -*-
fn main() {
spawn child(10, 20, 30, 40, 50, 60, 70, 80, 90);
spawn child(10, 20, 30, 40, 50, 60, 70, 80, 90);
}
fn child(int i1,
@ -27,6 +24,15 @@ fn child(int i1,
log_err i7;
log_err i8;
log_err i9;
assert(i1 == 10);
assert(i2 == 20);
assert(i3 == 30);
assert(i4 == 40);
assert(i5 == 50);
assert(i6 == 60);
assert(i7 == 70);
assert(i8 == 80);
assert(i9 == 90);
}
// Local Variables: