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