qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 1/2] coroutine: introduce coroutines


From: Jamie Lokier
Subject: Re: [Qemu-devel] [PATCH 1/2] coroutine: introduce coroutines
Date: Tue, 24 May 2011 21:51:06 +0100
User-agent: Mutt/1.5.13 (2006-08-11)

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.

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.

If the large local array insists on being optimised away, it's
probably better anyway to track the address of a local variable, and
split the stack whenever the address has changed by enough.  Try to
make sure the compiler doesn't optimise away the tail recursion :-)

It works better on non-threaded programs as per-thread stacks are more
likely to have limited size.  *But* the initial thread often has a
large growable stack, just like a single-threaded program.  So it's a
good idea to do the stack carving in the initial thread (doesn't
necessarily have to be at the start of the program).  You may be able
to add guard pages afterwards with mprotect() if you're paranoid :-)

-- Jamie



reply via email to

[Prev in Thread] Current Thread [Next in Thread]