]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/context/test/test_fcontext.cpp
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)
18 #include <boost/array.hpp>
19 #include <boost/assert.hpp>
20 #include <boost/test/unit_test.hpp>
21 #include <boost/utility.hpp>
23 #include <boost/context/detail/config.hpp>
24 #include <boost/context/detail/fcontext.hpp>
26 template< std::size_t Max
, std::size_t Default
, std::size_t Min
>
27 class simple_stack_allocator
30 static std::size_t maximum_stacksize()
33 static std::size_t default_stacksize()
36 static std::size_t minimum_stacksize()
39 void * allocate( std::size_t size
) const
41 BOOST_ASSERT( minimum_stacksize() <= size
);
42 BOOST_ASSERT( maximum_stacksize() >= size
);
44 void * limit
= malloc( size
);
45 if ( ! limit
) throw std::bad_alloc();
47 return static_cast< char * >( limit
) + size
;
50 void deallocate( void * vp
, std::size_t size
) const
53 BOOST_ASSERT( minimum_stacksize() <= size
);
54 BOOST_ASSERT( maximum_stacksize() >= size
);
56 void * limit
= static_cast< char * >( vp
) - size
;
61 typedef simple_stack_allocator
<
62 8 * 1024 * 1024, 64 * 1024, 8 * 1024
65 namespace ctx
= boost::context::detail
;
67 typedef simple_stack_allocator
<
68 8 * 1024 * 1024, // 8MB
78 void f1( ctx::transfer_t t
) {
80 ctx::jump_fcontext( t
.fctx
, t
.data
);
83 void f3( ctx::transfer_t t_
) {
85 ctx::transfer_t t
= ctx::jump_fcontext( t_
.fctx
, 0);
87 ctx::jump_fcontext( t
.fctx
, t
.data
);
90 void f4( ctx::transfer_t t
) {
92 ctx::jump_fcontext( t
.fctx
, & i
);
95 void f5( ctx::transfer_t t
) {
96 ctx::jump_fcontext( t
.fctx
, t
.data
);
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
);
108 void f7( ctx::transfer_t t
) {
110 throw std::runtime_error( * ( std::string
*) t
.data
);
111 } catch ( std::runtime_error
const& e
) {
114 ctx::jump_fcontext( t
.fctx
, t
.data
);
117 void f8( ctx::transfer_t t
) {
118 double d
= * ( double *) t
.data
;
121 ctx::jump_fcontext( t
.fctx
, 0);
124 void f10( ctx::transfer_t t
) {
126 ctx::jump_fcontext( t
.fctx
, 0);
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);
138 ctx::transfer_t
f11( ctx::transfer_t t_
) {
140 ctx::transfer_t t
= { t_
.fctx
, t_
.data
};
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
);
150 void f13( ctx::transfer_t t
) {
154 sscanf("3.14 7.13", "%lf %lf", & n1
, & n2
);
155 BOOST_CHECK( n1
== 3.14);
156 BOOST_CHECK( n2
== 7.13);
161 sscanf("1 23", "%d %d", & n1
, & n2
);
162 BOOST_CHECK( n1
== 1);
163 BOOST_CHECK( n2
== 23);
168 sscanf("1 jjj 23", "%d %*[j] %d", & n1
, & n2
);
169 BOOST_CHECK( n1
== 1);
170 BOOST_CHECK( n2
== 23);
172 ctx::jump_fcontext( t
.fctx
, 0);
175 void f14( ctx::transfer_t t
) {
177 const char *fmt
= "sqrt(2) = %f";
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) );
184 std::uint64_t n
= 0xbcdef1234567890;
185 const char *fmt
= "0x%016llX";
187 snprintf( buf
, sizeof( buf
), fmt
, n
);
188 BOOST_CHECK_EQUAL( std::string("0x0BCDEF1234567890"), std::string( buf
, 18) );
190 ctx::jump_fcontext( t
.fctx
, 0);
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
);
198 alloc
.deallocate( sp
, stack_allocator::default_stacksize() );
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
);
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() );
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
);
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() );
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
);
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() );
240 stack_allocator alloc
;
242 void * sp
= alloc
.allocate( stack_allocator::default_stacksize() );
243 ctx::fcontext_t ctx
= ctx::make_fcontext( sp
, stack_allocator::default_stacksize(), f5
);
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() );
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
);
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() );
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
);
273 ctx::jump_fcontext( ctx
, & what
);
274 BOOST_CHECK_EQUAL( std::string( what
), value2
);
275 alloc
.deallocate( sp
, stack_allocator::default_stacksize() );
279 stack_allocator alloc
;
281 void * sp
= alloc
.allocate( stack_allocator::default_stacksize() );
282 ctx::fcontext_t ctx
= ctx::make_fcontext( sp
, stack_allocator::default_stacksize(), f8
);
284 ctx::jump_fcontext( ctx
, & d
);
285 BOOST_CHECK_EQUAL( 10.58, value3
);
286 alloc
.deallocate( sp
, stack_allocator::default_stacksize() );
289 void test_stacked() {
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() );
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
);
306 ctx::transfer_t t
= ctx::jump_fcontext( ctx
, 0);
307 BOOST_CHECK_EQUAL( 0, value1
);
308 BOOST_CHECK( 0 == value4
);
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() );
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
);
323 ctx::jump_fcontext( ctx
, 0);
324 alloc
.deallocate( sp
, stack_allocator::default_stacksize() );
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() );
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: fcontext 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
) );