libcopp 2.3.1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
13typedef 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};
19static stack_pool_t::ptr_t global_stack_pool;
20
21typedef cotask::task<stack_pool_test_macro_coroutine> stack_pool_test_task_t;
22
23static int stack_pool_test_task_action(void *) { return 0; }
24
25CASE_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
39CASE_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
78CASE_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);
97 }
98
99 global_stack_pool.reset();
100}
101
102CASE_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
138CASE_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
182CASE_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 *)
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:99
#define CASE_TEST(test_name, case_name)
Definition test_macros.h:47
#define CASE_EXPECT_TRUE(c)
Definition test_macros.h:97