libcopp  1.1.0
sample_benchmark_task.cpp
Go to the documentation of this file.
1 /*
2  * sample_stress_test_task.cpp
3  *
4  * Created on: 2014年5月11日
5  * Author: owent
6  *
7  * Released under the MIT license
8  */
9 
10 
11 #include <cstdio>
12 #include <cstdlib>
13 #include <cstring>
14 #include <ctime>
15 #include <inttypes.h>
16 #include <stdint.h>
17 #include <vector>
18 
19 // include manager header file
20 #include <libcotask/task.h>
21 
22 #ifdef LIBCOTASK_MACRO_ENABLED
23 
24 #if defined(PROJECT_LIBCOPP_SAMPLE_HAS_CHRONO) && PROJECT_LIBCOPP_SAMPLE_HAS_CHRONO
25 #include <chrono>
26 #define CALC_CLOCK_T std::chrono::system_clock::time_point
27 #define CALC_CLOCK_NOW() std::chrono::system_clock::now()
28 #define CALC_MS_CLOCK(x) static_cast<int>(std::chrono::duration_cast<std::chrono::milliseconds>(x).count())
29 #define CALC_NS_AVG_CLOCK(x, y) static_cast<long long>(std::chrono::duration_cast<std::chrono::nanoseconds>(x).count() / (y ? y : 1))
30 #else
31 #define CALC_CLOCK_T clock_t
32 #define CALC_CLOCK_NOW() clock()
33 #define CALC_MS_CLOCK(x) static_cast<int>((x) / (CLOCKS_PER_SEC / 1000))
34 #define CALC_NS_AVG_CLOCK(x, y) (1000000LL * static_cast<long long>((x) / (CLOCKS_PER_SEC / 1000)) / (y ? y : 1))
35 #endif
36 
38 
39 int switch_count = 100;
40 int max_task_number = 100000; // 协程Task数量
41 std::vector<my_task_t::ptr_t> task_arr;
42 
43 // define a coroutine runner
44 static int my_task_action(void *) {
45  // ... your code here ...
46  int count = switch_count; // 每个task地切换次数
47 
48  while (count-- > 0)
50 
51  return 0;
52 }
53 
54 int main(int argc, char *argv[]) {
55 #ifdef LIBCOPP_MACRO_SYS_POSIX
56  puts("###################### context coroutine (stack using default allocator[mmap]) ###################");
57 #elif defined(LIBCOPP_MACRO_SYS_WIN)
58  puts("###################### context coroutine (stack using default allocator[VirtualAlloc]) ###################");
59 #else
60  puts("###################### context coroutine (stack using default allocator ###################");
61 #endif
62  printf("########## Cmd:");
63  for (int i = 0; i < argc; ++i) {
64  printf(" %s", argv[i]);
65  }
66  puts("");
67 
68  if (argc > 1) {
69  max_task_number = atoi(argv[1]);
70  }
71 
72  if (argc > 2) {
73  switch_count = atoi(argv[2]);
74  }
75 
76  size_t stack_size = 16 * 1024;
77  if (argc > 3) {
78  stack_size = atoi(argv[3]) * 1024;
79  }
80 
81  time_t begin_time = time(NULL);
82  CALC_CLOCK_T begin_clock = CALC_CLOCK_NOW();
83 
84  // create coroutines
85  task_arr.reserve(static_cast<size_t>(max_task_number));
86  while (task_arr.size() < static_cast<size_t>(max_task_number)) {
87  my_task_t::ptr_t new_task = my_task_t::create(my_task_action, stack_size);
88  if (!new_task) {
89  fprintf(stderr, "create coroutine task failed, real size is %d.\n", static_cast<int>(task_arr.size()));
90  fprintf(stderr, "maybe sysconf [vm.max_map_count] extended.\n");
91  max_task_number = static_cast<int>(task_arr.size());
92  break;
93  }
94  task_arr.push_back(new_task);
95  }
96 
97  time_t end_time = time(NULL);
98  CALC_CLOCK_T end_clock = CALC_CLOCK_NOW();
99  printf("create %d task, cost time: %d s, clock time: %d ms, avg: %lld ns\n", max_task_number, static_cast<int>(end_time - begin_time),
100  CALC_MS_CLOCK(end_clock - begin_clock), CALC_NS_AVG_CLOCK(end_clock - begin_clock, max_task_number));
101 
102  begin_time = end_time;
103  begin_clock = end_clock;
104 
105  // start a task
106  for (int i = 0; i < max_task_number; ++i) {
107  task_arr[i]->start();
108  }
109 
110  // yield & resume from runner
111  bool continue_flag = true;
112  long long real_switch_times = static_cast<long long>(0);
113 
114  while (continue_flag) {
115  continue_flag = false;
116  for (int i = 0; i < max_task_number; ++i) {
117  if (false == task_arr[i]->is_completed()) {
118  continue_flag = true;
119  ++real_switch_times;
120  task_arr[i]->resume();
121  }
122  }
123  }
124 
125  end_time = time(NULL);
126  end_clock = CALC_CLOCK_NOW();
127  printf("switch %d tasks %lld times, cost time: %d s, clock time: %d ms, avg: %lld ns\n", max_task_number, real_switch_times,
128  static_cast<int>(end_time - begin_time), CALC_MS_CLOCK(end_clock - begin_clock),
129  CALC_NS_AVG_CLOCK(end_clock - begin_clock, real_switch_times));
130 
131  begin_time = end_time;
132  begin_clock = end_clock;
133 
134  task_arr.clear();
135 
136  end_time = time(NULL);
137  end_clock = CALC_CLOCK_NOW();
138  printf("remove %d tasks, cost time: %d s, clock time: %d ms, avg: %lld ns\n", max_task_number, static_cast<int>(end_time - begin_time),
139  CALC_MS_CLOCK(end_clock - begin_clock), CALC_NS_AVG_CLOCK(end_clock - begin_clock, max_task_number));
140 
141  return 0;
142 }
143 #else
144 int main() {
145  puts("cotask disabled");
146  return 0;
147 }
148 #endif
#define CALC_MS_CLOCK(x)
cotask::task my_task_t
static ptr_t create(const Ty &functor, size_t stack_size=0, size_t private_buffer_size=0)
create task with functor
Definition: task.h:155
#define CALC_CLOCK_NOW()
impl::task_impl * get_task() UTIL_CONFIG_NOEXCEPT
get current running task
Definition: this_task.cpp:15
int main()
#define CALC_CLOCK_T
virtual int yield(void **priv_data)=0
#define CALC_NS_AVG_CLOCK(x, y)