]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/context/test/test_execution_context_v1.impl
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / context / test / test_execution_context_v1.impl
1
2 // Copyright Oliver Kowalke 2009.
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 #include <iostream>
8 #include <memory>
9 #include <sstream>
10 #include <stdexcept>
11 #include <string>
12 #include <utility>
13
14 #include <boost/array.hpp>
15 #include <boost/assert.hpp>
16 #include <boost/test/unit_test.hpp>
17 #include <boost/utility.hpp>
18
19 #include <boost/context/execution_context.hpp>
20 #include <boost/context/detail/config.hpp>
21
22 #ifdef BOOST_WINDOWS
23 #include <windows.h>
24 #endif
25
26 namespace ctx = boost::context;
27
28 int value1 = 0;
29 std::string value2;
30 double value3 = 0.;
31
32 #ifdef BOOST_WINDOWS
33 void seh( bool & catched) {
34 __try {
35 int i = 1;
36 i /= 0;
37 } __except( EXCEPTION_EXECUTE_HANDLER) {
38 catched = true;
39 }
40 }
41 #endif
42
43 void fn1( void * vp) {
44 value1 = 3;
45 ctx::execution_context * mctx = static_cast< ctx::execution_context * >( vp);
46 ( * mctx)();
47 }
48
49 void fn2( int i, void * vp) {
50 value1 = i;
51 ctx::execution_context * mctx = static_cast< ctx::execution_context * >( vp);
52 ( * mctx)();
53 }
54
55 void fn3( const char * what, void * vp) {
56 try {
57 throw std::runtime_error( what);
58 } catch ( std::runtime_error const& e) {
59 value2 = e.what();
60 }
61 ctx::execution_context * mctx = static_cast< ctx::execution_context * >( vp);
62 ( * mctx)();
63 }
64
65 void fn4( double d, void * vp) {
66 d += 3.45;
67 value3 = d;
68 ctx::execution_context * mctx = static_cast< ctx::execution_context * >( vp);
69 ( * mctx)();
70 }
71
72 void fn6( void * vp) {
73 value1 = 3;
74 ctx::execution_context * mctx = static_cast< ctx::execution_context * >( vp);
75 ( * mctx)();
76 }
77
78 void fn5( void * vp) {
79 std::cout << "fn5: entered" << std::endl;
80 ctx::execution_context ectx( fn6);
81 boost::context::execution_context ctx( boost::context::execution_context::current() );
82 ectx( & ctx);
83 value3 = 3.14;
84 ctx::execution_context * mctx = static_cast< ctx::execution_context * >( vp);
85 ( * mctx)();
86 }
87
88 void fn7( void * vp) {
89 ctx::execution_context * mctx = static_cast< ctx::execution_context * >( vp);
90 try {
91 value1 = 3;
92 void * data = ( * mctx)( vp);
93 value1 = 7;
94 ( * mctx)( data);
95 } catch ( std::runtime_error const& e) {
96 value2 = e.what();
97 }
98 ( * mctx)();
99 }
100
101 struct X {
102 int foo( int i, void * vp) {
103 value1 = i;
104 ctx::execution_context * mctx = static_cast< ctx::execution_context * >( vp);
105 ( * mctx)();
106 return i;
107 }
108 };
109
110 void test_ectx() {
111 value1 = 0;
112 ctx::execution_context ectx( fn1);
113 boost::context::execution_context ctx( boost::context::execution_context::current() );
114 ectx( & ctx);
115 BOOST_CHECK_EQUAL( 3, value1);
116 }
117
118 void test_variadric() {
119 value1 = 0;
120 ctx::execution_context ectx( fn2, 5);
121 boost::context::execution_context ctx( boost::context::execution_context::current() );
122 ectx( & ctx);
123 BOOST_CHECK_EQUAL( 5, value1);
124 }
125
126 void test_memfn() {
127 value1 = 0;
128 X x;
129 ctx::execution_context ectx( & X::foo, x, 7);
130 boost::context::execution_context ctx( boost::context::execution_context::current() );
131 ectx( & ctx);
132 BOOST_CHECK_EQUAL( 7, value1);
133 }
134
135 void test_exception() {
136 {
137 const char * what = "hello world";
138 ctx::execution_context ectx( fn3, what);
139 boost::context::execution_context ctx( boost::context::execution_context::current() );
140 ectx( & ctx);
141 BOOST_CHECK_EQUAL( std::string( what), value2);
142 }
143 #ifdef BOOST_WINDOWS
144 {
145 bool catched = false;
146 ctx::execution_context ectx([&catched]( void * vp){
147 ctx::execution_context * mctx = static_cast< ctx::execution_context * >( vp);
148 seh( catched);
149 ( * mctx)();
150 });
151 boost::context::execution_context ctx( boost::context::execution_context::current() );
152 ectx( & ctx);
153 BOOST_CHECK( catched);
154 }
155 #endif
156 }
157
158 void test_fp() {
159 double d = 7.13;
160 ctx::execution_context ectx( fn4, d);
161 boost::context::execution_context ctx( boost::context::execution_context::current() );
162 ectx( & ctx);
163 BOOST_CHECK_EQUAL( 10.58, value3);
164 }
165
166 void test_stacked() {
167 value1 = 0;
168 value3 = 0.;
169 ctx::execution_context ectx( fn5);
170 boost::context::execution_context ctx( boost::context::execution_context::current() );
171 ectx( & ctx);
172 BOOST_CHECK_EQUAL( 3, value1);
173 BOOST_CHECK_EQUAL( 3.14, value3);
174 }
175
176 void test_prealloc() {
177 value1 = 0;
178 ctx::default_stack alloc;
179 ctx::stack_context sctx( alloc.allocate() );
180 void * sp = static_cast< char * >( sctx.sp) - 10;
181 std::size_t size = sctx.size - 10;
182 ctx::execution_context ectx( std::allocator_arg, ctx::preallocated( sp, size, sctx), alloc, fn2, 7);
183 boost::context::execution_context ctx( boost::context::execution_context::current() );
184 ectx( & ctx);
185 BOOST_CHECK_EQUAL( 7, value1);
186 }
187
188 void test_ontop() {
189 value1 = 0;
190 value2 = "";
191 ctx::execution_context ectx( fn7);
192 boost::context::execution_context ctx( boost::context::execution_context::current() );
193 ectx( & ctx);
194 BOOST_CHECK_EQUAL( 3, value1);
195 BOOST_CHECK( value2.empty() );
196 std::string str("abc");
197 int i = 3;
198 void * data = ectx( ctx::exec_ontop_arg,
199 [str](void * data){
200 value2 = str;
201 return data;
202 },
203 & i);
204 BOOST_CHECK_EQUAL( 7, value1);
205 BOOST_CHECK_EQUAL( str, value2);
206 BOOST_CHECK_EQUAL( data, & i);
207 BOOST_CHECK_EQUAL( i, *( int*) data);
208 }
209
210 void test_ontop_exception() {
211 value1 = 0;
212 value2 = "";
213 ctx::execution_context ectx( fn7);
214 boost::context::execution_context ctx( boost::context::execution_context::current() );
215 ectx( & ctx);
216 BOOST_CHECK_EQUAL( 3, value1);
217 const char * what = "hello world";
218 ectx( ctx::exec_ontop_arg,
219 [what](void * data){
220 throw std::runtime_error( what);
221 return data;
222 },
223 nullptr);
224 BOOST_CHECK_EQUAL( 3, value1);
225 BOOST_CHECK_EQUAL( std::string( what), value2);
226 }
227
228 #ifdef BOOST_WINDOWS
229 void test_test_bug12215() {
230 ctx::execution_context ectx(
231 [](void * vp) {
232 ctx::execution_context * mctx = static_cast< ctx::execution_context * >( vp);
233 char buffer[MAX_PATH];
234 GetModuleFileName( nullptr, buffer, MAX_PATH);
235 ( * mctx)();
236 });
237 boost::context::execution_context ctx( boost::context::execution_context::current() );
238 ectx( & ctx);
239 }
240 #endif
241
242 boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
243 {
244 boost::unit_test::test_suite * test =
245 BOOST_TEST_SUITE("Boost.Context: execution_context v1 test suite");
246
247 test->add( BOOST_TEST_CASE( & test_ectx) );
248 test->add( BOOST_TEST_CASE( & test_variadric) );
249 test->add( BOOST_TEST_CASE( & test_memfn) );
250 test->add( BOOST_TEST_CASE( & test_exception) );
251 test->add( BOOST_TEST_CASE( & test_fp) );
252 test->add( BOOST_TEST_CASE( & test_stacked) );
253 test->add( BOOST_TEST_CASE( & test_prealloc) );
254 test->add( BOOST_TEST_CASE( & test_ontop) );
255 test->add( BOOST_TEST_CASE( & test_ontop_exception) );
256 #ifdef BOOST_WINDOWS
257 test->add( BOOST_TEST_CASE( & test_test_bug12215) );
258 #endif
259
260 return test;
261 }