...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
C99 defines setjmp()
/longjmp()
to provide non-local jumps but it does not require that longjmp()
preserves the current stack frame. Therefore, jumping into a function which
was exited via a call to longjmp() is undefined [2].
Since POSIX.1-2004 ucontext_t
is deprecated and was removed in POSIX.1-2008! The function signature of
makecontext()
is:
void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
The third argument of makecontext()
specifies the number of integer arguments
that follow which will require function pointer cast if func
will accept those arguments which is undefined in C99 [3].
The arguments in the var-arg list are required to be integers, passing pointers in var-arg list is not guaranteed to work, especially it will fail for architectures where pointers are larger than integers.
ucontext_t
preserves signal
mask between context switches which involves system calls consuming a lot
of CPU cycles (ucontext_t is slower; a context switch takes two
magnitutes of order more CPU cycles more than fcontext_t).
A drawback of Windows Fiber API is that CreateFiber()
does not accept a pointer to user allocated
stack space preventing the reuse of stacks for other context instances. Because
the Windows Fiber API requires to call ConvertThreadToFiber()
if SwitchFiber()
is called for a thread which has not been
converted to a fiber. For the same reason ConvertFiberToThread()
must be called after return from SwitchFiber()
if the thread was forced to be converted to a fiber before (which is inefficient).
if ( ! is_a_fiber() ) { ConvertThreadToFiber( 0); SwitchToFiber( ctx); ConvertFiberToThread(); }
If the condition _WIN32_WINNT >= _WIN32_WINNT_VISTA
is met function IsThreadAFiber()
is provided in order to detect if the current
thread was already converted. Unfortunately Windows XP + SP 2/3 defines
_WIN32_WINNT >=
_WIN32_WINNT_VISTA
without providing
IsThreadAFiber()
.