summaryrefslogtreecommitdiff
path: root/libs/context/doc/rationale.qbk
blob: a034f2ab418f4e198b7ba8c1515321d7f41c9051 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
[/
          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 his 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].


[heading ucontext_t]

Since POSIX.1-2003 `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 by
perfomance_link[factor 13x] relative to `fcontext_t`).


[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]