Fibers under the magnifying glass [pdf]
The implied background context is an analysis of whether C++ should adopt a fiber-based concurrency model <i>presuming</i> nothing outside a C++ compiler will ever change or be adapted. That may be a fair presumption from the perspective of the C++ committee, but the conclusions regarding efficiency and ergonomics of different concurrency models are not at all generalizable.<p>Even then, though, the analysis in the paper is still poor. Take section 2.2.1, for example:<p>&gt; This is approach allows fibers to use very small stacks (less than a typical memory page size of 4K), but, at the cost that the developer must have complete knowledge of how big activation frames are for every function that can be called directly&#x2F;transitively from the fiber. This is a very precarious approach to be used with extreme caution as the smallest mistake can lead to memory corruption and security exploits.<p>It characterizes the problem of determining stack size as being so intractable as to be unsafe. And yet this task--precisely calculating activation record size--is <i>exactly</i> what the compiler <i>must</i> <i>do</i> to implement stackless coroutines, the author&#x27;s preferred solution (and the one adopted by Rust and eventually adopted by C++).<p>In reality, the compiler can&#x27;t always do this, and so stackless coroutines in these languages don&#x27;t permit things like recursive function invocations or calling through function pointers (e.g. virtual methods), at least not without falling back to dynamic heap allocation. And yet elsewhere in the paper the author discusses and dismisses segmented stacks, without it apparently occurring to the author that segmented stacks is precisely what a C++ stackless coroutine implementation must end up implementing in any call chain that cannot be statically determined, which can be quite a common (even pervasive) situation in an object oriented language or in environments with dynamic linking.