#include "allocator.hpp"
|
|
#include "gp/algorithm/repeat.hpp"
|
|
#include "gp/algorithm/rotate.hpp"
|
|
#include "gp/algorithm/move.hpp"
|
|
#include "gp/allocator/aggregator.hpp"
|
|
#include "gp/allocator/arena.hpp"
|
|
#include "gp/allocator/buddy.hpp"
|
|
#include "gp/allocator/dummy.hpp"
|
|
#include "gp/array.hpp"
|
|
#include "gp/bitops.hpp"
|
|
#include "gp/indexed_array.hpp"
|
|
#include "gp/ring_list.hpp"
|
|
#include "test_scaffold.h"
|
|
|
|
#include <algorithm>
|
|
#include <chrono>
|
|
#include <fstream>
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
#include <numeric>
|
|
#include <random>
|
|
#include <set>
|
|
#include <stack>
|
|
#include <thread>
|
|
|
|
|
|
|
|
#ifndef FUZZ_STRENGTH
|
|
#define FUZZ_STRENGTH 2048
|
|
#endif
|
|
|
|
#define MACRO_STRGEN(X) #X
|
|
#define MACRO_STR(X) MACRO_STRGEN(X)
|
|
|
|
constexpr bool time_fuzzes = true;
|
|
|
|
|
|
struct arraysum_test : public test_scaffold {
|
|
arraysum_test() {
|
|
name = __FILE__ ":1";
|
|
}
|
|
|
|
virtual int run() {
|
|
gp::array<uint32_t, 16> test;
|
|
|
|
for(auto& elem : test)
|
|
{
|
|
elem = 12;
|
|
}
|
|
|
|
return std::accumulate(test.begin(), test.end(), 0) != 12*test.size();
|
|
}
|
|
};
|
|
|
|
append_test dummy_sd45uisd3(new arraysum_test{});
|
|
|
|
|
|
struct optional_test : public test_scaffold {
|
|
optional_test() {
|
|
name = __FILE__ ":1";
|
|
}
|
|
|
|
virtual int run() {
|
|
int res = 0;
|
|
{
|
|
gp::optional<uint32_t> test;
|
|
|
|
if(test.has_value())
|
|
{
|
|
res++;
|
|
}
|
|
|
|
test = 12;
|
|
|
|
if(test.has_value())
|
|
{
|
|
if(test.value()!=12)
|
|
{
|
|
res++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
res++;
|
|
}
|
|
}
|
|
{
|
|
gp::optional<std::ifstream> test;
|
|
|
|
if(test.has_value())
|
|
{
|
|
res++;
|
|
}
|
|
|
|
test = std::ifstream("/proc/cpuinfo");
|
|
|
|
if(!test.has_value())
|
|
{
|
|
res++;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
};
|
|
|
|
append_test dummy_mlyusisd3(new optional_test{});
|
|
|
|
|
|
struct buddy_test : public test_scaffold {
|
|
buddy_test() {
|
|
name = std::string(__FILE__ "seed_") + std::to_string(seed) + ":3";
|
|
rng.seed(seed);
|
|
}
|
|
|
|
std::mt19937 rng{};
|
|
int seed = std::random_device{}();
|
|
|
|
virtual int run() {
|
|
int res = 0;
|
|
gp::repeat(10, [&](){
|
|
gp::array<char, 4096> store;
|
|
{
|
|
gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)> bud{&*store.begin(), store.size()};
|
|
gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)> dum_bud{store.size()};
|
|
gp::buddy<static_mapper> inner_bud{2048};
|
|
gp::dummy_allocator dummyall;
|
|
{
|
|
gp_config::assertion(!dummyall.try_reallocate(nullptr, 0), "reallocation works wut?");
|
|
gp_config::assertion(!bud.try_reallocate(nullptr, 0), "reallocation works wut?");
|
|
gp_config::assertion(!inner_bud.try_reallocate(nullptr, 0), "reallocation works wut?");
|
|
std::set<void*> ptr_set;
|
|
for(int i = 0; i < 2048 / 16; i++)
|
|
{
|
|
void* v = inner_bud.allocate(16);
|
|
gp_config::assertion(!inner_bud.empty(), "allocator should have elements");
|
|
if(v == nullptr) throw gp::runtime_error("allocation failed");
|
|
ptr_set.insert(v);
|
|
}
|
|
bool wut = ptr_set.count(nullptr)!=0 || ptr_set.size()!=(2048/16);
|
|
if(wut) throw gp::runtime_error("some allocations failed line: " MACRO_STR(__LINE__));
|
|
if(nullptr != inner_bud.allocate(8)) throw gp::runtime_error("allocation succeeded, failure was expected");
|
|
|
|
for(auto elem : ptr_set) {
|
|
gp_config::assertion(!inner_bud.empty(), "allocator should have elements");
|
|
if(inner_bud.deallocate(elem) == false)
|
|
{
|
|
res += 1;
|
|
}
|
|
}
|
|
gp_config::assertion(inner_bud.empty(), "allocator should be empty");
|
|
}
|
|
{
|
|
gp_config::assertion(!dummyall.try_reallocate(nullptr, 0), "reallocation works wut?");
|
|
gp_config::assertion(!bud.try_reallocate(nullptr, 0), "reallocation works wut?");
|
|
std::set<void*> ptr_set;
|
|
for(int i = 0; i < 4096 / 16; i++)
|
|
{
|
|
void* v = bud.allocate(16);
|
|
gp_config::assertion(!bud.empty(), "allocator should have elements");
|
|
if(v == nullptr) throw gp::runtime_error("allocation failed");
|
|
ptr_set.insert(v);
|
|
}
|
|
if(ptr_set.count(nullptr)!=0 || ptr_set.size()!=(4096/16)) throw gp::runtime_error("some allocations failed line: " MACRO_STR(__LINE__));
|
|
if(nullptr != bud.allocate(8)) throw gp::runtime_error("allocation succeeded, failure was expected");
|
|
|
|
for(auto elem : ptr_set) {
|
|
gp_config::assertion(!bud.empty(), "allocator should have elements");
|
|
if(bud.deallocate(elem) == false)
|
|
{
|
|
res += 1;
|
|
}
|
|
}
|
|
gp_config::assertion(bud.empty(), "allocator should be empty");
|
|
}
|
|
{
|
|
std::set<void*> ptr_set;
|
|
for(int i = 0; i < 4096 / 8; i++)
|
|
{
|
|
void* v = bud.allocate(8);
|
|
gp_config::assertion(!bud.empty(), "allocator should have elements");
|
|
if(v == nullptr) throw gp::runtime_error("allocation failed");
|
|
ptr_set.insert(v);
|
|
}
|
|
if(ptr_set.count(nullptr)!=0 || ptr_set.size()!=(4096/8)) throw gp::runtime_error("some allocations failed line: " MACRO_STR(__LINE__));
|
|
if(nullptr != bud.allocate(8)) throw gp::runtime_error("allocation succeeded, failure was expected");
|
|
|
|
for(auto elem : ptr_set) {
|
|
gp_config::assertion(!bud.empty(), "allocator should have elements");
|
|
if(bud.deallocate(elem) == false)
|
|
{
|
|
res += 1;
|
|
}
|
|
}
|
|
gp_config::assertion(bud.empty(), "allocator should be empty");
|
|
}
|
|
{
|
|
std::set<void*> ptr_set;
|
|
std::vector<size_t> infill;
|
|
std::insert_iterator< std::vector<size_t> > inserter{infill, std::end(infill)};
|
|
std::fill_n(inserter, 4096 / 16 / 4, 16);
|
|
inserter = std::insert_iterator< std::vector<size_t> >{infill, std::end(infill)};
|
|
std::fill_n(inserter, 4096 / 8 / 4, 8);
|
|
std::shuffle(infill.begin(), infill.end(), rng);
|
|
for(auto sz : infill)
|
|
{
|
|
void* v = bud.allocate(sz);
|
|
gp_config::assertion(!bud.empty(), "allocator should have elements");
|
|
if(v == nullptr) throw gp::runtime_error("allocation failed");
|
|
ptr_set.insert(v);
|
|
}
|
|
if(ptr_set.count(nullptr)!=0) throw gp::runtime_error("some allocations failed line: " MACRO_STR(__LINE__));
|
|
|
|
gp_config::assertion(!bud.deallocate((char*)store.begin().data + 1), "misaligned deallocation fails");
|
|
for(auto elem : ptr_set) {
|
|
gp_config::assertion(!bud.empty(), "allocator should have elements");
|
|
if(bud.deallocate(elem) == false)
|
|
{
|
|
res += 1;
|
|
}
|
|
}
|
|
gp_config::assertion(!bud.deallocate(nullptr), "deallocating out of scope returns false");
|
|
gp_config::assertion(bud.empty(), "allocator should be empty");
|
|
}
|
|
}
|
|
});
|
|
return res;
|
|
}
|
|
};
|
|
|
|
append_test dummy_654sisd3(new buddy_test{});
|
|
|
|
|
|
|
|
// TODO: should implement a test that tries to wrongly remove pointers as well as to allocate them correctly
|
|
struct buddy_fuzz_test : public test_scaffold {
|
|
buddy_fuzz_test() {
|
|
name = std::string(__FILE__ "seed_") + std::to_string(seed) + ":4";
|
|
rng.seed(seed);
|
|
}
|
|
|
|
buddy_fuzz_test(size_t _seed) {
|
|
seed = _seed;
|
|
name = std::string(__FILE__ "seed_") + std::to_string(seed) + ":4";
|
|
rng.seed(seed);
|
|
}
|
|
|
|
std::mt19937 rng{};
|
|
int seed = std::random_device{}();
|
|
|
|
virtual int run() {
|
|
int res = 0;
|
|
alignas(8) gp::array<char, 4096> store;
|
|
gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)> bud{&*store.begin(), store.size()};
|
|
std::vector<void*> ptr_set;
|
|
auto get_random_mem_qt = [&]() -> size_t {
|
|
return 1+rng()%(store.size()-1);
|
|
};
|
|
|
|
auto start = std::chrono::steady_clock::now();
|
|
{
|
|
gp::repeat(FUZZ_STRENGTH, [&](){
|
|
void* ptr;
|
|
auto sz = get_random_mem_qt();
|
|
size_t tries = 0;
|
|
std::shuffle(
|
|
ptr_set.begin(),
|
|
ptr_set.end(),
|
|
rng
|
|
);
|
|
while(!(ptr = bud.allocate(sz)))
|
|
{
|
|
void* free_ptr = ptr_set.back();
|
|
ptr_set.pop_back();
|
|
gp_config::assertion(bud.deallocate(free_ptr), "could not free sample");
|
|
gp_config::assertion(++tries <= store.size(), "infinite fuzzing");
|
|
}
|
|
ptr_set.emplace_back(ptr);
|
|
});
|
|
for(auto ptr : ptr_set)
|
|
{
|
|
bud.deallocate(ptr);
|
|
}
|
|
ptr_set.resize(0);
|
|
}
|
|
auto duration = std::chrono::steady_clock::now() - start;
|
|
|
|
start = std::chrono::steady_clock::now();
|
|
{
|
|
size_t acc = 0;
|
|
gp::repeat(FUZZ_STRENGTH, [&](){
|
|
void* ptr;
|
|
auto sz = get_random_mem_qt();
|
|
size_t tries = 0;
|
|
std::shuffle(
|
|
ptr_set.begin(),
|
|
ptr_set.end(),
|
|
rng
|
|
);
|
|
ptr = malloc(sz);
|
|
acc+=1;
|
|
while(acc > 20)
|
|
{
|
|
void* free_ptr = ptr_set.back();
|
|
free(free_ptr);
|
|
acc -= 1;
|
|
ptr_set.pop_back();
|
|
gp_config::assertion(++tries <= store.size(), "infinite fuzzing");
|
|
}
|
|
ptr_set.emplace_back(ptr);
|
|
});
|
|
for(auto ptr : ptr_set)
|
|
{
|
|
free(ptr);
|
|
}
|
|
}
|
|
auto reference = std::chrono::steady_clock::now() - start;
|
|
|
|
if(do_bench){
|
|
std::cout
|
|
<< "Fuzzing timed at "
|
|
<< std::chrono::duration_cast<std::chrono::microseconds>(duration).count()
|
|
<< "µs for "
|
|
<< FUZZ_STRENGTH
|
|
<< " (reference: "
|
|
<< std::chrono::duration_cast<std::chrono::microseconds>(reference).count()
|
|
<< "µs)"
|
|
<< std::endl;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
};
|
|
|
|
append_test dummy_df987sd3(new buddy_fuzz_test{781017366});
|
|
append_test dummy_df4sisd3(new buddy_fuzz_test{});
|
|
|
|
struct ring_list_test : public test_scaffold {
|
|
ring_list_test() {
|
|
name = __FILE__ ":5";
|
|
}
|
|
|
|
virtual int run() {
|
|
int res = 0;
|
|
alignas(8) gp::array<char, 4096> store;
|
|
using local_allocator = gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)>;
|
|
local_allocator bud{&*store.begin(), store.size()};
|
|
{
|
|
using string_ring = gp::ring_list<std::string, local_allocator, false>;
|
|
auto p = new(bud.allocate(sizeof(std::string))) std::string("Hello");
|
|
auto orig = new(bud.allocate(sizeof(string_ring::node))) string_ring::node(p);
|
|
string_ring ring{orig, bud};
|
|
ring.insert("World");
|
|
auto it = ring.explore();
|
|
std::string test = "";
|
|
do{
|
|
test += *it;
|
|
++it;
|
|
}while(it != ring.explore());
|
|
res += (test != "HelloWorld");
|
|
}
|
|
return res;
|
|
}
|
|
};
|
|
|
|
append_test dummy_867fdrgsd3(new ring_list_test{});
|
|
|
|
|
|
struct aggregator_test : public test_scaffold {
|
|
aggregator_test() {
|
|
name = std::string(__FILE__ "seed_") + std::to_string(seed) + ":6";
|
|
rng.seed(seed);
|
|
}
|
|
|
|
std::mt19937 rng{};
|
|
int seed = std::random_device{}();
|
|
|
|
virtual int run() {
|
|
int res = 0;
|
|
alignas(8) gp::array<char, 4096> store;
|
|
using local_allocator = gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)>;
|
|
local_allocator bud{&*store.begin(), store.size()};
|
|
alignas(8) gp::array<char, 4096> store2;
|
|
local_allocator bud2{&*store2.begin(), store2.size()};
|
|
|
|
gp::aggregator allocator{bud};
|
|
allocator.insert(bud2);
|
|
{
|
|
std::vector<void*> ptr_set;
|
|
auto get_random_mem_qt = [&]() -> size_t {
|
|
return 1+rng()%(store.size()-1);
|
|
};
|
|
|
|
auto start = std::chrono::steady_clock::now();
|
|
{
|
|
gp::repeat(FUZZ_STRENGTH, [&](){
|
|
void* ptr;
|
|
auto sz = get_random_mem_qt();
|
|
size_t tries = 0;
|
|
std::shuffle(
|
|
ptr_set.begin(),
|
|
ptr_set.end(),
|
|
rng
|
|
);
|
|
while(!(ptr = allocator.allocate(sz)))
|
|
{
|
|
void* free_ptr = ptr_set.back();
|
|
ptr_set.pop_back();
|
|
gp_config::assertion(allocator.deallocate(free_ptr), "could not free sample");
|
|
gp_config::assertion(++tries <= store.size(), "infinite fuzzing");
|
|
}
|
|
ptr_set.emplace_back(ptr);
|
|
});
|
|
for(auto ptr : ptr_set)
|
|
{
|
|
bud.deallocate(ptr);
|
|
}
|
|
ptr_set.resize(0);
|
|
}
|
|
auto duration = std::chrono::steady_clock::now() - start;
|
|
}
|
|
void* a = allocator.allocate(8);
|
|
gp_config::assertion(allocator.try_reallocate(a, 16) == false, "could reallocate? was it implemented?");
|
|
gp_config::assertion(allocator.deallocate(nullptr) == false, "error, could free an invalid pointer");
|
|
allocator.deallocate(a);
|
|
{
|
|
gp::ring_list<int, gp::aggregator, false> list{allocator};
|
|
list.insert(8);
|
|
list.insert(16);
|
|
list.insert(32);
|
|
}
|
|
{
|
|
gp::array<char, 256> work_array;
|
|
gp::arena<> alloc_work(work_array.begin().data, work_array.size());
|
|
gp::ring_list<int, gp::arena<>, false> list{alloc_work};
|
|
gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator");
|
|
gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator");
|
|
gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator");
|
|
}
|
|
{
|
|
gp::array<char, sizeof(int)> once_array;
|
|
gp::arena<> alloc_once(once_array.begin().data, once_array.size());
|
|
gp::ring_list<int, gp::arena<>, false> list{alloc_once};
|
|
gp_config::assertion(list.insert(8) == false, "could allocate in list with insufficient allocator");
|
|
}
|
|
{
|
|
gp::arena<> alloc_none(nullptr, 0);
|
|
gp::ring_list<int, gp::arena<>, false> list{alloc_none};
|
|
gp_config::assertion(list.insert(8) == false, "could allocate in list with fake allocator");
|
|
}
|
|
return res;
|
|
}
|
|
};
|
|
|
|
append_test dummy_8ijfsd658(new aggregator_test{});
|
|
|
|
|
|
struct array_test : public test_scaffold {
|
|
array_test() {
|
|
name = __FILE__ ":7";
|
|
}
|
|
|
|
virtual int run() {
|
|
int res = 0;
|
|
gp::array<int, 8> store;
|
|
{
|
|
int i = 0;
|
|
for(auto& p : store)
|
|
{
|
|
p = i++;
|
|
}
|
|
for(auto it = store.rbegin(); it != store.rend(); ++it)
|
|
{
|
|
gp_config::assertion(*it == --i, "array error");
|
|
}
|
|
for(const auto& p : store)
|
|
{
|
|
gp_config::assertion(p == i++, "array error");
|
|
}
|
|
for(auto it = store.crbegin(); it != store.crend(); ++it)
|
|
{
|
|
gp_config::assertion(*it == --i, "array error");
|
|
}
|
|
size_t cnt = 0;
|
|
for(const auto& p : store)
|
|
{
|
|
cnt++;
|
|
}
|
|
gp_config::assertion(cnt == store.size(), "array error");
|
|
cnt = 0;
|
|
for(auto& p : store)
|
|
{
|
|
cnt++;
|
|
}
|
|
gp_config::assertion(cnt == store.size(), "array error");
|
|
cnt = 0;
|
|
for(auto it = store.crbegin(); it != store.crend(); ++it)
|
|
{
|
|
cnt++;
|
|
}
|
|
gp_config::assertion(cnt == store.size(), "array error");
|
|
cnt = 0;
|
|
for(auto it = store.rbegin(); it != store.rend(); ++it)
|
|
{
|
|
cnt++;
|
|
}
|
|
gp_config::assertion(cnt == store.size(), "array error");
|
|
gp::rotate(store.begin(), store.begin()+1, store.end());
|
|
gp::array<int, 8> rotated({1,2,3,4,5,6,7,0});
|
|
gp_config::assertion(store == rotated, "rotate error");
|
|
gp::rotate(store.begin(), store.end()-1, store.end());
|
|
gp_config::assertion(store[0] == 0, "rotate error");
|
|
|
|
}
|
|
return res;
|
|
}
|
|
};
|
|
|
|
append_test dummy_ajcurgsd3(new array_test{});
|
|
|
|
struct indexed_array_test : public test_scaffold {
|
|
indexed_array_test() {
|
|
name = __FILE__ ":7";
|
|
}
|
|
|
|
virtual int run() {
|
|
int res = 0;
|
|
{
|
|
gp::indexed_array<int, 8> store;
|
|
size_t idx = store.push (112);
|
|
store.push (113);
|
|
store.push (114);
|
|
gp_config::assertion(store[idx] == 112, "Bad value in indexed array");
|
|
|
|
store.mark_for_removal(idx);
|
|
store.sweep_removed();
|
|
for(auto& p : store) {
|
|
if(p == 112) res++;
|
|
}
|
|
|
|
gp_config::assertion(store.size() == 2, "Bad size of indexed array");
|
|
}
|
|
{
|
|
gp::indexed_array<std::string, 8> store;
|
|
size_t idx = store.push ("112");
|
|
store.push ("113");
|
|
store.push ("114");
|
|
gp_config::assertion(store[idx] == "112", "Bad value in indexed array");
|
|
|
|
store.mark_for_removal(idx);
|
|
store.sweep_removed();
|
|
for(auto& p : store) {
|
|
if(p == "112") res++;
|
|
}
|
|
|
|
gp_config::assertion(store.size() == 2, "Bad size of indexed array");
|
|
|
|
{
|
|
// TODO: write a concrete implementation and test it
|
|
// gp::vfs fs;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
};
|
|
|
|
append_test dummy_khxurgsd3(new indexed_array_test{});
|
|
|
|
|
|
|
|
struct move_uninitialized_test : public test_scaffold {
|
|
move_uninitialized_test() {
|
|
name = __FILE__ ":8";
|
|
}
|
|
|
|
struct tester {
|
|
size_t* const incremented;
|
|
|
|
tester(size_t* ptr)
|
|
: incremented(ptr)
|
|
{}
|
|
|
|
tester(tester&& oth)
|
|
: incremented(oth.incremented)
|
|
{
|
|
++*incremented;
|
|
}
|
|
};
|
|
|
|
virtual int run() {
|
|
int res = 0;
|
|
{
|
|
size_t counter;
|
|
using src_t = gp::array<tester, 16>;
|
|
src_t *source = reinterpret_cast<src_t*>(malloc(sizeof(src_t)));
|
|
gp::array<char, sizeof(tester)*16> buffer;
|
|
for(auto& a : *source) {
|
|
new(&a) tester(&counter);
|
|
}
|
|
gp::move_uninitialized(*source, buffer.as_buffer().cast<tester>());
|
|
free(source);
|
|
}
|
|
return res;
|
|
}
|
|
};
|
|
|
|
append_test dummy_hkfyr5f5(new move_uninitialized_test{});
|
|
|
|
|
|
|
|
struct clamp_test : public test_scaffold {
|
|
clamp_test() {
|
|
name = __FILE__ ":9";
|
|
}
|
|
|
|
virtual int run() {
|
|
int res = 0;
|
|
{
|
|
res += gp::clamp<float>(0.0, -1.0, 1.0);
|
|
res += gp::clamp<float>(-1.0, 1.0, 0.0);
|
|
res += gp::max(-1, -2, 0, -3);
|
|
}
|
|
return res;
|
|
}
|
|
};
|
|
|
|
append_test dummy_gsdh25f5(new clamp_test{});
|
|
|
|
struct buffer_test : public test_scaffold {
|
|
buffer_test() {
|
|
name = __FILE__ ":10";
|
|
}
|
|
|
|
virtual int run() {
|
|
int res = 0;
|
|
{
|
|
gp::array<char, 24> data;
|
|
gp::array<char, 24> data_e;
|
|
gp::buffer<char> handle = data.as_buffer();
|
|
handle[12] = '&';
|
|
gp_config::assertion(*(handle.begin()+12) == '&', "Could not assign to the buffer");
|
|
res += 1;
|
|
try {
|
|
handle[24] = 16;
|
|
res += 1;
|
|
handle[-1] = 16;
|
|
res += 1;
|
|
handle[1024] = 16;
|
|
} catch (...) {
|
|
res -= 1;
|
|
}
|
|
res += 1;
|
|
try {
|
|
auto cast = handle.cast<gp::array<char, 32>>();
|
|
} catch (...) {
|
|
res -= 1;
|
|
}
|
|
auto cast = handle.template cast<gp::array<char, 6>>().template cast<gp::array<char, 4>>();
|
|
gp_config::assertion(false == (data == data_e), "Different arrays should return false here");
|
|
}
|
|
return res;
|
|
}
|
|
};
|
|
|
|
append_test dummy_gs87ytf5f5(new buffer_test{});
|
|
|
|
|
|
|
|
struct endian_test : public test_scaffold {
|
|
endian_test() {
|
|
name = __FILE__ ":11";
|
|
}
|
|
|
|
virtual int run() {
|
|
int res = 0;
|
|
{
|
|
gp::endian_wrapper<uint32_t> a = 0x41424344UL;
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wfour-char-constants"
|
|
#pragma gcc diagnostic push
|
|
#pragma gcc diagnostic ignored "-Wfour-char-constants"
|
|
gp_config::assertion(a.value != 'ABCD', "Not a big endian in a big endian wrapper");
|
|
#pragma gcc diagnostic pop
|
|
#pragma clang diagnostic pop
|
|
gp_config::assertion(gp::swap_endian<uint32_t>(0x41424344UL)==0x44434241UL, "swap_endian doesn't swap endian");
|
|
}
|
|
return res;
|
|
}
|
|
};
|
|
|
|
append_test dummy_45zelotf5f5(new endian_test{});
|
|
|
|
struct alloc_bench_test : public test_scaffold {
|
|
alloc_bench_test() {
|
|
name = __FILE__ ":12";
|
|
}
|
|
|
|
virtual int run() {
|
|
int res = 0;
|
|
if(do_bench) {
|
|
auto store = std::make_unique<std::array<char, 1 << 16>>();
|
|
using buddy_loc = gp::buddy<>;
|
|
using arena_loc = gp::arena<>;
|
|
buddy_loc bud{&*store->begin(), store->size()};
|
|
arena_loc are{&*store->begin(), store->size()};
|
|
|
|
std::cout << "Allocator | Operation | Divider | Time (µs)" << std::endl;
|
|
|
|
for(size_t divider = 2; divider < 32; ++divider)
|
|
{
|
|
gp::ring_list<int, buddy_loc> a{bud};
|
|
gp::ring_list<int, arena_loc> b{are};
|
|
|
|
std::cout <<
|
|
"ARE | " << "INS | " << divider << " | " <<
|
|
time_operation([&](){
|
|
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int, arena_loc>::node)/divider; i++) {
|
|
b.insert(i);
|
|
}
|
|
}).count() << std::endl;
|
|
|
|
std::cout <<
|
|
"ARE | " << "DEL | " << divider << " | " <<
|
|
time_operation([&](){
|
|
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int, arena_loc>::node)/divider; i++) {
|
|
gp::ring_list<int, arena_loc>::explorer e = b.explore();
|
|
b.remove(e);
|
|
}
|
|
}).count() << std::endl;
|
|
|
|
std::cout <<
|
|
"BUD | " << "INS | " << divider << " | " <<
|
|
time_operation([&](){
|
|
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int, buddy_loc>::node)/divider; i++) {
|
|
a.insert(i);
|
|
}
|
|
}).count() << std::endl;
|
|
|
|
std::cout <<
|
|
"BUD | " << "DEL | " << divider << " | " <<
|
|
time_operation([&](){
|
|
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int, buddy_loc>::node)/divider; i++) {
|
|
gp::ring_list<int, buddy_loc>::explorer e = a.explore();
|
|
a.remove(e);
|
|
}
|
|
}).count() << std::endl;
|
|
}
|
|
{
|
|
gp::ring_list<int, buddy_loc> a{bud};
|
|
gp::ring_list<int, arena_loc> b{are};
|
|
|
|
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int, buddy_loc>::node)/2; i++) {
|
|
a.insert(i);
|
|
}
|
|
|
|
for(size_t i = 0; i < store->size()/sizeof(gp::ring_list<int, buddy_loc>::node)/2; i++) {
|
|
gp::ring_list<int, buddy_loc>::explorer e = a.explore();
|
|
a.remove(++e);
|
|
}
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
};
|
|
|
|
append_test dummy_jhgspo5d5(new alloc_bench_test{});
|
|
|
|
struct indexed_array_stair_test : public test_scaffold {
|
|
indexed_array_stair_test() {
|
|
name = __FILE__ ":13";
|
|
}
|
|
|
|
virtual int run() {
|
|
int res = 0;
|
|
{
|
|
int climb = 0;
|
|
int curr_climb = 0;
|
|
gp::indexed_array<int, 1024> arr;
|
|
while(climb < 1000)
|
|
{
|
|
for(; curr_climb < 10; climb++, curr_climb++ )
|
|
{
|
|
arr.push(climb);
|
|
}
|
|
|
|
for(; curr_climb != 0; curr_climb -= 2) {
|
|
arr.pop(arr.size() - curr_climb);
|
|
}
|
|
|
|
arr.pop(arr.size() - 1);
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
};
|
|
|
|
append_test dummy_amf763ld5(new indexed_array_stair_test{});
|