[/ Copyright Oliver Kowalke 2014. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt ] [section:rationale Rationale] [heading No inline-assembler] Some newer compiler (for instance MSVC 10 for x86_64 and itanium) do not support inline assembler. [footnote [@http://msdn.microsoft.com/en-us/library/4ks26t93.aspx MSDN article 'Inline Assembler']]. Inlined assembler generates code bloating which is not welcome on embedded systems. [heading fcontext_t] __boost_context__ provides the low level API fcontext_t which is implemented in assembler to provide context swapping operations. fcontext_t is the part to port to new platforms. [note Context switches do not preserve the signal mask on UNIX systems.] __fcontext__ is an opaque pointer. [section Other APIs ] [heading setjmp()/longjmp()] 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 [footnote ISO/IEC 9899:1999, 2005, 7.13.2.1:2]. [#ucontext] [heading ucontext_t] 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 [footnote ISO/IEC 9899:1999, 2005, J.2]. 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 [link performance ['two magnitutes of order more CPU cycles]] more than __fcontext__). [heading Windows fibers] 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()`. [endsect] [section x86 and floating-point env] [heading i386] "The FpCsr and the MxCsr register must be saved and restored before any call or return by any procedure that needs to modify them ..." [footnote 'Calling Conventions', Agner Fog]. [heading x86_64] [heading Windows] MxCsr - "A callee that modifies any of the non-volatile fields within MxCsr must restore them before returning to its caller. Furthermore, a caller that has modified any of these fields must restore them to their standard values before invoking a callee ..." [footnote [@http://http://msdn.microsoft.com/en-us/library/yxty7t75.aspx MSDN article 'MxCsr']]. FpCsr - "A callee that modifies any of the fields within FpCsr must restore them before returning to its caller. Furthermore, a caller that has modified any of these fields must restore them to their standard values before invoking a callee ..." [footnote [@http://http://msdn.microsoft.com/en-us/library/ms235300.aspx MSDN article 'FpCsr']]. "The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are preserved across context switches. There is no explicit calling convention for these registers." [footnote [@http://msdn.microsoft.com/en-us/library/a32tsf7t%28VS.80%29.aspx MSDN article 'Legacy Floating-Point Support']]. "The 64-bit Microsoft compiler does not use ST(0)-ST(7)/MM0-MM7". [footnote 'Calling Conventions', Agner Fog]. "XMM6-XMM15 must be preserved" [footnote [@http://msdn.microsoft.com/en-us/library/9z1stfyw%28v=vs.100%29.aspx MSDN article 'Register Usage']] [heading SysV] "The control bits of the MxCsr register are callee-saved (preserved across calls), while the status bits are caller-saved (not preserved). The x87 status word register is caller-saved, whereas the x87 control word (FpCsr) is callee-saved." [footnote SysV ABI AMD64 Architecture Processor Supplement Draft Version 0.99.4, 3.2.1]. [endsect] [endsect]