]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/context/test/test_fcontext.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / context / test / test_fcontext.cpp
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 <stdio.h>
8 #include <stdlib.h>
9
10 #include <cmath>
11 #include <cstdint>
12 #include <iostream>
13 #include <sstream>
14 #include <stdexcept>
15 #include <string>
16 #include <utility>
17
18 #include <boost/array.hpp>
19 #include <boost/assert.hpp>
20 #include <boost/test/unit_test.hpp>
21 #include <boost/utility.hpp>
22
23 #include <boost/context/detail/config.hpp>
24 #include <boost/context/detail/fcontext.hpp>
25
26 template< std::size_t Max, std::size_t Default, std::size_t Min >
27 class simple_stack_allocator
28 {
29 public:
30 static std::size_t maximum_stacksize()
31 { return Max; }
32
33 static std::size_t default_stacksize()
34 { return Default; }
35
36 static std::size_t minimum_stacksize()
37 { return Min; }
38
39 void * allocate( std::size_t size) const
40 {
41 BOOST_ASSERT( minimum_stacksize() <= size);
42 BOOST_ASSERT( maximum_stacksize() >= size);
43
44 void * limit = malloc( size);
45 if ( ! limit) throw std::bad_alloc();
46
47 return static_cast< char * >( limit) + size;
48 }
49
50 void deallocate( void * vp, std::size_t size) const
51 {
52 BOOST_ASSERT( vp);
53 BOOST_ASSERT( minimum_stacksize() <= size);
54 BOOST_ASSERT( maximum_stacksize() >= size);
55
56 void * limit = static_cast< char * >( vp) - size;
57 free( limit);
58 }
59 };
60
61 typedef simple_stack_allocator<
62 8 * 1024 * 1024, 64 * 1024, 8 * 1024
63 > stack_allocator;
64
65 namespace ctx = boost::context::detail;
66
67 typedef simple_stack_allocator<
68 8 * 1024 * 1024, // 8MB
69 64 * 1024, // 64kB
70 8 * 1024 // 8kB
71 > stack_allocator;
72
73 int value1 = 0;
74 std::string value2;
75 double value3 = 0.;
76 void * value4 = 0;
77
78 void f1( ctx::transfer_t t) {
79 ++value1;
80 ctx::jump_fcontext( t.fctx, t.data);
81 }
82
83 void f3( ctx::transfer_t t_) {
84 ++value1;
85 ctx::transfer_t t = ctx::jump_fcontext( t_.fctx, 0);
86 ++value1;
87 ctx::jump_fcontext( t.fctx, t.data);
88 }
89
90 void f4( ctx::transfer_t t) {
91 int i = 7;
92 ctx::jump_fcontext( t.fctx, & i);
93 }
94
95 void f5( ctx::transfer_t t) {
96 ctx::jump_fcontext( t.fctx, t.data);
97 }
98
99 void f6( ctx::transfer_t t_) {
100 std::pair< int, int > data = * ( std::pair< int, int > * ) t_.data;
101 int res = data.first + data.second;
102 ctx::transfer_t t = ctx::jump_fcontext( t_.fctx, & res);
103 data = * ( std::pair< int, int > *) t.data;
104 res = data.first + data.second;
105 ctx::jump_fcontext( t.fctx, & res);
106 }
107
108 void f7( ctx::transfer_t t) {
109 try {
110 throw std::runtime_error( * ( std::string *) t.data);
111 } catch ( std::runtime_error const& e) {
112 value2 = e.what();
113 }
114 ctx::jump_fcontext( t.fctx, t.data);
115 }
116
117 void f8( ctx::transfer_t t) {
118 double d = * ( double *) t.data;
119 d += 3.45;
120 value3 = d;
121 ctx::jump_fcontext( t.fctx, 0);
122 }
123
124 void f10( ctx::transfer_t t) {
125 value1 = 3;
126 ctx::jump_fcontext( t.fctx, 0);
127 }
128
129 void f9( ctx::transfer_t t) {
130 std::cout << "f1: entered" << std::endl;
131 stack_allocator alloc;
132 void * sp = alloc.allocate( stack_allocator::default_stacksize());
133 ctx::fcontext_t ctx = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f10);
134 ctx::jump_fcontext( ctx, 0);
135 ctx::jump_fcontext( t.fctx, 0);
136 }
137
138 ctx::transfer_t f11( ctx::transfer_t t_) {
139 value4 = t_.data;
140 ctx::transfer_t t = { t_.fctx, t_.data };
141 return t;
142 }
143
144 void f12( ctx::transfer_t t_) {
145 ctx::transfer_t t = ctx::jump_fcontext( t_.fctx, t_.data);
146 value1 = * ( int *) t.data;
147 ctx::jump_fcontext( t.fctx, t.data);
148 }
149
150 void f13( ctx::transfer_t t) {
151 {
152 double n1 = 0;
153 double n2 = 0;
154 sscanf("3.14 7.13", "%lf %lf", & n1, & n2);
155 BOOST_CHECK( n1 == 3.14);
156 BOOST_CHECK( n2 == 7.13);
157 }
158 {
159 int n1=0;
160 int n2=0;
161 sscanf("1 23", "%d %d", & n1, & n2);
162 BOOST_CHECK( n1 == 1);
163 BOOST_CHECK( n2 == 23);
164 }
165 {
166 int n1=0;
167 int n2=0;
168 sscanf("1 jjj 23", "%d %*[j] %d", & n1, & n2);
169 BOOST_CHECK( n1 == 1);
170 BOOST_CHECK( n2 == 23);
171 }
172 ctx::jump_fcontext( t.fctx, 0);
173 }
174
175 void f14( ctx::transfer_t t) {
176 {
177 const char *fmt = "sqrt(2) = %f";
178 char buf[15];
179 snprintf( buf, sizeof( buf), fmt, std::sqrt( 2) );
180 BOOST_CHECK( 0 < sizeof( buf) );
181 BOOST_CHECK_EQUAL( std::string("sqrt(2) = 1.41"), std::string( buf, 14) );
182 }
183 {
184 std::uint64_t n = 0xbcdef1234567890;
185 const char *fmt = "0x%016llX";
186 char buf[100];
187 snprintf( buf, sizeof( buf), fmt, n);
188 BOOST_CHECK_EQUAL( std::string("0x0BCDEF1234567890"), std::string( buf, 18) );
189 }
190 ctx::jump_fcontext( t.fctx, 0);
191 }
192
193 void test_setup() {
194 stack_allocator alloc;
195 void * sp = alloc.allocate( stack_allocator::default_stacksize() );
196 ctx::fcontext_t ctx = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f1);
197 BOOST_CHECK( ctx);
198 alloc.deallocate( sp, stack_allocator::default_stacksize() );
199 }
200
201 void test_start() {
202 value1 = 0;
203 stack_allocator alloc;
204 void * sp = alloc.allocate( stack_allocator::default_stacksize() );
205 ctx::fcontext_t ctx = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f1);
206 BOOST_CHECK( ctx);
207
208 BOOST_CHECK_EQUAL( 0, value1);
209 ctx::jump_fcontext( ctx, 0);
210 BOOST_CHECK_EQUAL( 1, value1);
211 alloc.deallocate( sp, stack_allocator::default_stacksize() );
212 }
213
214 void test_jump() {
215 value1 = 0;
216 stack_allocator alloc;
217 void * sp = alloc.allocate( stack_allocator::default_stacksize() );
218 ctx::fcontext_t ctx = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f3);
219 BOOST_CHECK( ctx);
220 BOOST_CHECK_EQUAL( 0, value1);
221 ctx::transfer_t t = ctx::jump_fcontext( ctx, 0);
222 BOOST_CHECK_EQUAL( 1, value1);
223 ctx::jump_fcontext( t.fctx, 0);
224 BOOST_CHECK_EQUAL( 2, value1);
225 alloc.deallocate( sp, stack_allocator::default_stacksize() );
226 }
227
228 void test_result() {
229 stack_allocator alloc;
230 void * sp = alloc.allocate( stack_allocator::default_stacksize() );
231 ctx::fcontext_t ctx = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f4);
232 BOOST_CHECK( ctx);
233 ctx::transfer_t t = ctx::jump_fcontext( ctx, 0);
234 int result = * ( int *) t.data;
235 BOOST_CHECK_EQUAL( 7, result);
236 alloc.deallocate( sp, stack_allocator::default_stacksize() );
237 }
238
239 void test_arg() {
240 stack_allocator alloc;
241 int i = 7;
242 void * sp = alloc.allocate( stack_allocator::default_stacksize() );
243 ctx::fcontext_t ctx = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f5);
244 BOOST_CHECK( ctx);
245 ctx::transfer_t t = ctx::jump_fcontext( ctx, & i);
246 int result = * ( int *) t.data;
247 BOOST_CHECK_EQUAL( i, result);
248 alloc.deallocate( sp, stack_allocator::default_stacksize() );
249 }
250
251 void test_transfer() {
252 stack_allocator alloc;
253 std::pair< int, int > data = std::make_pair( 3, 7);
254 void * sp = alloc.allocate( stack_allocator::default_stacksize() );
255 ctx::fcontext_t ctx = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f6);
256 BOOST_CHECK( ctx);
257 ctx::transfer_t t = ctx::jump_fcontext( ctx, & data);
258 int result = * ( int *) t.data;
259 BOOST_CHECK_EQUAL( 10, result);
260 data = std::make_pair( 7, 7);
261 t = ctx::jump_fcontext( t.fctx, & data);
262 result = * ( int *) t.data;
263 BOOST_CHECK_EQUAL( 14, result);
264 alloc.deallocate( sp, stack_allocator::default_stacksize() );
265 }
266
267 void test_exception() {
268 stack_allocator alloc;
269 std::string what("hello world");
270 void * sp = alloc.allocate( stack_allocator::default_stacksize() );
271 ctx::fcontext_t ctx = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f7);
272 BOOST_CHECK( ctx);
273 ctx::jump_fcontext( ctx, & what);
274 BOOST_CHECK_EQUAL( std::string( what), value2);
275 alloc.deallocate( sp, stack_allocator::default_stacksize() );
276 }
277
278 void test_fp() {
279 stack_allocator alloc;
280 double d = 7.13;
281 void * sp = alloc.allocate( stack_allocator::default_stacksize() );
282 ctx::fcontext_t ctx = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f8);
283 BOOST_CHECK( ctx);
284 ctx::jump_fcontext( ctx, & d);
285 BOOST_CHECK_EQUAL( 10.58, value3);
286 alloc.deallocate( sp, stack_allocator::default_stacksize() );
287 }
288
289 void test_stacked() {
290 value1 = 0;
291 stack_allocator alloc;
292 void * sp = alloc.allocate( stack_allocator::default_stacksize());
293 ctx::fcontext_t ctx = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f9);
294 ctx::jump_fcontext( ctx, 0);
295 BOOST_CHECK_EQUAL( 3, value1);
296 alloc.deallocate( sp, stack_allocator::default_stacksize() );
297 }
298
299 void test_ontop() {
300 value1 = 0;
301 value4 = 0;
302 stack_allocator alloc;
303 void * sp = alloc.allocate( stack_allocator::default_stacksize() );
304 ctx::fcontext_t ctx = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f12);
305 BOOST_CHECK( ctx);
306 ctx::transfer_t t = ctx::jump_fcontext( ctx, 0);
307 BOOST_CHECK_EQUAL( 0, value1);
308 BOOST_CHECK( 0 == value4);
309 int i = -3;
310 t = ctx::ontop_fcontext( t.fctx, & i, f11);
311 BOOST_CHECK_EQUAL( -3, value1);
312 BOOST_CHECK_EQUAL( & i, value4);
313 BOOST_CHECK_EQUAL( -3, * ( int *) t.data);
314 BOOST_CHECK_EQUAL( & i, ( int *) t.data);
315 alloc.deallocate( sp, stack_allocator::default_stacksize() );
316 }
317
318 void test_sscanf() {
319 stack_allocator alloc;
320 void * sp = alloc.allocate( stack_allocator::default_stacksize() );
321 ctx::fcontext_t ctx = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f13);
322 BOOST_CHECK( ctx);
323 ctx::jump_fcontext( ctx, 0);
324 alloc.deallocate( sp, stack_allocator::default_stacksize() );
325 }
326
327 void test_snprintf() {
328 stack_allocator alloc;
329 void * sp = alloc.allocate( stack_allocator::default_stacksize() );
330 ctx::fcontext_t ctx = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f14);
331 ctx::jump_fcontext( ctx, 0);
332 alloc.deallocate( sp, stack_allocator::default_stacksize() );
333 }
334
335 boost::unit_test::test_suite * init_unit_test_suite( int, char* []) {
336 boost::unit_test::test_suite * test =
337 BOOST_TEST_SUITE("Boost.Context: context test suite");
338 test->add( BOOST_TEST_CASE( & test_setup) );
339 test->add( BOOST_TEST_CASE( & test_start) );
340 test->add( BOOST_TEST_CASE( & test_jump) );
341 test->add( BOOST_TEST_CASE( & test_result) );
342 test->add( BOOST_TEST_CASE( & test_arg) );
343 test->add( BOOST_TEST_CASE( & test_transfer) );
344 test->add( BOOST_TEST_CASE( & test_exception) );
345 test->add( BOOST_TEST_CASE( & test_fp) );
346 test->add( BOOST_TEST_CASE( & test_stacked) );
347 test->add( BOOST_TEST_CASE( & test_ontop) );
348 test->add( BOOST_TEST_CASE( & test_sscanf) );
349 test->add( BOOST_TEST_CASE( & test_snprintf) );
350
351 return test;
352 }