about summary refs log tree commit diff
path: root/src/rt/rust_task.h
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-06-02 23:14:25 -0700
committerBrian Anderson <banderson@mozilla.com>2012-06-02 23:14:47 -0700
commit94ac30c498399eec1c5239b472845d238b1926ec (patch)
treea6da1c59d45e57954673a047faffd7d1af494a66 /src/rt/rust_task.h
parent9b9ceea6bdcc51ffab258ed2d6ef23066c17838c (diff)
downloadrust-94ac30c498399eec1c5239b472845d238b1926ec.tar.gz
rust-94ac30c498399eec1c5239b472845d238b1926ec.zip
rt: Improve docs for main, kernel, scheduler, and task
Diffstat (limited to 'src/rt/rust_task.h')
-rw-r--r--src/rt/rust_task.h69
1 files changed, 48 insertions, 21 deletions
diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h
index 4ad13472024..43f1abd190e 100644
--- a/src/rt/rust_task.h
+++ b/src/rt/rust_task.h
@@ -1,3 +1,28 @@
+/**
+   The rust task is a cooperatively-scheduled green thread that executes
+   Rust code on a segmented stack.
+
+   This class has too many responsibilities:
+
+   * Working with the scheduler loop to signal and respond to state changes,
+   and dealing with all the thread synchronization issues involved
+
+   * Managing the dynamically resizing list of Rust stack segments
+
+   * Switching between running Rust code on the Rust segmented stack and
+   native C code on large stacks owned by the scheduler
+
+   The lifetime of a rust_task object closely mirrors that of a running Rust
+   task object, but they are not identical. In particular, the rust_task is an
+   atomically reference counted object that might be accessed from arbitrary
+   threads at any time. This may keep the task from being destroyed even after
+   the task is dead from a Rust task lifecycle perspective.
+
+   FIXME: The task and the scheduler have an over-complicated, undocumented
+   protocol for shutting down the task, hopefully without races. It would be
+   easier to reason about if other runtime objects could not access the task
+   from arbitrary threads, and didn't need to be atomically refcounted.
+ */
 
 #ifndef RUST_TASK_H
 #define RUST_TASK_H
@@ -17,7 +42,8 @@
 
 // The amount of extra space at the end of each stack segment, available
 // to the rt, compiler and dynamic linker for running small functions
-// FIXME: We want this to be 128 but need to slim the red zone calls down
+// FIXME: We want this to be 128 but need to slim the red zone calls down,
+// disable lazy symbol relocation, and other things we haven't discovered yet
 #define RZ_LINUX_32 (1024*2)
 #define RZ_LINUX_64 (1024*2)
 #define RZ_MAC_32   (1024*20)
@@ -59,18 +85,6 @@
 #endif
 #endif
 
-extern "C" CDECL void
-record_sp_limit(void *limit);
-extern "C" CDECL uintptr_t
-get_sp_limit();
-
-// The function prolog compares the amount of stack needed to the end of
-// the stack. As an optimization, when the frame size is less than 256
-// bytes, it will simply compare %esp to to the stack limit instead of
-// subtracting the frame size. As a result we need our stack limit to
-// account for those 256 bytes.
-const unsigned LIMIT_OFFSET = 256;
-
 struct rust_box;
 
 struct frame_glue_fns {
@@ -323,14 +337,19 @@ template <typename T> struct task_owned {
 
 // This stuff is on the stack-switching fast path
 
-// Get a rough approximation of the current stack pointer
-extern "C" uintptr_t get_sp();
-
-// This is the function that switches stacks by calling another function with
-// a single void* argument while changing the stack pointer. It has a funny
-// name because gdb doesn't normally like to backtrace through split stacks
-// (thinks it indicates a bug), but has a special case to allow functions
-// named __morestack to move the stack pointer around.
+// Records the pointer to the end of the Rust stack in a platform-
+// specific location in the thread control block
+extern "C" CDECL void      record_sp_limit(void *limit);
+extern "C" CDECL uintptr_t get_sp_limit();
+// Gets a pointer to the vicinity of the current stack pointer
+extern "C" uintptr_t       get_sp();
+
+// This is the function that switches between the C and the Rust stack by
+// calling another function with a single void* argument while changing the
+// stack pointer. It has a funny name because gdb doesn't normally like to
+// backtrace through split stacks (thinks it indicates a bug), but has a
+// special case to allow functions named __morestack to move the stack pointer
+// around.
 extern "C" void __morestack(void *args, void *fn_ptr, uintptr_t stack_ptr);
 
 inline static uintptr_t
@@ -490,6 +509,14 @@ rust_task::prev_stack() {
 extern "C" CDECL void
 record_sp_limit(void *limit);
 
+// The LLVM-generated segmented-stack function prolog compares the amount of
+// stack needed for each frame to the end-of-stack pointer stored in the
+// TCB. As an optimization, when the frame size is less than 256 bytes, it
+// will simply compare %esp to to the stack limit instead of subtracting the
+// frame size. As a result we need our stack limit to account for those 256
+// bytes.
+const unsigned LIMIT_OFFSET = 256;
+
 inline void
 rust_task::record_stack_limit() {
     assert(stk);