Skip to content

Instantly share code, notes, and snippets.

@kALLEBALIK
Created November 28, 2019 19:51
Show Gist options
  • Save kALLEBALIK/8d9797399cf3bce8608834472d619f98 to your computer and use it in GitHub Desktop.
Save kALLEBALIK/8d9797399cf3bce8608834472d619f98 to your computer and use it in GitHub Desktop.
#pragma once
template <class T>
class FreeLinkedList
{
public:
struct Node {
T data;
Node* next;
};
FreeLinkedList(FreeLinkedList&) = delete;
FreeLinkedList() = default;
~FreeLinkedList()
{
delete head;
}
void release(Node* new_node)
{
new_node->next = head;
head = new_node;
}
Node* obtain()
{
if (head == nullptr)
return nullptr;
Node* last = head;
head = head->next;
return last;
}
private:
Node* head;
};
#include <iostream>
#include "MemoryPool.h"
#include <iomanip>
int main()
{
struct b8
{
char a1 = 1;
char a2 = 2;
char a3 = 3;
char a4 = 4;
char a5 = 5;
char a6 = 6;
char a7 = 7;
char a8 = 8;
};
struct b16
{
char a1 = 1;
char a2 = 2;
char a3 = 3;
char a4 = 4;
char a5 = 5;
char a6 = 6;
char a7 = 7;
char a8 = 8;
char a11 = 1;
char a22 = 2;
char a33 = 3;
char a44 = 4;
char a55 = 5;
char a66 = 6;
char a77 = 7;
char a88 = 8;
};
std::cout << "-------16-bit-------" << std::endl;
MemoryPool* mp = new MemoryPool(128, 16);
std::cout << "-before-" << std::endl;
mp->print_memory();
std::cout << "-first-" << std::endl;
void* ptr11 = new(mp->allocate(16)) b16();
mp->print_memory();
std::cout << "-second-" << std::endl;
void* ptr12 = new(mp->allocate(16)) b16();
mp->print_memory();
std::cout << "-third-" << std::endl;
void* ptr13 = new(mp->allocate(16)) b16();
mp->print_memory();
std::cout << "-fourth-" << std::endl;
void* ptr14 = new(mp->allocate(16)) b16();
mp->print_memory();
std::cout << "-fifth-" << std::endl;
void* ptr15 = new(mp->allocate(16)) b16();
mp->print_memory();
std::cout << "-sixth-" << std::endl;
void* ptr16 = new(mp->allocate(16)) b16();
std::cout << "-------8-bit-------" << std::endl;
MemoryPool* mp2 = new MemoryPool(64, 8);
std::cout << "-before-" << std::endl;
mp->print_memory();
std::cout << "-first-" << std::endl;
void* bptr11 = new(mp2->allocate(8)) b8();
mp->print_memory();
std::cout << "-second-" << std::endl;
void* bptr12 = new(mp2->allocate(8)) b8();
mp->print_memory();
std::cout << "-third-" << std::endl;
void* bptr13 = new(mp2->allocate(8)) b8();
mp->print_memory();
std::cout << "-fourth-" << std::endl;
void* bptr14 = new(mp2->allocate(8)) b8();
mp->print_memory();
std::cout << "-fifth-" << std::endl;
void* bptr15 = new(mp2->allocate(8)) b8();
mp->print_memory();
std::cout << "-sixth-" << std::endl;
void* bptr16 = new(mp2->allocate(8)) b8();
mp->free(ptr11);
mp->free(ptr12);
mp->free(ptr13);
mp->free(ptr14);
mp->free(ptr15);
mp->free(ptr16);
mp2->free(bptr11);
mp2->free(bptr12);
mp2->free(bptr13);
mp2->free(bptr14);
mp2->free(bptr15);
mp2->free(bptr16);
delete(mp);
delete(mp2);
}
#include "MemoryPool.h"
#include <iostream>
#include <iomanip>
void MemoryPool::increment() { this->used_size += this->block_size; }
void MemoryPool::decrement() { this->used_size -= this->block_size; }
MemoryPool::MemoryPool(const size_t total_size, const size_t block_size)
{
this->total_size = total_size;
this->block_size = block_size;
this->start_pointer = malloc(this->total_size);
reset();
}
MemoryPool::~MemoryPool()
{
if (this->start_pointer != nullptr)
free(this->start_pointer);
}
void MemoryPool::reset()
{
const size_t block_count = this->total_size / this->block_size;
for (unsigned int i = 0; i < block_count; ++i)
{
this->used_size = 0;
const size_t mem_address = reinterpret_cast<size_t>(this->start_pointer) + i * block_size;
free_list.release(reinterpret_cast<Node*>(mem_address));
}
}
void* MemoryPool::allocate(const size_t size, const size_t alignment)
{
Node* free_position = free_list.obtain();
this->increment();
return (void*)free_position;
}
void MemoryPool::free(void* ptr)
{
this->decrement();
free_list.release((Node*)ptr);
}
void MemoryPool::print_memory_range(void* ptr, const size_t range) const
{
for (size_t k = 0; k < range; ++k)
{
printf("%02hhx ", *reinterpret_cast<unsigned char*>(reinterpret_cast<size_t>(ptr) + k));
}
}
void MemoryPool::print_memory() const
{
for (size_t i = 0; i < total_size; i += block_size)
{
std::cout << "0x" << std::hex << std::noshowbase << std::setw(16) << std::setfill('0') << reinterpret_cast<size_t>(this->start_pointer) + i << ": ";
print_memory_range(reinterpret_cast<void*>(reinterpret_cast<size_t>(this->start_pointer) + i), this->block_size);
std::cout << std::endl;
}
}
#include "FreeLinkedList.h"
class MemoryPool
{
struct FreeHeader {};
using Node = FreeLinkedList<FreeHeader>::Node;
FreeLinkedList<FreeHeader> free_list;
size_t total_size;
size_t used_size;
size_t block_size;
void* start_pointer;
void increment();
void decrement();
void reset();
public:
MemoryPool(const size_t total_size, const size_t block_size);
~MemoryPool();
void* allocate(const size_t size, const size_t alignment = 0);
void free(void* ptr);
void print_memory_range(void* ptr, const size_t range) const;
void print_memory() const;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment