libcopp  2.2.0
sample_linux_gcc_splited_segment.cpp
Go to the documentation of this file.
1 /*
2  * sample_default_manager.cpp
3  *
4  * Created on: 2014年3月17日
5  * Author: owent
6  *
7  * Released under the MIT license
8  */
9 
10 #include <inttypes.h>
11 #include <stdint.h>
12 #include <algorithm>
13 #include <cstdio>
14 #include <cstring>
15 #include <iostream>
16 #include <limits>
17 
18 // include manager header file
20 
21 #ifdef LIBCOPP_MACRO_USE_SEGMENTED_STACKS
22 
23 typedef copp::coroutine_context_container<copp::allocator::stack_allocator_split_segment> co_context_t;
24 
25 // define a coroutine runner
26 class my_runner {
27  public:
28  bool is_running_;
29  intptr_t min_;
30  intptr_t max_;
31 
32  private:
33  void loop(int times) {
34  char buffer[64 * 1024] = {0};
35  co_context_t *pco = copp::this_coroutine::get<co_context_t>();
36 
37  std::cout << "context " << pco << " => buffer start addr " << reinterpret_cast<void *>(buffer) << ", end addr "
38  << reinterpret_cast<void *>(buffer + sizeof(buffer)) << "." << std::endl;
39 
40  min_ = std::min<intptr_t>(min_, (intptr_t)buffer);
41  max_ = std::max<intptr_t>(max_, (intptr_t)(buffer + sizeof(buffer)));
42  pco->yield();
43  if (times > 0) {
44  loop(times - 1);
45  }
46 
47  is_running_ = false;
48  }
49 
50  public:
51  int operator()(void *) {
52  // test split stack(64MB of stack)
53  is_running_ = true;
54  min_ = std::numeric_limits<intptr_t>::max();
55  max_ = std::numeric_limits<intptr_t>::min();
56  loop(64 * 16);
57  // action code here ...
58  return 1;
59  }
60 };
61 
62 int main() {
63  // create a runner
64  my_runner runner1, runner2;
65 
66  {
67  // create coroutines
68  co_context_t::ptr_t co_obj1 = co_context_t::create(&runner1, 32 * 1024);
69  co_context_t::ptr_t co_obj2 = co_context_t::create(&runner2, 32 * 1024);
70  std::cout << "cortoutine " << co_obj1.get() << " created.\n" << std::endl;
71  std::cout << "cortoutine " << co_obj2.get() << " created.\n" << std::endl;
72 
73  // start a coroutine
74  co_obj1->start();
75  co_obj2->start();
76 
77  while (runner1.is_running_ || runner2.is_running_) {
78  if (runner1.is_running_) {
79  co_obj1->resume();
80  }
81 
82  if (runner2.is_running_) {
83  co_obj2->resume();
84  }
85  }
86 
87  // print stack distance
88  std::cout << "co_obj1 stack min addr " << runner1.min_ << ", max addr " << runner1.max_ << ". dis "
89  << ((runner1.max_ - runner1.min_) / 1024) << "KB." << std::endl;
90  std::cout << "co_obj2 stack min addr " << runner2.min_ << ", max addr " << runner2.max_ << ". dis "
91  << ((runner2.max_ - runner2.min_) / 1024) << "KB." << std::endl;
92 
93  puts("all jobs done.");
94  }
95  return 0;
96 }
97 
98 #else
99 int main() {
100  puts("split stack disabled.");
101  return 0;
102 }
103 #endif