General Purpose library for Freestanding C++ and POSIX systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

802 regels
20 KiB

4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
  1. #include "allocator.hpp"
  2. #include "gp/algorithm/repeat.hpp"
  3. #include "gp/algorithm/rotate.hpp"
  4. #include "gp/algorithm/move.hpp"
  5. #include "gp/allocator/aggregator.hpp"
  6. #include "gp/allocator/arena.hpp"
  7. #include "gp/allocator/buddy.hpp"
  8. #include "gp/allocator/dummy.hpp"
  9. #include "gp/array.hpp"
  10. #include "gp/bitops.hpp"
  11. #include "gp/indexed_array.hpp"
  12. #include "gp/ring_list.hpp"
  13. #include "test_scaffold.h"
  14. #include <algorithm>
  15. #include <chrono>
  16. #include <fstream>
  17. #include <iomanip>
  18. #include <iostream>
  19. #include <numeric>
  20. #include <random>
  21. #include <set>
  22. #include <stack>
  23. #include <thread>
  24. #ifndef FUZZ_STRENGTH
  25. #define FUZZ_STRENGTH 2048
  26. #endif
  27. #define MACRO_STRGEN(X) #X
  28. #define MACRO_STR(X) MACRO_STRGEN(X)
  29. constexpr bool time_fuzzes = true;
  30. struct arraysum_test : public test_scaffold {
  31. arraysum_test() {
  32. name = __FILE__ ":1";
  33. }
  34. virtual int run() {
  35. gp::array<uint32_t, 16> test;
  36. for(auto& elem : test)
  37. {
  38. elem = 12;
  39. }
  40. return std::accumulate(test.begin(), test.end(), 0) != 12*test.size();
  41. }
  42. };
  43. append_test dummy_sd45uisd3(new arraysum_test{});
  44. struct optional_test : public test_scaffold {
  45. optional_test() {
  46. name = __FILE__ ":1";
  47. }
  48. virtual int run() {
  49. int res = 0;
  50. {
  51. gp::optional<uint32_t> test;
  52. if(test.has_value())
  53. {
  54. res++;
  55. }
  56. test = 12;
  57. if(test.has_value())
  58. {
  59. if(test.value()!=12)
  60. {
  61. res++;
  62. }
  63. }
  64. else
  65. {
  66. res++;
  67. }
  68. }
  69. {
  70. gp::optional<std::ifstream> test;
  71. if(test.has_value())
  72. {
  73. res++;
  74. }
  75. test = std::ifstream("/proc/cpuinfo");
  76. if(!test.has_value())
  77. {
  78. res++;
  79. }
  80. }
  81. return res;
  82. }
  83. };
  84. append_test dummy_mlyusisd3(new optional_test{});
  85. struct buddy_test : public test_scaffold {
  86. buddy_test() {
  87. name = std::string(__FILE__ "seed_") + std::to_string(seed) + ":3";
  88. rng.seed(seed);
  89. }
  90. std::mt19937 rng{};
  91. int seed = std::random_device{}();
  92. virtual int run() {
  93. int res = 0;
  94. gp::repeat(10, [&](){
  95. gp::array<char, 4096> store;
  96. {
  97. gp::dummy_allocator dummyall;
  98. static_assert(gp::math::msb<uint64_t>(8) == 3);
  99. static_assert(gp::math::msb<uint64_t>(127) == 7);
  100. static_assert(gp::math::msb<uint64_t>(4096) == 12);
  101. gp::buddy<gp::math::msb<uint64_t>(4096)> bud{&*store.begin(), store.size()};
  102. gp::buddy<gp::math::msb<uint64_t>(4096)> dum_bud{store.size(), dummyall};
  103. {
  104. gp::buddy<> inner_bud{2048, bud};
  105. gp_config::assertion(!dummyall.try_reallocate(nullptr, 0), "reallocation works wut?");
  106. gp_config::assertion(!bud.try_reallocate(nullptr, 0), "reallocation works wut?");
  107. gp_config::assertion(!inner_bud.try_reallocate(nullptr, 0), "reallocation works wut?");
  108. std::set<void*> ptr_set;
  109. for(int i = 0; i < 2048 / 16; i++)
  110. {
  111. void* v = inner_bud.allocate(16);
  112. gp_config::assertion(!inner_bud.empty(), "allocator should have elements");
  113. if(v == nullptr)
  114. {
  115. throw gp::runtime_error("allocation failed");
  116. }
  117. ptr_set.insert(v);
  118. }
  119. bool wut = ptr_set.count(nullptr)!=0 || ptr_set.size()!=(2048/16);
  120. if(wut) throw gp::runtime_error("some allocations failed line: " MACRO_STR(__LINE__));
  121. if(nullptr != inner_bud.allocate(8)) throw gp::runtime_error("allocation succeeded, failure was expected");
  122. for(auto elem : ptr_set) {
  123. gp_config::assertion(!inner_bud.empty(), "allocator should have elements");
  124. if(inner_bud.deallocate(elem) == false)
  125. {
  126. res += 1;
  127. }
  128. }
  129. gp_config::assertion(inner_bud.empty(), "allocator should be empty");
  130. }
  131. {
  132. gp_config::assertion(!dummyall.try_reallocate(nullptr, 0), "reallocation works wut?");
  133. gp_config::assertion(!bud.try_reallocate(nullptr, 0), "reallocation works wut?");
  134. std::set<void*> ptr_set;
  135. for(int i = 0; i < 4096 / 16; i++)
  136. {
  137. void* v = bud.allocate(16);
  138. gp_config::assertion(!bud.empty(), "allocator should have elements");
  139. if(v == nullptr) throw gp::runtime_error("allocation failed");
  140. ptr_set.insert(v);
  141. }
  142. if(ptr_set.count(nullptr)!=0 || ptr_set.size()!=(4096/16)) throw gp::runtime_error("some allocations failed line: " MACRO_STR(__LINE__));
  143. if(nullptr != bud.allocate(8)) throw gp::runtime_error("allocation succeeded, failure was expected");
  144. for(auto elem : ptr_set) {
  145. gp_config::assertion(!bud.empty(), "allocator should have elements");
  146. if(bud.deallocate(elem) == false)
  147. {
  148. res += 1;
  149. }
  150. }
  151. gp_config::assertion(bud.empty(), "allocator should be empty");
  152. }
  153. {
  154. std::set<void*> ptr_set;
  155. for(int i = 0; i < 4096 / 8; i++)
  156. {
  157. void* v = bud.allocate(8);
  158. gp_config::assertion(!bud.empty(), "allocator should have elements");
  159. if(v == nullptr) throw gp::runtime_error("allocation failed");
  160. ptr_set.insert(v);
  161. }
  162. if(ptr_set.count(nullptr)!=0 || ptr_set.size()!=(4096/8)) throw gp::runtime_error("some allocations failed line: " MACRO_STR(__LINE__));
  163. if(nullptr != bud.allocate(8)) throw gp::runtime_error("allocation succeeded, failure was expected");
  164. for(auto elem : ptr_set) {
  165. gp_config::assertion(!bud.empty(), "allocator should have elements");
  166. if(bud.deallocate(elem) == false)
  167. {
  168. res += 1;
  169. }
  170. }
  171. gp_config::assertion(bud.empty(), "allocator should be empty");
  172. }
  173. {
  174. std::set<void*> ptr_set;
  175. std::vector<size_t> infill;
  176. std::insert_iterator< std::vector<size_t> > inserter{infill, std::end(infill)};
  177. std::fill_n(inserter, 4096 / 16 / 4, 16);
  178. inserter = std::insert_iterator< std::vector<size_t> >{infill, std::end(infill)};
  179. std::fill_n(inserter, 4096 / 8 / 4, 8);
  180. std::shuffle(infill.begin(), infill.end(), rng);
  181. for(auto sz : infill)
  182. {
  183. void* v = bud.allocate(sz);
  184. gp_config::assertion(!bud.empty(), "allocator should have elements");
  185. if(v == nullptr) throw gp::runtime_error("allocation failed");
  186. ptr_set.insert(v);
  187. }
  188. if(ptr_set.count(nullptr)!=0) throw gp::runtime_error("some allocations failed line: " MACRO_STR(__LINE__));
  189. gp_config::assertion(!bud.deallocate((char*)store.begin().data + 1), "misaligned deallocation fails");
  190. for(auto elem : ptr_set) {
  191. gp_config::assertion(!bud.empty(), "allocator should have elements");
  192. if(bud.deallocate(elem) == false)
  193. {
  194. res += 1;
  195. }
  196. }
  197. gp_config::assertion(!bud.deallocate(nullptr), "deallocating out of scope returns false");
  198. gp_config::assertion(bud.empty(), "allocator should be empty");
  199. }
  200. }
  201. });
  202. return res;
  203. }
  204. };
  205. append_test dummy_654sisd3(new buddy_test{});
  206. // TODO: should implement a test that tries to wrongly remove pointers as well as to allocate them correctly
  207. struct buddy_fuzz_test : public test_scaffold {
  208. buddy_fuzz_test() {
  209. name = std::string(__FILE__ "seed_") + std::to_string(seed) + ":4";
  210. rng.seed(seed);
  211. }
  212. buddy_fuzz_test(size_t _seed) {
  213. seed = _seed;
  214. name = std::string(__FILE__ "seed_") + std::to_string(seed) + ":4";
  215. rng.seed(seed);
  216. }
  217. std::mt19937 rng{};
  218. int seed = std::random_device{}();
  219. virtual int run() {
  220. int res = 0;
  221. alignas(8) gp::array<char, 4096> store;
  222. gp::buddy<gp::math::msb<uint64_t>(4096)> bud{&*store.begin(), store.size()};
  223. std::vector<void*> ptr_set;
  224. auto get_random_mem_qt = [&]() -> size_t {
  225. return 1+rng()%(store.size()-1);
  226. };
  227. auto start = std::chrono::steady_clock::now();
  228. {
  229. gp::repeat(FUZZ_STRENGTH, [&](){
  230. void* ptr;
  231. auto sz = get_random_mem_qt();
  232. size_t tries = 0;
  233. std::shuffle(
  234. ptr_set.begin(),
  235. ptr_set.end(),
  236. rng
  237. );
  238. while(!(ptr = bud.allocate(sz)))
  239. {
  240. void* free_ptr = ptr_set.back();
  241. ptr_set.pop_back();
  242. gp_config::assertion(bud.deallocate(free_ptr), "could not free sample");
  243. gp_config::assertion(++tries <= store.size(), "infinite fuzzing");
  244. }
  245. ptr_set.emplace_back(ptr);
  246. });
  247. for(auto ptr : ptr_set)
  248. {
  249. bud.deallocate(ptr);
  250. }
  251. ptr_set.resize(0);
  252. }
  253. auto duration = std::chrono::steady_clock::now() - start;
  254. start = std::chrono::steady_clock::now();
  255. {
  256. size_t acc = 0;
  257. gp::repeat(FUZZ_STRENGTH, [&](){
  258. void* ptr;
  259. auto sz = get_random_mem_qt();
  260. size_t tries = 0;
  261. std::shuffle(
  262. ptr_set.begin(),
  263. ptr_set.end(),
  264. rng
  265. );
  266. ptr = malloc(sz);
  267. acc+=1;
  268. while(acc > 20)
  269. {
  270. void* free_ptr = ptr_set.back();
  271. free(free_ptr);
  272. acc -= 1;
  273. ptr_set.pop_back();
  274. gp_config::assertion(++tries <= store.size(), "infinite fuzzing");
  275. }
  276. ptr_set.emplace_back(ptr);
  277. });
  278. for(auto ptr : ptr_set)
  279. {
  280. free(ptr);
  281. }
  282. }
  283. auto reference = std::chrono::steady_clock::now() - start;
  284. if(do_bench){
  285. std::cout
  286. << "Fuzzing timed at "
  287. << std::chrono::duration_cast<std::chrono::microseconds>(duration).count()
  288. << "µs for "
  289. << FUZZ_STRENGTH
  290. << " (reference: "
  291. << std::chrono::duration_cast<std::chrono::microseconds>(reference).count()
  292. << "µs)"
  293. << std::endl;
  294. }
  295. return res;
  296. }
  297. };
  298. append_test dummy_df987sd3(new buddy_fuzz_test{781017366});
  299. append_test dummy_df4sisd3(new buddy_fuzz_test{});
  300. struct ring_list_test : public test_scaffold {
  301. ring_list_test() {
  302. name = __FILE__ ":5";
  303. }
  304. virtual int run() {
  305. int res = 0;
  306. alignas(8) gp::array<char, 4096> store;
  307. using local_allocator = gp::buddy<gp::math::msb<uint64_t>(4096)>;
  308. local_allocator bud{&*store.begin(), store.size()};
  309. {
  310. using string_ring = gp::ring_list<std::string>;
  311. auto p = new(bud.allocate(sizeof(std::string))) std::string("Hello");
  312. auto orig = new(bud.allocate(sizeof(string_ring::node))) string_ring::node(p);
  313. string_ring ring{orig, bud};
  314. ring.insert("World");
  315. auto it = ring.explore();
  316. std::string test = "";
  317. do{
  318. test += *it;
  319. ++it;
  320. }while(it != ring.explore());
  321. res += (test != "HelloWorld");
  322. }
  323. return res;
  324. }
  325. };
  326. append_test dummy_867fdrgsd3(new ring_list_test{});
  327. struct aggregator_test : public test_scaffold {
  328. aggregator_test() {
  329. name = std::string(__FILE__ "seed_") + std::to_string(seed) + ":6";
  330. rng.seed(seed);
  331. }
  332. std::mt19937 rng{};
  333. int seed = std::random_device{}();
  334. virtual int run() {
  335. int res = 0;
  336. alignas(8) gp::array<char, 4096> store;
  337. using local_allocator = gp::buddy<gp::math::msb<uint64_t>(4096)>;
  338. local_allocator bud{&*store.begin(), store.size()};
  339. alignas(8) gp::array<char, 4096> store2;
  340. local_allocator bud2{&*store2.begin(), store2.size()};
  341. gp::aggregator allocator(bud);
  342. allocator.insert(bud2);
  343. {
  344. std::vector<void*> ptr_set;
  345. auto get_random_mem_qt = [&]() -> size_t {
  346. return 1+rng()%(store.size()-1);
  347. };
  348. auto start = std::chrono::steady_clock::now();
  349. {
  350. gp::repeat(FUZZ_STRENGTH, [&](){
  351. void* ptr;
  352. auto sz = get_random_mem_qt();
  353. size_t tries = 0;
  354. std::shuffle(
  355. ptr_set.begin(),
  356. ptr_set.end(),
  357. rng
  358. );
  359. while(!(ptr = allocator.allocate(sz)))
  360. {
  361. void* free_ptr = ptr_set.back();
  362. ptr_set.pop_back();
  363. gp_config::assertion(allocator.deallocate(free_ptr), "could not free sample");
  364. gp_config::assertion(++tries <= store.size(), "infinite fuzzing");
  365. }
  366. ptr_set.emplace_back(ptr);
  367. });
  368. for(auto ptr : ptr_set)
  369. {
  370. bud.deallocate(ptr);
  371. }
  372. ptr_set.resize(0);
  373. }
  374. auto duration = std::chrono::steady_clock::now() - start;
  375. }
  376. void* a = allocator.allocate(8);
  377. gp_config::assertion(allocator.try_reallocate(a, 16) == false, "could reallocate? was it implemented?");
  378. gp_config::assertion(allocator.deallocate(nullptr) == false, "error, could free an invalid pointer");
  379. allocator.deallocate(a);
  380. {
  381. gp::ring_list<int> list{allocator};
  382. list.insert(8);
  383. list.insert(16);
  384. list.insert(32);
  385. }
  386. {
  387. gp::array<char, 256> work_array;
  388. gp::arena alloc_work(work_array.begin().data, work_array.size());
  389. gp::ring_list<int> list{alloc_work};
  390. gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator");
  391. gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator");
  392. gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator");
  393. }
  394. {
  395. gp::array<char, sizeof(int)> once_array;
  396. gp::arena alloc_once(once_array.begin().data, once_array.size());
  397. gp::ring_list<int> list{alloc_once};
  398. gp_config::assertion(list.insert(8) == false, "could allocate in list with insufficient allocator");
  399. }
  400. {
  401. gp::arena alloc_none(nullptr, 0);
  402. gp::ring_list<int> list{alloc_none};
  403. gp_config::assertion(list.insert(8) == false, "could allocate in list with fake allocator");
  404. }
  405. return res;
  406. }
  407. };
  408. append_test dummy_8ijfsd658(new aggregator_test{});
  409. struct array_test : public test_scaffold {
  410. array_test() {
  411. name = __FILE__ ":7";
  412. }
  413. virtual int run() {
  414. int res = 0;
  415. gp::array<int, 8> store;
  416. {
  417. int i = 0;
  418. for(auto& p : store)
  419. {
  420. p = i++;
  421. }
  422. for(auto it = store.rbegin(); it != store.rend(); ++it)
  423. {
  424. gp_config::assertion(*it == --i, "array error");
  425. }
  426. for(const auto& p : store)
  427. {
  428. gp_config::assertion(p == i++, "array error");
  429. }
  430. for(auto it = store.crbegin(); it != store.crend(); ++it)
  431. {
  432. gp_config::assertion(*it == --i, "array error");
  433. }
  434. size_t cnt = 0;
  435. for(const auto& p : store)
  436. {
  437. cnt++;
  438. }
  439. gp_config::assertion(cnt == store.size(), "array error");
  440. cnt = 0;
  441. for(auto& p : store)
  442. {
  443. cnt++;
  444. }
  445. gp_config::assertion(cnt == store.size(), "array error");
  446. cnt = 0;
  447. for(auto it = store.crbegin(); it != store.crend(); ++it)
  448. {
  449. cnt++;
  450. }
  451. gp_config::assertion(cnt == store.size(), "array error");
  452. cnt = 0;
  453. for(auto it = store.rbegin(); it != store.rend(); ++it)
  454. {
  455. cnt++;
  456. }
  457. gp_config::assertion(cnt == store.size(), "array error");
  458. gp::rotate(store.begin(), store.begin()+1, store.end());
  459. gp::array<int, 8> rotated({1,2,3,4,5,6,7,0});
  460. gp_config::assertion(store == rotated, "rotate error");
  461. gp::rotate(store.begin(), store.end()-1, store.end());
  462. gp_config::assertion(store[0] == 0, "rotate error");
  463. }
  464. return res;
  465. }
  466. };
  467. append_test dummy_ajcurgsd3(new array_test{});
  468. struct indexed_array_test : public test_scaffold {
  469. indexed_array_test() {
  470. name = __FILE__ ":7";
  471. }
  472. virtual int run() {
  473. int res = 0;
  474. {
  475. gp::indexed_array<int, 8> store;
  476. size_t idx = store.push (112);
  477. store.push (113);
  478. store.push (114);
  479. gp_config::assertion(store[idx] == 112, "Bad value in indexed array");
  480. store.mark_for_removal(idx);
  481. store.sweep_removed();
  482. for(auto& p : store) {
  483. if(p == 112) res++;
  484. }
  485. gp_config::assertion(store.size() == 2, "Bad size of indexed array");
  486. }
  487. {
  488. gp::indexed_array<std::string, 8> store;
  489. size_t idx = store.push ("112");
  490. store.push ("113");
  491. store.push ("114");
  492. gp_config::assertion(store[idx] == "112", "Bad value in indexed array");
  493. store.mark_for_removal(idx);
  494. store.sweep_removed();
  495. for(auto& p : store) {
  496. if(p == "112") res++;
  497. }
  498. gp_config::assertion(store.size() == 2, "Bad size of indexed array");
  499. {
  500. // TODO: write a concrete implementation and test it
  501. // gp::vfs fs;
  502. }
  503. }
  504. return res;
  505. }
  506. };
  507. append_test dummy_khxurgsd3(new indexed_array_test{});
  508. struct move_uninitialized_test : public test_scaffold {
  509. move_uninitialized_test() {
  510. name = __FILE__ ":8";
  511. }
  512. struct tester {
  513. size_t* const incremented;
  514. tester(size_t* ptr)
  515. : incremented(ptr)
  516. {}
  517. tester(tester&& oth)
  518. : incremented(oth.incremented)
  519. {
  520. ++*incremented;
  521. }
  522. };
  523. virtual int run() {
  524. int res = 0;
  525. {
  526. size_t counter;
  527. using src_t = gp::array<tester, 16>;
  528. src_t *source = reinterpret_cast<src_t*>(malloc(sizeof(src_t)));
  529. gp::array<char, sizeof(tester)*16> buffer;
  530. for(auto& a : *source) {
  531. new(&a) tester(&counter);
  532. }
  533. gp::move_uninitialized(*source, buffer.as_buffer().cast<tester>());
  534. free(source);
  535. }
  536. return res;
  537. }
  538. };
  539. append_test dummy_hkfyr5f5(new move_uninitialized_test{});
  540. struct clamp_test : public test_scaffold {
  541. clamp_test() {
  542. name = __FILE__ ":9";
  543. }
  544. virtual int run() {
  545. int res = 0;
  546. {
  547. res += gp::clamp<float>(0.0, -1.0, 1.0);
  548. res += gp::clamp<float>(-1.0, 1.0, 0.0);
  549. res += gp::max(-1, -2, 0, -3);
  550. }
  551. return res;
  552. }
  553. };
  554. append_test dummy_gsdh25f5(new clamp_test{});
  555. struct buffer_test : public test_scaffold {
  556. buffer_test() {
  557. name = __FILE__ ":10";
  558. }
  559. virtual int run() {
  560. int res = 0;
  561. {
  562. gp::array<char, 24> data;
  563. gp::array<char, 24> data_e;
  564. gp::buffer<char> handle = data.as_buffer();
  565. handle[12] = '&';
  566. gp_config::assertion(*(handle.begin()+12) == '&', "Could not assign to the buffer");
  567. res += 1;
  568. try {
  569. handle[24] = 16;
  570. res += 1;
  571. handle[-1] = 16;
  572. res += 1;
  573. handle[1024] = 16;
  574. } catch (...) {
  575. res -= 1;
  576. }
  577. res += 1;
  578. try {
  579. auto cast = handle.cast<gp::array<char, 32>>();
  580. } catch (...) {
  581. res -= 1;
  582. }
  583. auto cast = handle.template cast<gp::array<char, 6>>().template cast<gp::array<char, 4>>();
  584. gp_config::assertion(false == (data == data_e), "Different arrays should return false here");
  585. }
  586. return res;
  587. }
  588. };
  589. append_test dummy_gs87ytf5f5(new buffer_test{});
  590. struct endian_test : public test_scaffold {
  591. endian_test() {
  592. name = __FILE__ ":11";
  593. }
  594. virtual int run() {
  595. int res = 0;
  596. {
  597. gp::endian_wrapper<uint32_t> a = 0x41424344UL;
  598. #pragma clang diagnostic push
  599. #pragma clang diagnostic ignored "-Wfour-char-constants"
  600. #pragma gcc diagnostic push
  601. #pragma gcc diagnostic ignored "-Wfour-char-constants"
  602. gp_config::assertion(a.value != 'ABCD', "Not a big endian in a big endian wrapper");
  603. #pragma gcc diagnostic pop
  604. #pragma clang diagnostic pop
  605. gp_config::assertion(gp::swap_endian<uint32_t>(0x41424344UL)==0x44434241UL, "swap_endian doesn't swap endian");
  606. }
  607. return res;
  608. }
  609. };
  610. append_test dummy_45zelotf5f5(new endian_test{});
  611. struct alloc_bench_test : public test_scaffold {
  612. alloc_bench_test() {
  613. name = __FILE__ ":12";
  614. }
  615. virtual int run() {
  616. int res = 0;
  617. if(do_bench) {
  618. auto store = std::make_unique<std::array<char, 1 << 16>>();
  619. using buddy_loc = gp::buddy<>;
  620. using arena_loc = gp::arena;
  621. buddy_loc bud{&*store->begin(), store->size()};
  622. arena_loc are{&*store->begin(), store->size()};
  623. std::cout << "Allocator | Operation | Divider | Time (µs)" << std::endl;
  624. for(size_t divider = 2; divider < 32; ++divider)
  625. {
  626. gp::ring_list<int> a{bud};
  627. gp::ring_list<int> b{are};
  628. std::cout <<
  629. "ARE | " << "INS | " << divider << " | " <<
  630. time_operation([&](){
  631. for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int>::node)/divider; i++) {
  632. b.insert(i);
  633. }
  634. }).count() << std::endl;
  635. std::cout <<
  636. "ARE | " << "DEL | " << divider << " | " <<
  637. time_operation([&](){
  638. for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int>::node)/divider; i++) {
  639. gp::ring_list<int>::explorer e = b.explore();
  640. b.remove(e);
  641. }
  642. }).count() << std::endl;
  643. std::cout <<
  644. "BUD | " << "INS | " << divider << " | " <<
  645. time_operation([&](){
  646. for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int>::node)/divider; i++) {
  647. a.insert(i);
  648. }
  649. }).count() << std::endl;
  650. std::cout <<
  651. "BUD | " << "DEL | " << divider << " | " <<
  652. time_operation([&](){
  653. for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int>::node)/divider; i++) {
  654. gp::ring_list<int>::explorer e = a.explore();
  655. a.remove(e);
  656. }
  657. }).count() << std::endl;
  658. }
  659. {
  660. gp::ring_list<int> a{bud};
  661. gp::ring_list<int> b{are};
  662. for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int>::node)/2; i++) {
  663. a.insert(i);
  664. }
  665. for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int>::node)/2; i++) {
  666. gp::ring_list<int>::explorer e = a.explore();
  667. a.remove(++e);
  668. }
  669. }
  670. }
  671. return res;
  672. }
  673. };
  674. append_test dummy_jhgspo5d5(new alloc_bench_test{});
  675. struct indexed_array_stair_test : public test_scaffold {
  676. indexed_array_stair_test() {
  677. name = __FILE__ ":13";
  678. }
  679. virtual int run() {
  680. int res = 0;
  681. {
  682. int climb = 0;
  683. int curr_climb = 0;
  684. gp::indexed_array<int, 1024> arr;
  685. while(climb < 1000)
  686. {
  687. for(; curr_climb < 10; climb++, curr_climb++ )
  688. {
  689. arr.push(climb);
  690. }
  691. for(; curr_climb != 0; curr_climb -= 2) {
  692. arr.pop(arr.size() - curr_climb);
  693. }
  694. arr.pop(arr.size() - 1);
  695. }
  696. }
  697. return res;
  698. }
  699. };
  700. append_test dummy_amf763ld5(new indexed_array_stair_test{});