libcopp  2.2.0
stack_pool_test.cpp
Go to the documentation of this file.
1 // Copyright 2023 owent
2 
4 #include <libcotask/task.h>
5 
6 #include <cstdio>
7 #include <cstring>
8 #include <iostream>
9 #include <vector>
10 
11 #include "frame/test_macros.h"
12 
13 typedef copp::stack_pool<copp::allocator::stack_allocator_malloc> stack_pool_t;
15  using stack_allocator_type = copp::allocator::stack_allocator_pool<stack_pool_t>;
16  using coroutine_type = copp::coroutine_context_container<stack_allocator_type>;
17  using value_type = int;
18 };
19 static stack_pool_t::ptr_t global_stack_pool;
20 
21 typedef cotask::task<stack_pool_test_macro_coroutine> stack_pool_test_task_t;
22 
23 static int stack_pool_test_task_action(void *) { return 0; }
24 
25 CASE_TEST(stack_pool_test, stack_context) {
26  copp::stack_context ctx;
27  CASE_EXPECT_EQ(nullptr, ctx.sp);
28  CASE_EXPECT_EQ(0, ctx.size);
29 
30  unsigned char test_buffer[256];
31  ctx.sp = reinterpret_cast<void *>(test_buffer + 256);
32  ctx.size = sizeof(test_buffer);
33  ctx.reset();
34 
35  CASE_EXPECT_EQ(nullptr, ctx.sp);
36  CASE_EXPECT_EQ(0, ctx.size);
37 }
38 
39 CASE_TEST(stack_pool_test, basic) {
40  global_stack_pool = stack_pool_t::create();
41  std::vector<stack_pool_test_task_t::ptr_t> task_arr;
42  const size_t task_arr_sz = 64;
43 
44  // alloc
45  for (size_t i = 0; i < task_arr_sz; ++i) {
46  copp::allocator::stack_allocator_pool<stack_pool_t> alloc(global_stack_pool);
47  stack_pool_test_task_t::ptr_t tp = stack_pool_test_task_t::create(stack_pool_test_task_action, alloc);
48  task_arr.push_back(tp);
49  }
50  CASE_EXPECT_EQ(task_arr_sz, global_stack_pool->get_limit().used_stack_number);
51  CASE_EXPECT_EQ(task_arr_sz * (global_stack_pool->get_stack_size() + global_stack_pool->get_stack_size_offset()),
52  global_stack_pool->get_limit().used_stack_size);
53 
54  CASE_EXPECT_EQ(0, global_stack_pool->get_limit().free_stack_number);
55  CASE_EXPECT_EQ(0, global_stack_pool->get_limit().free_stack_size);
56 
57  // recycle to free list
58  for (size_t i = 0; i < task_arr_sz / 2; ++i) {
59  task_arr.pop_back();
60  }
61  CASE_EXPECT_EQ(task_arr_sz - task_arr_sz / 2, global_stack_pool->get_limit().used_stack_number);
62  CASE_EXPECT_EQ(task_arr_sz / 2, global_stack_pool->get_limit().free_stack_number);
63  CASE_EXPECT_EQ((task_arr_sz - task_arr_sz / 2) *
64  (global_stack_pool->get_stack_size() + global_stack_pool->get_stack_size_offset()),
65  global_stack_pool->get_limit().used_stack_size);
66  CASE_EXPECT_EQ((task_arr_sz / 2) * (global_stack_pool->get_stack_size() + global_stack_pool->get_stack_size_offset()),
67  global_stack_pool->get_limit().free_stack_size);
68 
69  // auto_gc
70  task_arr.pop_back();
71  CASE_EXPECT_EQ(task_arr_sz / 4, global_stack_pool->get_limit().free_stack_number);
72  CASE_EXPECT_EQ((task_arr_sz / 4) * (global_stack_pool->get_stack_size() + global_stack_pool->get_stack_size_offset()),
73  global_stack_pool->get_limit().free_stack_size);
74 
75  global_stack_pool.reset();
76 }
77 
78 CASE_TEST(stack_pool_test, full_number) {
79  global_stack_pool = stack_pool_t::create();
80  // full
81 
82  std::vector<stack_pool_test_task_t::ptr_t> task_arr;
83  const size_t task_arr_sz = 64;
84  global_stack_pool->set_max_stack_number(task_arr_sz);
85  // alloc
86  for (size_t i = 0; i < task_arr_sz; ++i) {
87  copp::allocator::stack_allocator_pool<stack_pool_t> alloc(global_stack_pool);
88  stack_pool_test_task_t::ptr_t tp = stack_pool_test_task_t::create(stack_pool_test_task_action, alloc);
89  CASE_EXPECT_TRUE(!!tp);
90  task_arr.push_back(tp);
91  }
92 
93  {
94  copp::allocator::stack_allocator_pool<stack_pool_t> alloc(global_stack_pool);
95  stack_pool_test_task_t::ptr_t tp = stack_pool_test_task_t::create(stack_pool_test_task_action, alloc);
96  CASE_EXPECT_TRUE(!tp);
97  }
98 
99  global_stack_pool.reset();
100 }
101 
102 CASE_TEST(stack_pool_test, custom_gc) {
103  global_stack_pool = stack_pool_t::create();
104  std::vector<stack_pool_test_task_t::ptr_t> task_arr;
105  const size_t task_arr_sz = 64;
106 
107  global_stack_pool->set_min_stack_number(task_arr_sz);
108 
109  // alloc
110  for (size_t i = 0; i < task_arr_sz; ++i) {
111  copp::allocator::stack_allocator_pool<stack_pool_t> alloc(global_stack_pool);
112  stack_pool_test_task_t::ptr_t tp = stack_pool_test_task_t::create(stack_pool_test_task_action, alloc);
113  task_arr.push_back(tp);
114  }
115 
116  CASE_EXPECT_EQ(task_arr_sz, global_stack_pool->get_limit().used_stack_number);
117  CASE_EXPECT_EQ(task_arr_sz * (global_stack_pool->get_stack_size() + global_stack_pool->get_stack_size_offset()),
118  global_stack_pool->get_limit().used_stack_size);
119 
120  CASE_EXPECT_EQ(0, global_stack_pool->get_limit().free_stack_number);
121  CASE_EXPECT_EQ(0, global_stack_pool->get_limit().free_stack_size);
122 
123  for (size_t i = 0; i < task_arr_sz; ++i) {
124  task_arr.pop_back();
125  }
126 
127  CASE_EXPECT_EQ(0, global_stack_pool->get_limit().used_stack_number);
128  CASE_EXPECT_EQ(0, global_stack_pool->get_limit().used_stack_size);
129 
130  CASE_EXPECT_EQ(task_arr_sz, global_stack_pool->get_limit().free_stack_number);
131  CASE_EXPECT_EQ(task_arr_sz * (global_stack_pool->get_stack_size() + global_stack_pool->get_stack_size_offset()),
132  global_stack_pool->get_limit().free_stack_size);
133 
134  global_stack_pool->set_min_stack_number(0);
135  global_stack_pool.reset();
136 }
137 
138 CASE_TEST(stack_pool_test, gc_once) {
139  global_stack_pool = stack_pool_t::create();
140  // gc_once
141  std::vector<stack_pool_test_task_t::ptr_t> task_arr;
142  const size_t task_arr_sz = 64;
143 
144  global_stack_pool->set_auto_gc(false);
145  global_stack_pool->set_gc_once_number(10);
146 
147  // alloc
148  for (size_t i = 0; i < task_arr_sz; ++i) {
149  copp::allocator::stack_allocator_pool<stack_pool_t> alloc(global_stack_pool);
150  stack_pool_test_task_t::ptr_t tp = stack_pool_test_task_t::create(stack_pool_test_task_action, alloc);
151  task_arr.push_back(tp);
152  }
153 
154  CASE_EXPECT_EQ(task_arr_sz, global_stack_pool->get_limit().used_stack_number);
155  CASE_EXPECT_EQ(task_arr_sz * (global_stack_pool->get_stack_size() + global_stack_pool->get_stack_size_offset()),
156  global_stack_pool->get_limit().used_stack_size);
157 
158  CASE_EXPECT_EQ(0, global_stack_pool->get_limit().free_stack_number);
159  CASE_EXPECT_EQ(0, global_stack_pool->get_limit().free_stack_size);
160 
161  for (size_t i = 0; i < task_arr_sz; ++i) {
162  task_arr.pop_back();
163  }
164 
165  CASE_EXPECT_EQ(0, global_stack_pool->get_limit().used_stack_number);
166  CASE_EXPECT_EQ(0, global_stack_pool->get_limit().used_stack_size);
167 
168  CASE_EXPECT_EQ(task_arr_sz, global_stack_pool->get_limit().free_stack_number);
169  CASE_EXPECT_EQ(task_arr_sz * (global_stack_pool->get_stack_size() + global_stack_pool->get_stack_size_offset()),
170  global_stack_pool->get_limit().free_stack_size);
171 
172  global_stack_pool->gc();
173 
174  CASE_EXPECT_EQ(task_arr_sz - 10, global_stack_pool->get_limit().free_stack_number);
176  (task_arr_sz - 10) * (global_stack_pool->get_stack_size() + global_stack_pool->get_stack_size_offset()),
177  global_stack_pool->get_limit().free_stack_size);
178 
179  global_stack_pool.reset();
180 }
181 
182 CASE_TEST(stack_pool_test, full_size) {
183  global_stack_pool = stack_pool_t::create();
184  // full size
185 
186  std::vector<stack_pool_test_task_t::ptr_t> task_arr;
187  stack_pool_test_task_t::ptr_t tp1;
188  stack_pool_test_task_t::ptr_t tp2;
189 
190  global_stack_pool->set_max_stack_size(128 * 1024);
191  global_stack_pool->set_stack_size(100 * 1024);
192  // alloc
193  copp::allocator::stack_allocator_pool<stack_pool_t> alloc1(global_stack_pool);
194  copp::allocator::stack_allocator_pool<stack_pool_t> alloc2(global_stack_pool);
195  tp1 = stack_pool_test_task_t::create(stack_pool_test_task_action, alloc1);
196  CASE_EXPECT_TRUE(!!tp1);
197 
198  tp2 = stack_pool_test_task_t::create(stack_pool_test_task_action, alloc2);
199  CASE_EXPECT_TRUE(!tp2);
200 
201  global_stack_pool.reset();
202 }
static stack_pool_t::ptr_t global_stack_pool
copp::stack_pool< copp::allocator::stack_allocator_malloc > stack_pool_t
cotask::task< stack_pool_test_macro_coroutine > stack_pool_test_task_t
static int stack_pool_test_task_action(void *)
CASE_TEST(stack_pool_test, stack_context)
copp::coroutine_context_container< stack_allocator_type > coroutine_type
copp::allocator::stack_allocator_pool< stack_pool_t > stack_allocator_type
#define CASE_EXPECT_EQ(l, r)
Definition: test_macros.h:96
#define CASE_EXPECT_TRUE(c)
Definition: test_macros.h:94