113 {
114 log_module::write_information("\n=== Concurrent Usage Demo ===");
115
116 constexpr int NUM_THREADS = 4;
117 constexpr int OPERATIONS_PER_THREAD = 1000;
118 constexpr int INITIAL_CHUNKS = 2;
119 constexpr int CHUNK_SIZE = 256;
120
121 node_pool<TestData> pool(INITIAL_CHUNKS, CHUNK_SIZE);
122
123 std::atomic<int> total_allocations{0};
124 std::atomic<int> total_deallocations{0};
125 std::atomic<int> allocation_failures{0};
126
127 auto start_time = std::chrono::high_resolution_clock::now();
128
129 std::vector<std::thread> threads;
130 threads.reserve(NUM_THREADS);
131
132
133 for (int thread_id = 0; thread_id < NUM_THREADS; ++thread_id) {
134 threads.emplace_back([&, thread_id]() {
135 std::random_device rd;
136 std::mt19937 gen(rd());
137 std::uniform_int_distribution<> dis(0, 100);
138
139 std::vector<TestData*> local_nodes;
140 local_nodes.reserve(OPERATIONS_PER_THREAD / 2);
141
142 for (int op = 0; op < OPERATIONS_PER_THREAD; ++op) {
143 if (dis(gen) < 70 || local_nodes.empty()) {
144 try {
145 auto* node = pool.allocate();
146 node->value = thread_id * 10000 + op;
147 node->data = thread_id + op * 0.001;
148 local_nodes.push_back(node);
149 total_allocations.fetch_add(1, std::memory_order_relaxed);
150 } catch (const std::bad_alloc&) {
151 allocation_failures.fetch_add(1, std::memory_order_relaxed);
152 }
153 } else {
154 if (!local_nodes.empty()) {
155 auto idx = std::uniform_int_distribution<size_t>(0, local_nodes.size() - 1)(gen);
156 pool.deallocate(local_nodes[idx]);
157 local_nodes.erase(local_nodes.begin() + idx);
158 total_deallocations.fetch_add(1, std::memory_order_relaxed);
159 }
160 }
161 }
162
163
164 for (auto* node : local_nodes) {
165 if (node) {
166 pool.deallocate(node);
167 total_deallocations.fetch_add(1, std::memory_order_relaxed);
168 }
169 }
170 });
171 }
172
173
174 for (auto& thread : threads) {
175 thread.join();
176 }
177
178 auto end_time = std::chrono::high_resolution_clock::now();
179 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
180
181 log_module::write_information("Concurrent operations completed in {} ms", duration.count());
182 log_module::write_information("Total allocations: {}", total_allocations.load());
183 log_module::write_information("Total deallocations: {}", total_deallocations.load());
184 log_module::write_information("Allocation failures: {}", allocation_failures.load());
185
186
187 auto stats = pool.get_statistics();
188 log_module::write_information("Final pool statistics:");
189 log_module::write_information(" Total chunks: {}", stats.total_chunks);
190 log_module::write_information(" Total nodes: {}", stats.total_nodes);
191 log_module::write_information(" Allocated nodes: {}", stats.allocated_nodes);
192 log_module::write_information(" Free list size: {}", stats.free_list_size);
193
194
195 int total_ops = total_allocations.load() + total_deallocations.load();
196 double ops_per_second = (double)total_ops / (duration.count() / 1000.0);
197 log_module::write_information("Performance: {} ops/second", static_cast<int>(ops_per_second));
198}