6 An executing Rust program consists of a tree of tasks, each with their own
7 stack, and sole ownership of their allocated heap data. Tasks communicate
8 with each other using ports and channels.
10 When a task fails, that failure will propagate to its parent (the task
11 that spawned it) and the parent will fail as well. The reverse is not
12 true: when a parent task fails its children will continue executing. When
13 the root (main) task fails, all tasks fail, and then so does the entire
16 A task may remove itself from this failure propagation mechanism by
17 calling the <unsupervise> function, after which failure will only
18 result in the termination of that task.
20 Tasks may execute in parallel and are scheduled automatically by the runtime.
24 > spawn("Hello, World", fn (&&msg: str) {
29 import cast = unsafe::reinterpret_cast;
31 import option::{some, none};
32 import option = option::t;
40 export task_notification;
50 export spawn_joinable;
52 #[abi = "rust-intrinsic"]
54 // these must run on the Rust stack so that they can swap stacks etc:
55 fn task_sleep(task: *rust_task, time_in_us: uint, &killed: bool);
59 fnptr: c::intptr_t, envptr: c::intptr_t
62 #[link_name = "rustrt"]
65 // these can run on the C stack:
68 fn get_task_id() -> task_id;
69 fn rust_get_task() -> *rust_task;
71 fn new_task() -> task_id;
72 fn drop_task(task_id: *rust_task);
73 fn get_task_pointer(id: task_id) -> *rust_task;
75 fn migrate_alloc(alloc: *u8, target: task_id);
77 fn start_task(id: task, closure: *rust_closure);
84 mutable notify_enabled: int,
85 mutable notify_chan: comm::chan<task_notification>,
86 mutable stack_ptr: *u8};
88 resource rust_task_ptr(task: *rust_task) { rustrt::drop_task(task); }
102 Creates and executes a new child task
104 Sets up a new task with its own call stack and schedules it to be
105 executed. Upon execution, the closure `f()` will be invoked.
109 f - A function to execute in the new task
113 A handle to the new task
115 fn spawn(-f: sendfn()) -> task unsafe {
116 let closure: *rust_closure = unsafe::reinterpret_cast(ptr::addr_of(f));
117 #debug("spawn: closure={%x,%x}", (*closure).fnptr, (*closure).envptr);
118 let id = rustrt::new_task();
119 rustrt::start_task(id, closure);
127 A task that sends notification upon termination
129 type joinable_task = (task, comm::port<task_notification>);
131 fn spawn_joinable(-f: sendfn()) -> joinable_task {
132 resource notify_rsrc(data: (comm::chan<task_notification>,
134 @mutable task_result)) {
135 let (chan, task, tr) = data;
136 let msg = exit(task, *tr);
137 comm::send(chan, msg);
140 let notify_port = comm::port();
141 let notify_chan = comm::chan(notify_port);
142 let g = sendfn[copy notify_chan; move f]() {
143 let this_task = rustrt::get_task_id();
144 let result = @mutable tr_failure;
145 let _rsrc = notify_rsrc((notify_chan, this_task, result));
147 *result = tr_success; // rsrc will fire msg when fn returns
150 ret (task, notify_port);
156 Indicates the manner in which a task exited
159 /* Variant: tr_success */
161 /* Variant: tr_failure */
166 Tag: task_notification
168 Message sent upon task exit to indicate normal or abnormal termination
170 tag task_notification {
172 exit(task, task_result);
175 /* Section: Operations */
180 Retreives a handle to the currently executing task
182 fn get_task() -> task { rustrt::get_task_id() }
187 Hints the scheduler to yield this task for a specified ammount of time.
191 time_in_us - maximum number of microseconds to yield control for
193 fn sleep(time_in_us: uint) {
194 let task = rustrt::rust_get_task();
196 // FIXME: uncomment this when extfmt is moved to core
198 // #debug("yielding for %u us", time_in_us);
199 rusti::task_sleep(task, time_in_us, killed);
208 Yield control to the task scheduler
210 The scheduler may schedule another task to execute.
212 fn yield() { sleep(1u) }
217 Wait for a child task to exit
219 The child task must have been spawned with <spawn_joinable>, which
220 produces a notification port that the child uses to communicate its
225 A task_result indicating whether the task terminated normally or failed
227 fn join(task_port: joinable_task) -> task_result {
228 let (id, port) = task_port;
229 alt comm::recv::<task_notification>(port) {
234 // FIXME: uncomment this when extfmt is moved to core
236 // fail #fmt["join received id %d, expected %d", _id, id]
244 Function: unsupervise
246 Detaches this task from its parent in the task tree
248 An unsupervised task will not propagate its failure up the task tree
250 fn unsupervise() { ret sys::unsupervise(); }
255 Pins the current task and future child tasks to a single scheduler thread
257 fn pin() { rustrt::pin_task(); }
262 Unpin the current task and future child tasks
264 fn unpin() { rustrt::unpin_task(); }
269 // indent-tabs-mode: nil
271 // buffer-file-coding-system: utf-8-unix