Skip to content

Commit d1857d3

Browse files
Eric Holkgraydon
Eric Holk
authored andcommitted
This is the mega-ucontext commit. It replaces the task switching mechanism with a new one inspired by ucontext. It works under Linux, OS X and Windows, and is Valgrind clean on Linux and OS X (provided the runtime is built with gcc).
This commit also moves yield and join to the standard library, as requested in #42. Join is currently a no-op though.
1 parent 1595c9d commit d1857d3

30 files changed

+418
-442
lines changed

configure

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,11 @@ fi
176176
step_msg "making directories"
177177
for i in \
178178
doc \
179-
rt rt/isaac rt/bigint rt/sync rt/test \
179+
rt rt/isaac rt/bigint rt/sync rt/test rt/arch/i386 \
180180
rustllvm \
181181
dl stage0 stage1 stage2 stage3 \
182182
test/run-pass test/run-fail test/compile-fail \
183-
test/bench/99-bottles test/bench/shootout
183+
test/bench/99-bottles test/bench/shootout
184184
do
185185
make_dir $i
186186
done

mk/rt.mk

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ RUNTIME_CS := rt/sync/timer.cpp \
2727
rt/memory_region.cpp \
2828
rt/test/rust_test_harness.cpp \
2929
rt/test/rust_test_runtime.cpp \
30-
rt/test/rust_test_util.cpp
30+
rt/test/rust_test_util.cpp \
31+
rt/arch/i386/context.cpp \
3132

32-
RUNTIME_LL := rt/new_exit.ll rt/vec_append.ll
33+
RUNTIME_LL := rt/vec_append.ll
3334

34-
RUNTIME_S := rt/activate_glue.s rt/yield_glue.s
35+
RUNTIME_S := rt/arch/i386/_context.s
3536

3637
RUNTIME_HDR := rt/globals.h \
3738
rt/rust.h \
@@ -60,10 +61,12 @@ RUNTIME_HDR := rt/globals.h \
6061
rt/memory.h \
6162
rt/test/rust_test_harness.h \
6263
rt/test/rust_test_runtime.h \
63-
rt/test/rust_test_util.h
64+
rt/test/rust_test_util.h \
65+
rt/arch/i386/context.h \
6466

6567
RUNTIME_DEF := rt/rustrt$(CFG_DEF_SUFFIX)
66-
RUNTIME_INCS := -I $(S)src/rt/isaac -I $(S)src/rt/uthash
68+
RUNTIME_INCS := -I $(S)src/rt/isaac -I $(S)src/rt/uthash \
69+
-I $(S)src/rt/arch/i386
6770
RUNTIME_OBJS := $(RUNTIME_CS:.cpp=.o) $(RUNTIME_LL:.ll=.o) $(RUNTIME_S:.s=.o)
6871
RUNTIME_LIBS := $(CFG_GCCISH_POST_LIB_FLAGS)
6972

src/comp/back/abi.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,6 @@ fn vec_append_glue_name() -> str {
9393
ret "rust_vec_append_glue";
9494
}
9595

96-
fn yield_glue_name() -> str {
97-
ret "rust_yield_glue";
98-
}
99-
10096
fn no_op_type_glue_name() -> str {
10197
ret "rust_no_op_type_glue";
10298
}

