On Mon, Oct 28, 2013 at 10:23 PM, Corey Richardson <co...@octayn.net> wrote:

> I've written up more thoughts on stack safety at
> http://cmr.github.io/blog/2013/10/28/more-on-stack-safety/. If no one
> objects to it (meeting tomorrow!) or has any better ideas, I'll start
> implementing it.
>

Consider this: *if* you're only executing tasks that you know will never
block (either due to IO, a concurrency primitive, or due to pre-emption)
then you would only need a single stack per OS thread. These can be
therefore be "big" (e.g. 1GB, lazily allocated, with logic to shrink it
occasionally?).

This holds true if only 90% of tasks are non-blocking. For blocking tasks
you can't use large stacks without risking that the task will block
while holding on to all that address space (and even physical memory). So,
if 90% of tasks run without blocking, you could run the remaining 10% of
tasks with segmented stacks. Do all the usual heroic analysis to minimize
cost of segmented stacks, but know that it only affects tasks that block,
which would be a minority in this scheme.

One way to make sure that most tasks don't block is to make co-operative
scheduling the default. IME you tend to have a lot of blocking at the
bottom of a thread (for coordination), and then a whole bunch of work
happening in functions that never touch any IO or OS primitives (and really
don't need to be pre-empted either). If you can make sure the scheduler
never pre-empts these tasks they can switch to a big stack as soon as they
enter a function that doesn't block (known statically).

This way the vast majority of code executes without ever checking for stack
sizes manually, and you still don't gobble up massive amounts of address
space.

The big issue here then is really that rust tasks can be pre-empted, and
therefore you can't guarantee that *any* function is free from blocking
(which means you can't assign it a large stack, since it may go to sleep
while holding it). IMO co-operative tasks (by default) is worth considering
as a solution here. Then tag functions that don't block (transitively), and
let those functions run on large stacks (unless you statically know that
the current segmented stack space is enough.. you can save the switching
cost in those cases).

Seb
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to