Last active
July 11, 2023 16:43
-
-
Save Marqin/393bc994dab292f6d25914b3509898e5 to your computer and use it in GitHub Desktop.
pools.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//https://isocpp.org/wiki/faq/dtors#memory-pools | |
#include <iostream> | |
#include <exception> | |
#include <map> | |
#include <stdlib.h> | |
// 1 | |
class Pool { | |
public: | |
void* alloc(size_t nbytes) | |
{ | |
return malloc(nbytes); // przyklad, docelowo mmap | |
} | |
void dealloc(void* p) | |
{ | |
free(p); // przyklad | |
} | |
private: | |
// | |
}; | |
struct Foo {}; | |
void example1(Pool& pool) | |
{ | |
Foo* obj = new(pool.alloc(sizeof(Foo))) Foo(); | |
} | |
// 2 | |
inline void* operator new(size_t nbytes, Pool& pool) | |
{ | |
return pool.alloc(nbytes); | |
} | |
void example2(Pool& pool) | |
{ | |
Foo* obj = new(pool) Foo(); | |
} | |
// 3 | |
void example3(Pool& pool) //valgrind | |
{ | |
Foo* p = new(pool) Foo(); | |
p->~Foo(); | |
pool.dealloc(p); | |
} | |
/* | |
problemy: | |
1. exception | |
2. pamietac o dtorze | |
3. pamietac ktora poola | |
*/ | |
// problem 1 | |
// przyklad jak dziala new: | |
void new_example() | |
{ | |
Foo* p; | |
void* raw = operator new(sizeof(Foo)); | |
try | |
{ | |
p = new(raw) Foo(); // call the ctor with raw as this | |
} | |
catch (...) { | |
operator delete(raw); | |
throw; | |
} | |
} | |
// solution, dopisac nowy operator delete: | |
void operator delete(void* p, Pool& pool) // automagical | |
{ | |
pool.dealloc(p); | |
} | |
Pool* getPool(void* p); | |
// problem 2 i 3 mozna zalatwic razem | |
// solution | |
void operator delete(void* p) noexcept | |
{ | |
if (p != NULL) { | |
Pool* pool = getPool(p); // a gdzie te dane mamy? | |
if (pool == NULL) | |
free(p); // a co jesli bylo new a nie malloc ?! | |
else | |
pool->dealloc(p); | |
} | |
} | |
// no to nadpiszmy NEW! | |
void* operator new(size_t nbytes) | |
{ | |
if (nbytes == 0) | |
{ | |
nbytes = 1; | |
} | |
void* raw = malloc(nbytes); | |
return raw; | |
} | |
std::map<void*, Pool*> poolMap; | |
// ale przeciez std::map bedzie uzywac new do tworzenia wartosci i uzyje global new i sie zapetli ERROR | |
// rozwiazanie? dodawac w "operator new(size_t,Pool&)" | |
// BONUS jesli potrzebujemy predkosci! (ale zuzywa wiecej pamieci) | |
// constexpr size_t offset = sizeof(Pool*); | |
// void* operator new(size_t nbytes) | |
// { | |
// if (nbytes == 0) | |
// { | |
// nbytes = 1; | |
// } | |
// void* memory = malloc(nbytes + offset); | |
// *(Pool**)memory = NULL; | |
// return (char*)memory + offset; | |
// } | |
// void* operator new(size_t nbytes, Pool& pool) | |
// { | |
// if (nbytes == 0) | |
// { | |
// nbytes = 1; | |
// } | |
// void* memory = pool.alloc(nbytes + offset); | |
// *(Pool**)memory = &pool; | |
// return (char*)memory + offset; | |
// } | |
// void operator delete(void* p) noexcept | |
// { | |
// if (p != NULL) | |
// { | |
// p = (char*)p - offset; | |
// { | |
// Pool* pool = *(Pool**)p; | |
// if (pool == NULL) | |
// { | |
// free(p); | |
// } | |
// else | |
// { | |
// pool->dealloc(p); | |
// } | |
// } | |
// } | |
// } | |
int main() | |
{ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment