On Tue, May 24, 2011 at 9:51 PM, Jamie Lokier <ja...@shareable.org> wrote:
> Stefan Hajnoczi wrote:
>> My current plan is to try using sigaltstack(2) instead of
>> makecontext()/swapcontext() as a hack since OpenBSD doesn't have
>> makecontext()/swapcontext().
>
> sigaltstack() is just a system call to tell the system about an
> alternative signal stack - that you have allocated yourself using
> malloc().  According to 'info libc "Signal Stack"'.  It won't help you
> get a new stack by itself.

Issue sigaltstack() with the malloced new stack.  Send yourself a
signal and in a custom signal handler setjmp() to stash away the state
(you're now on the new stack).

>
> Maybe take a look at what GNU Pth does.  It has a similar matrix of
> tested platforms using different strategies on each, though it is
> slightly different because it obviously doesn't link with
> libpthread.so (it provides it!), and it has to context switch from the
> SIGALRM handler for pre-emption.
>
>> TBH I'm almost at the stage where I think we should just use threads
>> and/or async callbacks, as appropriate.  Hopefully I'll be able to cook
>> up a reasonably portable implementation of coroutines though, because
>> the prospect of having to go fully threaded or do async callbacks isn't
>> attractive in many cases.
>
> Another classic trick is just to call a function recursively which has
> a large local array(*), setjmp() every M calls, and longjmp() back to
> the start after M*N calls.  That gets you N setjmp() contexts to
> switch between, all in the same larger stack so it's fine even with
> old pthread implementations, providing the total stack used isn't too
> big, and the individual stacks you've allocated aren't too small for
> the program.

True, I think I've done something like this with alloca() before :(.
It's extremely hacky though.

Stefan

Reply via email to