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.

796 lines
20 KiB

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