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.

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