137 lines
4.9 KiB
Text
Executable file
137 lines
4.9 KiB
Text
Executable file
[/
|
|
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]
|