about summary refs log tree commit diff
path: root/src/lib
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-08-17 14:42:28 -0700
committerEric Holk <eholk@mozilla.com>2011-08-17 14:42:40 -0700
commitae89ea223de2fe5e9c9a5cdd2fa85a93828a7daa (patch)
tree1a28bb09eaeaf105bd84cc62c6a3e6c9ae2a8b8f /src/lib
parentefac7c9a197fa3ff3497ce99a2dda8693b3ef683 (diff)
downloadrust-ae89ea223de2fe5e9c9a5cdd2fa85a93828a7daa.tar.gz
rust-ae89ea223de2fe5e9c9a5cdd2fa85a93828a7daa.zip
Making more of the rust_task structure directly accessible from Rust.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/comm.rs2
-rw-r--r--src/lib/ptr.rs1
-rw-r--r--src/lib/task.rs45
3 files changed, 30 insertions, 18 deletions
diff --git a/src/lib/comm.rs b/src/lib/comm.rs
index 318d9782301..17c766cda1a 100644
--- a/src/lib/comm.rs
+++ b/src/lib/comm.rs
@@ -8,7 +8,6 @@ export _chan;
 export _port;
 
 export mk_port;
-export chan_from_unsafe_ptr;
 export send;
 export recv;
 export chan;
@@ -47,7 +46,6 @@ resource port_ptr(po: *rustrt::rust_port) {
 type port<~T> = @port_ptr;
 
 obj port_obj<~T>(raw_port : port<T>) {
-    // FIXME: rename this to chan once chan is not a keyword.
     fn mk_chan() -> _chan<T> {
         chan::<T>(raw_port)
     }
diff --git a/src/lib/ptr.rs b/src/lib/ptr.rs
index baacaf2d5e0..42815845e47 100644
--- a/src/lib/ptr.rs
+++ b/src/lib/ptr.rs
@@ -10,3 +10,4 @@ fn offset<T>(ptr: *T, count: uint) -> *T {
     ret rusti::ptr_offset(ptr, count);
 }
 
+fn null<T>() -> *T { ret unsafe::reinterpret_cast(0u); }
diff --git a/src/lib/task.rs b/src/lib/task.rs
index d010afc5217..d3f26ce769b 100644
--- a/src/lib/task.rs
+++ b/src/lib/task.rs
@@ -4,6 +4,7 @@ import comm::_chan;
 import option::some;
 import option::none;
 import option = option::t;
+import ptr;
 
 native "rust" mod rustrt {
     fn task_sleep(time_in_us: uint);
@@ -19,9 +20,8 @@ native "rust" mod rustrt {
     fn set_min_stack(stack_size: uint);
 
     fn new_task() -> task_id;
-    fn drop_task(id : task_id);
+    fn drop_task(task : *rust_task);
     fn get_task_pointer(id : task_id) -> *rust_task;
-    fn get_task_context(id : task_id) -> *x86_registers;
     fn start_task(id : task_id);
     fn get_task_trampoline() -> u32;
 
@@ -31,10 +31,26 @@ native "rust" mod rustrt {
 }
 
 type rust_task = {
+    id : task,
     mutable notify_enabled : u8,
-    mutable notify_chan : _chan<task_notification>
+    mutable notify_chan : _chan<task_notification>,
+    ctx : task_context,
+    stack_ptr : *u8
 };
 
+type task_context = {
+    regs : x86_registers,
+    next : *u8
+};
+
+resource rust_task_ptr(task : *rust_task) {
+    rustrt::drop_task(task);
+}
+
+fn get_task_ptr(id : task) -> rust_task_ptr {
+    ret rust_task_ptr(rustrt::get_task_pointer(id));
+}
+
 type task = int;
 type task_id = task;
 
@@ -95,14 +111,16 @@ fn spawn_inner(thunk : -fn() -> (),
     let id = rustrt::new_task();
 
     // the order of arguments are outptr, taskptr, envptr.
-
-    // In LLVM fastcall puts the first two in ecx, edx, and the rest on the
+    // LLVM fastcall puts the first two in ecx, edx, and the rest on the
     // stack.
-    let regs = rustrt::get_task_context(id);
 
     // set up the task pointer
-    let task_ptr = rustrt::get_task_pointer(id);
-    (*regs).edx = cast(task_ptr);
+    let task_ptr = get_task_ptr(id);
+    let regs = ptr::addr_of((**task_ptr).ctx.regs);
+    (*regs).edx = cast(*task_ptr);
+    (*regs).esp = cast((**task_ptr).stack_ptr);
+
+    assert ptr::null() != (**task_ptr).stack_ptr;
 
     let raw_thunk : { code: u32, env: u32 } = cast(thunk);
     (*regs).eip = raw_thunk.code;
@@ -110,8 +128,8 @@ fn spawn_inner(thunk : -fn() -> (),
     // set up notifications if they are enabled.
     alt notify {
       some(c) {
-        (*task_ptr).notify_enabled = 1u8;
-        (*task_ptr).notify_chan = c;
+        (**task_ptr).notify_enabled = 1u8;
+        (**task_ptr).notify_chan = c;
       }
       none {}
     };
@@ -130,7 +148,7 @@ fn spawn_inner(thunk : -fn() -> (),
     // put the return pointer in ecx.
     (*regs).ecx = (*regs).esp + 8u32;
 
-    *tptr = cast(task_ptr);
+    *tptr = cast(*task_ptr);
     *env = raw_thunk.env;
     *ra = rustrt::get_task_trampoline();
 
@@ -139,11 +157,6 @@ fn spawn_inner(thunk : -fn() -> (),
 
     rustrt::leak(thunk);
 
-    // Drop twice because get_task_context and get_task_pounter both bump the
-    // ref count and expect us to free it.
-    rustrt::drop_task(id);
-    rustrt::drop_task(id);
-
     ret id;
 }