Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "toyalloc.hpp"
- #include <twist/stdlike/atomic.hpp>
- #include <twist/support/compiler.hpp>
- #include <twist/support/locking.hpp>
- #include <pthread.h>
- #include <sys/types.h>
- #include <unistd.h>
- using twist::MemSpan;
- using twist::MmapAllocation;
- namespace toyalloc {
- static const size_t kBlockSize = 4096;
- struct BlockNode {
- BlockNode* next_;
- };
- class Allocator {
- public:
- friend void ForkPrepare(void);
- friend void ChildAfterFork(void);
- friend void ParentAfterFork(void);
- void Init(MmapAllocation arena) {
- arena_ = std::move(arena);
- list_head = arena_.Start();
- char* current_ptr = reinterpret_cast<char*>(list_head);
- for (size_t i = 0; i < arena_.Size() / kBlockSize; ++i) {
- void** next_ptr = reinterpret_cast<void**>(current_ptr);
- current_ptr += kBlockSize;
- if (current_ptr < arena_.End()) {
- *next_ptr = current_ptr;
- } else {
- *next_ptr = nullptr;
- }
- }
- }
- MemSpan GetArena() const {
- return arena_.AsMemSpan();
- }
- void* Allocate() {
- // printf("%s %d ", "allocate begin", getpid());
- // fflush(stdout);
- // auto lck = twist::LockUnique(mutex);
- mutex.lock();
- // printf("%s %d ", "mutex lock", getpid());
- // fflush(stdout);
- void* result = nullptr;
- if (list_head != nullptr) {
- result = list_head;
- list_head = *reinterpret_cast<void**>(list_head);
- }
- // printf("%s %d \n", "finish", getpid());
- // fflush(stdout);
- mutex.unlock();
- return result;
- }
- void Free(void* addr) {
- // printf("%s %d ", "free begin", getpid());
- // fflush(stdout);
- // auto lck = twist::LockUnique(mutex);
- // printf("%s %d ", "mutex lock", getpid());
- // fflush(stdout);
- mutex.lock();
- *reinterpret_cast<void**>(addr) = list_head;
- list_head = addr;
- TWIST_UNUSED(addr);
- mutex.unlock();
- // printf("%s %d \n", "finish", getpid());
- // fflush(stdout);
- }
- private:
- MmapAllocation arena_;
- void* list_head = nullptr;
- std::mutex mutex;
- };
- /////////////////////////////////////////////////////////////////////
- static Allocator allocator;
- /////////////////////////////////////////////////////////////////////
- void ForkPrepare(void) {
- // auto lck = twist::LockUnique(allocator.mutex);
- allocator.mutex.lock();
- // printf("%s %d \n", "prepare", getpid());
- // fflush(stdout);
- }
- void ChildAfterFork(void) {
- allocator.mutex.unlock();
- // printf("%s %d \n", "after", getpid());
- // fflush(stdout);
- }
- void ParentAfterFork(void) {
- allocator.mutex.unlock();
- // printf("%s %d \n", "after", getpid());
- // fflush(stdout);
- }
- void Init(MmapAllocation arena) {
- allocator.Init(std::move(arena));
- pthread_atfork(&ForkPrepare, &ParentAfterFork,
- &ChildAfterFork);
- }
- MemSpan GetArena() {
- return allocator.GetArena();
- }
- size_t GetBlockSize() {
- return kBlockSize;
- }
- void* Allocate() {
- return allocator.Allocate();
- }
- void Free(void* addr) {
- allocator.Free(addr);
- }
- } // namespace toyalloc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement