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 <sstream>
9 #include <stdexcept>
10 #include <string>
11 #include <utility>
12
13 #include <boost/array.hpp>
14 #include <boost/assert.hpp>
15 #include <boost/test/unit_test.hpp>
16 #include <boost/utility.hpp>
17
18 #include <boost/context/all.hpp>
19 #include <boost/context/detail/config.hpp>
20
21 #include "../example/simple_stack_allocator.hpp"
22
23 namespace ctx = boost::context;
24
25 typedef ctx::simple_stack_allocator<
26 8 * 1024 * 1024, // 8MB
27 64 * 1024, // 64kB
28 8 * 1024 // 8kB
29 > stack_allocator;
30
31 ctx::fcontext_t fcm = 0;
32 ctx::fcontext_t fc = 0;
33 ctx::fcontext_t fc1 = 0;
34 ctx::fcontext_t fc2 = 0;
35 int value1 = 0;
36 std::string value2;
37 double value3 = 0.;
38
f1(intptr_t)39 void f1( intptr_t)
40 {
41 ++value1;
42 ctx::jump_fcontext( & fc, fcm, 0);
43 }
44
f3(intptr_t)45 void f3( intptr_t)
46 {
47 ++value1;
48 ctx::jump_fcontext( & fc, fcm, 0);
49 ++value1;
50 ctx::jump_fcontext( & fc, fcm, 0);
51 }
52
f4(intptr_t)53 void f4( intptr_t)
54 {
55 ctx::jump_fcontext( & fc, fcm, 7);
56 }
57
f5(intptr_t arg)58 void f5( intptr_t arg)
59 {
60 ctx::jump_fcontext( & fc, fcm, arg);
61 }
62
f6(intptr_t arg)63 void f6( intptr_t arg)
64 {
65 std::pair< int, int > data = * ( std::pair< int, int > * ) arg;
66 int res = data.first + data.second;
67 data = * ( std::pair< int, int > *)
68 ctx::jump_fcontext( & fc, fcm, ( intptr_t) res);
69 res = data.first + data.second;
70 ctx::jump_fcontext( & fc, fcm, ( intptr_t) res);
71 }
72
f7(intptr_t arg)73 void f7( intptr_t arg)
74 {
75 try
76 { throw std::runtime_error( ( char *) arg); }
77 catch ( std::runtime_error const& e)
78 { value2 = e.what(); }
79 ctx::jump_fcontext( & fc, fcm, arg);
80 }
81
f8(intptr_t arg)82 void f8( intptr_t arg)
83 {
84 double d = * ( double *) arg;
85 d += 3.45;
86 value3 = d;
87 ctx::jump_fcontext( & fc, fcm, 0);
88 }
89
f10(intptr_t)90 void f10( intptr_t)
91 {
92 value1 = 3;
93 ctx::jump_fcontext( & fc2, fc1, 0);
94 }
95
f9(intptr_t)96 void f9( intptr_t)
97 {
98 std::cout << "f1: entered" << std::endl;
99
100 stack_allocator alloc;
101 void * sp = alloc.allocate( stack_allocator::default_stacksize());
102 fc2 = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f10);
103 ctx::jump_fcontext( & fc1, fc2, 0);
104 ctx::jump_fcontext( & fc1, fcm, 0);
105 }
106
test_setup()107 void test_setup()
108 {
109 stack_allocator alloc;
110
111 void * sp = alloc.allocate( stack_allocator::minimum_stacksize() );
112 fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f1);
113 BOOST_CHECK( fc);
114 }
115
test_start()116 void test_start()
117 {
118 value1 = 0;
119
120 stack_allocator alloc;
121
122 void * sp = alloc.allocate( stack_allocator::minimum_stacksize() );
123 fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f1);
124 BOOST_CHECK( fc);
125
126 BOOST_CHECK_EQUAL( 0, value1);
127 ctx::jump_fcontext( & fcm, fc, 0);
128 BOOST_CHECK_EQUAL( 1, value1);
129 }
130
test_jump()131 void test_jump()
132 {
133 value1 = 0;
134
135 stack_allocator alloc;
136
137 void * sp = alloc.allocate( stack_allocator::minimum_stacksize() );
138 fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f3);
139 BOOST_CHECK( fc);
140
141 BOOST_CHECK_EQUAL( 0, value1);
142 ctx::jump_fcontext( & fcm, fc, 0);
143 BOOST_CHECK_EQUAL( 1, value1);
144 ctx::jump_fcontext( & fcm, fc, 0);
145 BOOST_CHECK_EQUAL( 2, value1);
146 }
147
test_result()148 void test_result()
149 {
150 stack_allocator alloc;
151
152 void * sp = alloc.allocate( stack_allocator::minimum_stacksize() );
153 fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f4);
154 BOOST_CHECK( fc);
155
156 int result = ( int) ctx::jump_fcontext( & fcm, fc, 0);
157 BOOST_CHECK_EQUAL( 7, result);
158 }
159
test_arg()160 void test_arg()
161 {
162 stack_allocator alloc;
163
164 int i = 7;
165 void * sp = alloc.allocate( stack_allocator::minimum_stacksize() );
166 fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f5);
167 BOOST_CHECK( fc);
168
169 int result = ( int) ctx::jump_fcontext( & fcm, fc, i);
170 BOOST_CHECK_EQUAL( i, result);
171 }
172
test_transfer()173 void test_transfer()
174 {
175 stack_allocator alloc;
176
177 std::pair< int, int > data = std::make_pair( 3, 7);
178 void * sp = alloc.allocate( stack_allocator::minimum_stacksize() );
179 fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f6);
180 BOOST_CHECK( fc);
181
182 int result = ( int) ctx::jump_fcontext( & fcm, fc, ( intptr_t) & data);
183 BOOST_CHECK_EQUAL( 10, result);
184 data = std::make_pair( 7, 7);
185 result = ( int) ctx::jump_fcontext( & fcm, fc, ( intptr_t) & data);
186 BOOST_CHECK_EQUAL( 14, result);
187 }
188
test_exception()189 void test_exception()
190 {
191 stack_allocator alloc;
192
193 const char * what = "hello world";
194 void * sp = alloc.allocate( stack_allocator::default_stacksize() );
195 fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f7);
196 BOOST_CHECK( fc);
197
198 ctx::jump_fcontext( & fcm, fc, ( intptr_t) what);
199 BOOST_CHECK_EQUAL( std::string( what), value2);
200 }
201
test_fp()202 void test_fp()
203 {
204 stack_allocator alloc;
205
206 double d = 7.13;
207 void * sp = alloc.allocate( stack_allocator::minimum_stacksize() );
208 fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f8);
209 BOOST_CHECK( fc);
210
211 ctx::jump_fcontext( & fcm, fc, (intptr_t) & d);
212 BOOST_CHECK_EQUAL( 10.58, value3);
213 }
214
test_stacked()215 void test_stacked()
216 {
217 value1 = 0;
218 stack_allocator alloc;
219 void * sp = alloc.allocate( stack_allocator::default_stacksize());
220 fc1 = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f9);
221 ctx::jump_fcontext( & fcm, fc1, 0);
222 BOOST_CHECK_EQUAL( 3, value1);
223 }
224
init_unit_test_suite(int,char * [])225 boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
226 {
227 boost::unit_test::test_suite * test =
228 BOOST_TEST_SUITE("Boost.Context: context test suite");
229
230 test->add( BOOST_TEST_CASE( & test_setup) );
231 test->add( BOOST_TEST_CASE( & test_start) );
232 test->add( BOOST_TEST_CASE( & test_jump) );
233 test->add( BOOST_TEST_CASE( & test_result) );
234 test->add( BOOST_TEST_CASE( & test_arg) );
235 test->add( BOOST_TEST_CASE( & test_transfer) );
236 test->add( BOOST_TEST_CASE( & test_exception) );
237 test->add( BOOST_TEST_CASE( & test_fp) );
238 test->add( BOOST_TEST_CASE( & test_stacked) );
239
240 return test;
241 }
242