Skip to content

Commit 67360ae

Browse files
author
Eric Holk
committed
Fixed a problem where spawn arguments were getting lost again. Also, fixed up stack alignment, which closes #496
1 parent c4f9bd9 commit 67360ae

File tree

10 files changed

+54
-38
lines changed

10 files changed

+54
-38
lines changed

src/rt/arch/i386/context.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,14 @@ void context::swap(context &out)
3636
void context::call(void *f, void *arg, void *stack) {
3737
// set up the trampoline frame
3838
uint32_t *sp = (uint32_t *)stack;
39+
40+
// Shift the stack pointer so the alignment works out right.
41+
sp = align_down(sp) - 2;
42+
3943
*--sp = (uint32_t)this;
4044
*--sp = (uint32_t)arg;
41-
*--sp = 0xdeadbeef; //(uint32_t)ctx_trampoline1;
4245
*--sp = 0xdeadbeef;
46+
*--sp = 0xca11ab1e;
4347

4448
regs.esp = (uint32_t)sp;
4549
regs.eip = (uint32_t)f;

src/rt/arch/i386/context.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,12 @@ class context {
3232
void call(void *f, void *arg, void *sp);
3333
};
3434

35+
template<typename T>
36+
T align_down(T sp)
37+
{
38+
// There is no platform we care about that needs more than a
39+
// 16-byte alignment.
40+
return (T)((int)sp & ~(16 - 1));
41+
}
42+
3543
#endif

src/rt/rust.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,7 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
9393
DLOG(dom, dom, "startup: arg[%d] = '%s'", i, args->argv[i]);
9494
}
9595

96-
dom->root_task->start(main_fn,
97-
(uintptr_t)args->args, sizeof(args->args));
96+
dom->root_task->start(main_fn, (uintptr_t)args->args);
9897

9998
int ret = dom->start_main_loop();
10099
delete args;

src/rt/rust_task.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
static size_t const min_stk_bytes = 0x300000;
1818
// static size_t const min_stk_bytes = 0x10000;
1919

20+
2021
// Task stack segments. Heap allocated and chained together.
2122

2223
static stk_seg*
@@ -152,25 +153,24 @@ void task_start_wrapper(spawn_args *a)
152153

153154
void
154155
rust_task::start(uintptr_t spawnee_fn,
155-
uintptr_t args,
156-
size_t callsz)
156+
uintptr_t args)
157157
{
158158
LOGPTR(dom, "from spawnee", spawnee_fn);
159159

160160
I(dom, stk->data != NULL);
161161

162-
char *sp = (char *)stk->limit;
162+
char *sp = (char *)rust_sp;
163163

164164
sp -= sizeof(spawn_args);
165165

166166
spawn_args *a = (spawn_args *)sp;
167167

168168
a->task = this;
169-
a->a3 = 0xca11ab1e;
169+
a->a3 = 0;
170170
a->a4 = args;
171171
void **f = (void **)&a->f;
172172
*f = (void *)spawnee_fn;
173-
173+
174174
ctx.call((void *)task_start_wrapper, a, sp);
175175

176176
yield_timer.reset(0);

src/rt/rust_task.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ rust_task : public maybe_proxy<rust_task>,
6060
~rust_task();
6161

6262
void start(uintptr_t spawnee_fn,
63-
uintptr_t args,
64-
size_t callsz);
63+
uintptr_t args);
6564
void grow(size_t n_frame_bytes);
6665
bool running();
6766
bool blocked();

src/rt/rust_upcall.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -509,14 +509,6 @@ upcall_new_task(rust_task *spawner, rust_vec *name) {
509509
return task;
510510
}
511511

