]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [/ |
2 | Copyright Oliver Kowalke 2014. | |
3 | Distributed under the Boost Software License, Version 1.0. | |
4 | (See accompanying file LICENSE_1_0.txt or copy at | |
5 | http://www.boost.org/LICENSE_1_0.txt | |
6 | ] | |
7 | ||
8 | [section:rationale Rationale] | |
9 | ||
10 | [heading No inline-assembler] | |
11 | ||
12 | Some newer compiler (for instance MSVC 10 for x86_64 and itanium) do not | |
13 | support inline assembler. | |
14 | [footnote [@http://msdn.microsoft.com/en-us/library/4ks26t93.aspx MSDN article | |
15 | 'Inline Assembler']]. | |
16 | Inlined assembler generates code bloating which is not welcome on embedded | |
17 | systems. | |
18 | ||
19 | ||
20 | [heading fcontext_t] | |
21 | ||
22 | __boost_context__ provides the low level API fcontext_t which is | |
23 | implemented in assembler to provide context swapping operations. | |
24 | fcontext_t is the part to port to new platforms. | |
25 | ||
26 | [note Context switches do not preserve the signal mask on UNIX systems.] | |
27 | ||
28 | __fcontext__ is an opaque pointer. | |
29 | ||
30 | ||
31 | ||
32 | [section Other APIs ] | |
33 | ||
34 | [heading setjmp()/longjmp()] | |
35 | ||
36 | C99 defines `setjmp()`/`longjmp()` to provide non-local jumps but it does not | |
37 | require that ['longjmp()] preserves the current stack frame. Therefore, jumping | |
38 | into a function which was exited via a call to ['longjmp()] is undefined | |
39 | [footnote ISO/IEC 9899:1999, 2005, 7.13.2.1:2]. | |
40 | ||
41 | ||
42 | [heading ucontext_t] | |
43 | ||
44 | Since POSIX.1-2003 `ucontext_t` is deprecated and was removed in POSIX.1-2008! | |
45 | The function signature of `makecontext()` is: | |
46 | ||
47 | void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...); | |
48 | ||
49 | The third argument of `makecontext()` specifies the number of integer arguments | |
50 | that follow which will require function pointer cast if `func` will accept those | |
51 | arguments which is undefined in C99 | |
52 | [footnote ISO/IEC 9899:1999, 2005, J.2]. | |
53 | ||
54 | The arguments in the var-arg list are required to be integers, passing pointers | |
55 | in var-arg list is not guaranteed to work, especially it will fail for | |
56 | architectures where pointers are larger than integers. | |
57 | ||
58 | `ucontext_t` preserves signal mask between context switches which involves system | |
59 | calls consuming a lot of CPU cycles (ucontext_t is slower by | |
60 | perfomance_link[factor 13x] relative to `fcontext_t`). | |
61 | ||
62 | ||
63 | [heading Windows fibers] | |
64 | ||
65 | A drawback of Windows Fiber API is that `CreateFiber()` does not accept a | |
66 | pointer to user allocated stack space preventing the reuse of stacks for other | |
67 | context instances. Because the Windows Fiber API requires to call | |
68 | `ConvertThreadToFiber()` if `SwitchFiber()` is called for a thread which has not | |
69 | been converted to a fiber. For the same reason `ConvertFiberToThread()` | |
70 | must be called after return from `SwitchFiber()` if the thread was forced to be | |
71 | converted to a fiber before (which is inefficient). | |
72 | ||
73 | if ( ! is_a_fiber() ) | |
74 | { | |
75 | ConvertThreadToFiber( 0); | |
76 | SwitchToFiber( ctx); | |
77 | ConvertFiberToThread(); | |
78 | } | |
79 | ||
80 | If the condition `_WIN32_WINNT >= _WIN32_WINNT_VISTA` is met function | |
81 | `IsThreadAFiber()` is provided in order to detect if the current thread was | |
82 | already converted. Unfortunately Windows XP + SP 2/3 defines | |
83 | `_WIN32_WINNT >= _WIN32_WINNT_VISTA` without providing `IsThreadAFiber()`. | |
84 | ||
85 | [endsect] | |
86 | ||
87 | ||
88 | [section x86 and floating-point env] | |
89 | ||
90 | [heading i386] | |
91 | ||
92 | "The FpCsr and the MxCsr register must be saved and restored before any call or return | |
93 | by any procedure that needs to modify them ..." | |
94 | [footnote 'Calling Conventions', Agner Fog]. | |
95 | ||
96 | ||
97 | [heading x86_64] | |
98 | ||
99 | [heading Windows] | |
100 | ||
101 | MxCsr - "A callee that modifies any of the non-volatile fields within MxCsr must restore | |
102 | them before returning to its caller. Furthermore, a caller that has modified any | |
103 | of these fields must restore them to their standard values before invoking a callee ..." | |
104 | [footnote [@http://http://msdn.microsoft.com/en-us/library/yxty7t75.aspx MSDN article | |
105 | 'MxCsr']]. | |
106 | ||
107 | FpCsr - "A callee that modifies any of the fields within FpCsr must restore them before | |
108 | returning to its caller. Furthermore, a caller that has modified any of these | |
109 | fields must restore them to their standard values before invoking a callee ..." | |
110 | [footnote [@http://http://msdn.microsoft.com/en-us/library/ms235300.aspx MSDN article | |
111 | 'FpCsr']]. | |
112 | ||
113 | "The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are preserved across | |
114 | context switches. There is no explicit calling convention for these registers." | |
115 | [footnote [@http://msdn.microsoft.com/en-us/library/a32tsf7t%28VS.80%29.aspx MSDN article | |
116 | 'Legacy Floating-Point Support']]. | |
117 | ||
118 | "The 64-bit Microsoft compiler does not use ST(0)-ST(7)/MM0-MM7". | |
119 | [footnote 'Calling Conventions', Agner Fog]. | |
120 | ||
121 | "XMM6-XMM15 must be preserved" | |
122 | [footnote [@http://msdn.microsoft.com/en-us/library/9z1stfyw%28v=vs.100%29.aspx MSDN | |
123 | article 'Register Usage']] | |
124 | ||
125 | [heading SysV] | |
126 | ||
127 | "The control bits of the MxCsr register are callee-saved (preserved across calls), | |
128 | while the status bits are caller-saved (not preserved). The x87 status word register is | |
129 | caller-saved, whereas the x87 control word (FpCsr) is callee-saved." | |
130 | [footnote SysV ABI AMD64 Architecture Processor Supplement Draft Version 0.99.4, 3.2.1]. | |
131 | ||
132 | [endsect] | |
133 | ||
134 | ||
135 | [endsect] |