mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Fixed a problem where spawn arguments were getting lost again. Also, fixed up stack alignment, which closes #496
This commit is contained in:
parent
c4f9bd9470
commit
67360ae618
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user