512-
static uintptr_t
513-
align_down(uintptr_t sp)
514-
{
515-
// There is no platform we care about that needs more than a
516-
// 16-byte alignment.
517-
return sp & ~(16 - 1);
518-
}
519-
520512
extern "C" CDECL rust_task *
521513
upcall_start_task(rust_task *spawner,
522514
rust_task *task,
@@ -538,12 +530,11 @@ upcall_start_task(rust_task *spawner,
538530
// The args tuple is stack-allocated. We need to move it over to the new
539531
// stack.
540532
task->rust_sp -= args_sz;
533+
uintptr_t child_arg = (uintptr_t)task->rust_sp;
534+
541535
memcpy((void*)task->rust_sp, (void*)args, args_sz);
542-
uintptr_t start_args[] = {0, 0, 0, task->rust_sp};
543-
544-
task->rust_sp = align_down(task->rust_sp);
545-
546-
task->start(spawnee_fn, (uintptr_t)start_args, sizeof(start_args));
536+
537+
task->start(spawnee_fn, child_arg);
547538
return task;
548539
}
549540

@@ -567,6 +558,8 @@ upcall_new_thread(rust_task *task, const char *name) {
567558
return child_task_proxy;
568559
}
569560

561+
#if 0 /* TODO: this code will be re-enabled once we have multithreading. */
562+
570563
#if defined(__WIN32__)
571564
static DWORD WINAPI rust_thread_start(void *ptr)
572565
#elif defined(__GNUC__)
@@ -587,6 +580,8 @@ static void *rust_thread_start(void *ptr)
587580
return 0;
588581
}
589582

583+
#endif
584+
590585
/**
591586
* Called after a new domain is created. Here we create a new thread and
592587
* and start the domain main loop.
@@ -597,6 +592,7 @@ upcall_start_thread(rust_task *task,
597592
uintptr_t spawnee_fn,
598593
size_t callsz) {
599594
LOG_UPCALL_ENTRY(task);
595+
#if 0
600596
rust_dom *parenet_dom = task->dom;
601597
rust_handle<rust_task> *child_task_handle = child_task_proxy->handle();
602598
LOG(task, task,
@@ -616,6 +612,7 @@ upcall_start_thread(rust_task *task,
616612
pthread_create(&thread, &parenet_dom->attr, rust_thread_start,
617613
(void *) child_task->dom);
618614
#endif
615+
#endif // 0
619616
return child_task_proxy;
620617
}
621618

src/rt/test/rust_test_runtime.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ rust_task_test::worker::run() {
5252
rust_handle<rust_dom> *handle =
5353
kernel->create_domain("test");
5454
rust_dom *domain = handle->referent();
55-
domain->root_task->start((uintptr_t)&task_entry, (uintptr_t)NULL, 0);
55+
domain->root_task->start((uintptr_t)&task_entry, (uintptr_t)NULL);
5656
domain->start_main_loop();
5757
kernel->destroy_domain(domain);
5858
}

src/test/run-pass/comm.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,16 @@
55

66
fn main() {
77
let port[int] p = port();
8-
spawn child(chan(p));
8+
let task t = spawn child(chan(p));
99
let int y;
1010
p |> y;
1111
log_err "received";
1212
log_err y;
13-
//assert (y == 10);
13+
assert (y == 10);
1414
}
1515

1616
fn child(chan[int] c) {
1717
log_err "sending";
1818
c <| 10;
1919
log_err "value sent"
2020
}
21-

src/test/run-pass/spawn.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1+
// xfail-stage0
2+
// -*- rust -*-
13

4+
use std;
25

6+
fn main() {
7+
auto t = spawn child(10);
8+
std::task::join(t)
9+
}
310

4-
// xfail-stage0
5-
// xfail-stage1
6-
// xfail-stage2
7-
// xfail-stage3
8-
// -*- rust -*-
9-
fn main() { auto t = spawn child(10); }
11+
fn child(int i) {
12+
log_err i;
13+
assert(i == 10);
14+
}
1015

11-
fn child(int i) { log_err i; }
1216
// Local Variables:
1317
// mode: rust;
1418
// fill-column: 78;

src/test/run-pass/spawn2.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
// xfail-stage0
2-
// xfail-stage1
3-
// xfail-stage2
4-
// xfail-stage3
52
// -*- rust -*-
63

74
fn main() {
8-
spawn child(10, 20, 30, 40, 50, 60, 70, 80, 90);
5+
spawn child(10, 20, 30, 40, 50, 60, 70, 80, 90);
96
}
107

118
fn child(int i1,
@@ -27,6 +24,15 @@ fn child(int i1,
2724
log_err i7;
2825
log_err i8;
2926
log_err i9;
27+
assert(i1 == 10);
28+
assert(i2 == 20);
29+
assert(i3 == 30);
30+
assert(i4 == 40);
31+
assert(i5 == 50);
32+
assert(i6 == 60);
33+
assert(i7 == 70);
34+
assert(i8 == 80);
35+
assert(i9 == 90);
3036
}
3137

3238
// Local Variables:

0 commit comments

Comments
 (0)