On Thu, Mar 14, 2013 at 10:04:23AM +0000, Peter Maydell wrote: > On 13 March 2013 12:34, Anthony Liguori <anth...@codemonkey.ws> wrote: > > AioContext is necessary for the block layer because the block layer > > still has synchronous I/O. I think we should aim to replace all sync > > I/O in the long term with coroutine based I/O. > > I think coroutines are dreadful and we should really not be moving > towards greater use of them. They're just really really not portable > and they don't fit with the C language, and they're a constant source > of problems.(For instance I have a bug I need to look into where we > seem to hang using the gthread coroutine backend but not sigaltstack.) > > Use threads, or a genuinely asynchronous API, or a select/poll loop > with callbacks, but not more coroutines please.
You're right that coroutines make it harder to support QEMU across host operating systems. Why we have coroutines ====================== That said, we need an alternative mechanism for writing sequential code. If we went through the effort of converting all coroutine and blocking code to asynchronous callbacks the codebase would be very hard to understand: Straightforward operations would be split into many little callbacks. Local variables would turn into state that gets passed between callbacks. This sort of code is much harder to reason about and is why coroutines were introduced. Coroutines allow us to keep the block layer and some of its users readable. Removing them would not only be a big effort, but would also make the codebase worse. An alternative to stack switching ================================= I was looking at a second approach when considering the options: continuation passing style transformation. The following research project implements an extension to C for writing sequential code that gets converted to callbacks: http://www.pps.univ-paris-diderot.fr/~kerneis/software/cpc/ Quick summary of how it works: Continuating passing functions are marked with coroutine_fn, similar to how we already do it in QEMU. There are APIs to create new coroutines and to yield. The trick is that stack switching is not used and therefore this approach is portable C. Instead the code is translated to callbacks at build-time and variables are automatically passed on the heap in a "thunk" buffer. I chatted with the authors and it looks like a good approach. The problems are: 1. Uses OCaml compiler framework. Should this be part of gcc or an external tool that is easily consumed on all QEMU host platforms? 2. Debug information - need to make sure that callbacks map back to sequential code. 3. Maturity - cpc isn't used much to my knowledge. I'm willing to mentor a Summer of Code project that attempts to replace coroutines with cpc. There's no guarantee it can replace coroutines due to the issues I listed, but I think it's worth a shot. Peter: Does this approach address your concerns about coroutines? Thoughts about using a build-time tool instead of run-time stack switching? Stefan