Blame view

3rdparty/boost_1_81_0/libs/context/doc/rationale.qbk 4.89 KB
977ed18d   Hu Chunming   提交三方库
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
137
  [/
            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]