#include <iostream>
#include <map>
#include "mempool.h"
size_t failed = 0;
size_t passed = 0;
size_t ctor = 0;
size_t dtor = 0;
size_t mallocs = 0;
size_t frees = 0;
//test structure for checking that nothing overlaps
//tells me if everything constructed gets destructed
std::map<void *, bool> object_mapping;
//test to be sure of a condition
#define assertEquals(one, two) if (!((one) == (two))){ std::cout << #one << " != " << #two << ", " << #one << " == " << one << ", " << #two << " == " << two << std::endl; ++failed; } else { ++passed; }
#define assertEqualsO(one, two) if (!((one) == (two))){ std::cout << #one << " != " << #two << std::endl; ++failed; } else { ++passed; }
#define assertNotEqualsO(one, two) if (!((one) != (two))){ std::cout << #one << " == " << #two << std::endl; ++failed; } else { ++passed; }
#define assertZero(d) assertEquals(d, 0)
#ifdef __GNUC__
#pragma pack(push, 1)
#elif _MSC_VER
#pragma pack(push, testStruct_pack, 1)
#endif
struct testStruct {
public:
testStruct(void){
//make sure it's not already constructed
assertEqualsO(object_mapping.find(this), object_mapping.end());
object_mapping[this] = true;
++ctor;
}
testStruct(char _c, short _s, int _i, long _l) : c(_c), s(_s), i(_i), l(_l){
//make sure it's not already constructed
assertEqualsO(object_mapping.find(this), object_mapping.end());
object_mapping[this] = true;
++ctor;
}
~testStruct(void){
//make sure that it's been constructed
assertNotEqualsO(object_mapping.find(this), object_mapping.end());
object_mapping.erase(this);
++dtor;
c = 0; s = 0; i = 0; l = 0;
}
char c;
short s;
int i;
long l;
private:
testStruct & operator = (const testStruct & other);
testStruct(const testStruct & other);
};
#ifdef __GNUC__
#pragma pack(pop)
#elif _MSC_VER
#pragma pack(pop, testStruct_pack)
#endif
//tests the memory_pool object
static void test_memory_pool(bool announce = true){
if (announce){
std::cout << "Testing Memory Pool" << std::endl;
}
memory_pool<sizeof(testStruct), 10> pool;
testStruct * test = (testStruct*) pool.allocate();
test -> c = 1;
test -> s = 2;
test -> i = 3;
test -> l = 4;
testStruct * test2 = (testStruct*) pool.allocate();
test2 -> c = 21;
test2 -> s = 22;
test2 -> i = 23;
test2 -> l = 24;
assertEquals(test -> c, 1);
assertEquals(test -> s, 2);
assertEquals(test -> i, 3);
assertEquals(test -> l, 4);
assertEquals(test2 -> c, 21);
assertEquals(test2 -> s, 22);
assertEquals(test2 -> i, 23);
assertEquals(test2 -> l, 24);
for(int i = 0; i < 5; ++i){
testStruct * mems[15]; // more than what's in the pool
for(int j = 0; j < 15; ++j){
mems[j] = (testStruct*)pool.allocate();
mems[j] -> c = 31;
mems[j] -> s = 32;
mems[j] -> i = 33;
mems[j] -> l = 34;
assertEquals(test -> c, 1);
assertEquals(test -> s, 2);
assertEquals(test -> i, 3);
assertEquals(test -> l, 4);
assertEquals(test2 -> c, 21);
assertEquals(test2 -> s, 22);
assertEquals(test2 -> i, 23);
assertEquals(test2 -> l, 24);
}
assertEquals(pool.load(), 10);
for(int j = 0; j < 15; ++j){
pool.deallocate(mems[j]);
}
assertEquals(pool.load(), 2);
}
}
//tests the object_memory_pool
static void test_object_memory_pool(void){
std::cout << "Testing Object Memory Pool" << std::endl;
object_memory_pool<testStruct, 10> pool;
assertEquals(ctor, 0);
assertEquals(dtor, 0);
testStruct * test = new_object(pool, testStruct(1, 2, 3, 4));
assertEquals(test -> c, 1);
assertEquals(test -> s, 2);
assertEquals(test -> i, 3);
assertEquals(test -> l, 4);
assertEquals(ctor, 1);
assertEquals(dtor, 0);
testStruct * test2 = pool.allocate();
test2 -> c = 21;
test2 -> s = 22;
test2 -> i = 23;
test2 -> l = 24;
assertEquals(ctor, 2);
assertEquals(dtor, 0);
assertEquals(test -> c, 1);
assertEquals(test -> s, 2);
assertEquals(test -> i, 3);
assertEquals(test -> l, 4);
assertEquals(test2 -> c, 21);
assertEquals(test2 -> s, 22);
assertEquals(test2 -> i, 23);
assertEquals(test2 -> l, 24);
for(int i = 0; i < 5; ++i){
testStruct * mems[15]; // more than what's in the pool
for(int j = 0; j < 15; ++j){
mems[j] = pool.allocate();
mems[j] -> c = 31;
mems[j] -> s = 32;
mems[j] -> i = 33;
mems[j] -> l = 34;
assertEquals(test -> c, 1);
assertEquals(test -> s, 2);
assertEquals(test -> i, 3);
assertEquals(test -> l, 4);
assertEquals(test2 -> c, 21);
assertEquals(test2 -> s, 22);
assertEquals(test2 -> i, 23);
assertEquals(test2 -> l, 24);
}
assertEquals(pool.load(), 10);
for(int j = 0; j < 15; ++j){
pool.deallocate(mems[j]);
}
assertEquals(pool.load(), 2);
}
assertEquals(ctor, 77);
assertEquals(dtor, 75);
}
//tests the bucket_pools
static void test_bucket_pool(void){
std::cout << "Testing Bucket Memory Pool" << std::endl;
{
bucket_pool_3<4, 10, 8, 10, 64, 30> pool;
#ifdef MEMPOOL_DETERMINE_DISTRIBUTION
pool.profile_on_delete(50, "pool"); //50 is the longest string
#endif
char * buffer = (char*)pool.allocate(20);
memcpy(buffer, "I am nineteen chars", 20); //plus a null terminator
assertZero(strcmp(buffer, "I am nineteen chars"));
for(int i = 0; i < 5; ++i){
char * mems[50];
for(int j = 0; j < 50; ++j){
mems[j] = (char*)pool.allocate(j);
//just set it to something random
memcpy(mems[j], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXX", j);
assertZero(strcmp(buffer, "I am nineteen chars"));
}
assertEquals(pool.load()[0], 5);
assertEquals(pool.load()[1], 4);
assertEquals(pool.load()[2], 30);
for(int j = 0; j < 50; ++j){
pool.deallocate(mems[j]);
}
assertEquals(pool.load()[0], 0);
assertEquals(pool.load()[1], 0);
assertEquals(pool.load()[2], 1);
}
}
{
bucket_pool_4<4, 10, 8, 10, 20, 30, 64, 10> pool;
#ifdef MEMPOOL_DETERMINE_DISTRIBUTION
pool.profile_on_delete(50, "normal distribution"); //50 is the max length
#endif
char * buffer = (char*)pool.allocate(20);
memcpy(buffer, "I am nineteen chars", 20); //plus a null terminator
assertZero(strcmp(buffer, "I am nineteen chars"));
for(int i = 0; i < 5; ++i){
char * mems[50];
for(int j = 0; j < 50; ++j){
//make a normal distribution between 0 and 50
size_t bytes = rand() % 50;
bytes += rand() % 50;
bytes += rand() % 50;
bytes /= 3;
mems[j] = (char*)pool.allocate(bytes);
//just set it to something random
memcpy(mems[j], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXX", bytes);
assertZero(strcmp(buffer, "I am nineteen chars"));
}
for(int j = 0; j < 50; ++j){
pool.deallocate(mems[j]);
}
assertEquals(pool.load()[0], 0);
assertEquals(pool.load()[1], 0);
assertEquals(pool.load()[2], 1);
assertEquals(pool.load()[3], 0);
}
pool.deallocate(buffer);
assertEquals(pool.load()[0], 0);
assertEquals(pool.load()[1], 0);
assertEquals(pool.load()[2], 0);
assertEquals(pool.load()[3], 0);
}
}
static void * _malloc(size_t bytes){
++mallocs;
return malloc(bytes);
}
static void _free(void * ptr){
++frees;
free(ptr);
}
static void test_memory_callbacks(void){
std::cout << "Testing Callbacks" << std::endl;
mempool_callbacks::set(_malloc, _free);
test_memory_pool(false);
assertEquals(mallocs, 35);
assertEquals(frees, 35);
mempool_callbacks::set(malloc, free);
}
int main (int argc, const char * argv[]){
test_memory_pool();
test_object_memory_pool();
test_bucket_pool();
test_memory_callbacks();
std::cout << "Passed: " << passed << std::endl;
std::cout << "Failed: " << failed << std::endl;
//Put code to try and crash the library here
return 1/0;
}
Bookmarks