src/comp/back/upcall.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ fn declare_upcalls(type_names tn, ModuleRef llmod) -> @upcalls {
114114
T_ptr(T_tydesc(tn))),
115115
new_task=d("new_task", [T_ptr(T_str())], T_taskptr(tn)),
116116
start_task=d("start_task", [T_taskptr(tn),
117-
T_int(), T_int()],
117+
T_int(), T_int(), T_size_t()],
118118
T_taskptr(tn)),
119119
new_thread=d("new_thread", [T_ptr(T_i8())], T_taskptr(tn)),
120120
start_thread=d("start_thread", [T_taskptr(tn), T_int(), T_int(),

src/comp/middle/trans.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,7 @@ state obj namegen(mutable int i) {
8585

8686
type derived_tydesc_info = rec(ValueRef lltydesc, bool escapes);
8787

88-
type glue_fns = rec(ValueRef yield_glue,
89-
ValueRef no_op_type_glue,
88+
type glue_fns = rec(ValueRef no_op_type_glue,
9089
ValueRef vec_append_glue);
9190

9291
type tydesc_info = rec(ty::t ty,
@@ -6454,13 +6453,12 @@ fn trans_spawn(&@block_ctxt cx,
64546453
auto wrapper = mk_spawn_wrapper(bcx, func, args_ty);
64556454
bcx = wrapper.bcx;
64566455
auto llfnptr_i = bcx.build.PointerCast(wrapper.val, T_int());
6457-
// TODO: this next line might be necessary...
6458-
//llfnptr_i = bcx.build.Load(llfnptr_i);
64596456

64606457
// And start the task
6458+
auto args_size = size_of(bcx, args_ty).val;
64616459
bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.start_task,
64626460
[bcx.fcx.lltaskptr, new_task,
6463-
llfnptr_i, llargs_i]);
6461+
llfnptr_i, llargs_i, args_size]);
64646462

64656463
auto task_ty = node_ann_type(bcx.fcx.lcx.ccx, ann);
64666464
auto dropref = clean(bind drop_ty(_, new_task, task_ty));
@@ -8545,8 +8543,7 @@ fn vec_p0(&@block_ctxt bcx, ValueRef v) -> ValueRef {
85458543
}
85468544

85478545
fn make_glues(ModuleRef llmod, &type_names tn) -> @glue_fns {
8548-
ret @rec(yield_glue = decl_glue(llmod, tn, abi::yield_glue_name()),
8549-
no_op_type_glue = decl_no_op_type_glue(llmod, tn),
8546+
ret @rec(no_op_type_glue = decl_no_op_type_glue(llmod, tn),
85508547
vec_append_glue = make_vec_append_glue(llmod, tn));
85518548
}
85528549

src/lib/std.rc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ mod str;
1818

1919
mod io;
2020
mod sys;
21-
mod _task;
21+
mod task;
2222

2323
// Utility modules.
2424

@@ -33,7 +33,7 @@ auth os_fs = unsafe;
3333
auth run = unsafe;
3434
auth str = unsafe;
3535
auth vec = unsafe;
36-
auth _task = unsafe;
36+
auth task = unsafe;
3737

3838
auth dbg = unsafe;
3939

src/lib/_task.rs renamed to src/lib/task.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
native "rust" mod rustrt {
22
fn task_sleep(uint time_in_us);
3+
fn task_yield();
34
}
45

56
/**
@@ -11,6 +12,15 @@ fn sleep(uint time_in_us) {
1112
ret rustrt::task_sleep(time_in_us);
1213
}
1314

15+
fn yield() {
16+
ret rustrt::task_yield();
17+
}
18+
19+
fn join(task t) {
20+
// TODO: figure out how to pass tasks to the runtime and call the builtin
21+
// join.
22+
}
23+
1424
// Local Variables:
1525
// mode: rust;
1626
// fill-column: 78;

src/rt/activate_glue.s

Lines changed: 0 additions & 89 deletions
This file was deleted.

src/rt/arch/i386/_context.s

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
.text
2+
3+
/*
4+
Callee save registers:
5+
ebp, ebx, esi, edi
6+
7+
Caller save registers:
8+
eax, ecx, edx
9+
*/
10+
11+
/*
12+
Saves a set of registers. This is used by our implementation of
13+
getcontext.
14+
15+
The registers_t variable is in (%esp)
16+
*/
17+
18+
.globl get_registers
19+
get_registers:
20+
movl 4(%esp), %eax
21+
movl %eax, 0(%eax)
22+
movl %ebx, 4(%eax)
23+
movl %ecx, 8(%eax)
24+
movl %edx, 12(%eax)
25+
movl %ebp, 16(%eax)
26+
movl %esi, 20(%eax)
27+
movl %edi, 24(%eax)
28+
movl %esp, 28(%eax)
29+
movw %cs, 32(%eax)
30+
movw %ds, 34(%eax)
31+
movw %ss, 36(%eax)
32+
movw %es, 38(%eax)
33+
movw %fs, 40(%eax)
34+
movw %gs, 42(%eax)
35+
36+
// save the flags
37+
pushf
38+
popl %ecx
39+
movl %ecx, 44(%eax)
40+
41+
// save the return address as the instruction pointer
42+
movl 0(%esp), %ecx
43+
movl %ecx, 48(%eax)
44+
45+
// return 0
46+
xor %eax, %eax
47+
ret
48+
49+
.globl set_registers
50+
set_registers:
51+
movl 4(%esp), %eax
52+
53+
movl 4(%eax), %ebx
54+
// save ecx for later...
55+
movl 12(%eax), %edx
56+
movl 16(%eax), %ebp
57+
movl 20(%eax), %esi
58+
movl 24(%eax), %edi
59+
movl 28(%eax), %esp
60+
// We can't actually change this...
61+
//movl 32(%eax), %cs
62+
movw 34(%eax), %ds
63+
movw 36(%eax), %ss
64+
movw 38(%eax), %es
65+
movw 40(%eax), %fs
66+
movw 42(%eax), %gs
67+
68+
// restore the flags
69+
movl 44(%eax), %ecx
70+
push %ecx
71+
popf
72+
73+
// get ready to return back to the old eip
74+
// We could write this directly to 0(%esp), but Valgrind on OS X
75+
// complains.
76+
pop %ecx
77+
mov 48(%eax), %ecx
78+
push %ecx
79+
//movl %ecx, 0(%esp)
80+
81+
// okay, now we can restore ecx.
82+
movl 8(%eax), %ecx
83+
84+
// return 1 to the saved eip
85+
movl $1, %eax
86+
ret

0 commit comments

Comments
 (0)