Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // START FILE: destructorcall.h
- #pragma once
- template <typename T>
- void DestructorCall(void *ptr)
- {
- ((T*)ptr)->~T();
- }
- // START FILE: finalizer.h
- #pragma once
- struct Finalizer; // fwd decl
- typedef void (finalizer_function_t)(void*);
- #define GET_FINALIZER_OBJECT(f) (((uint8_t*)f) + ALIGNED_SIZE(sizeof(Finalizer)))
- struct Finalizer
- {
- finalizer_function_t* function;
- Finalizer* chain;
- };
- // START FILE: linearallocator.h
- #pragma once
- #include "../types.h"
- #include "../Async/lock.h"
- static const size_t kLinearAllocatorMemoryAlignment = 16;
- #define ALIGNED_SIZE(size) ((size + (kLinearAllocatorMemoryAlignment - 1)) & ~(kLinearAllocatorMemoryAlignment - 1))
- class LinearAllocator
- {
- uint8_t* m_Cursor;
- uint8_t* m_End;
- Lock m_Lock;
- public:
- LinearAllocator(void* buffer, size_t buffer_size);
- void* Allocate(size_t size);
- void RewindCursor(void* cursor_position);
- void* GetCursor(void) const;
- };
- // START FILE: linearallocator.cpp
- #include <assert.h>
- #include "linearallocator.h"
- LinearAllocator::LinearAllocator(void* buffer, size_t buffer_size)
- {
- assert(nullptr != buffer);
- assert(buffer_size > 0);
- m_Lock.Acquire();
- {
- m_Cursor = (uint8_t*)buffer;
- m_End = m_Cursor + buffer_size;
- }
- m_Lock.Release();
- }
- void* LinearAllocator::Allocate(size_t size)
- {
- size = ALIGNED_SIZE(size);
- uint8_t* result = nullptr;
- // Lock to preserve the value of m_Cursor during allocation:
- m_Lock.Acquire();
- {
- result = m_Cursor;
- assert(m_Cursor + size <= m_End);
- m_Cursor = m_Cursor + size;
- }
- m_Lock.Release();
- return result;
- }
- void LinearAllocator::RewindCursor(void* cursor_position)
- {
- assert(nullptr != cursor_position);
- assert(cursor_position < m_End);
- // Lock to prevent allocation while rewinding:
- m_Lock.Acquire();
- {
- m_Cursor = (uint8_t*)cursor_position;
- }
- m_Lock.Release();
- }
- void* LinearAllocator::GetCursor(void) const
- {
- return m_Cursor;
- }
- // START FILE: scopestack.h
- #pragma once
- #include "./linearallocator.h"
- #include "./finalizer.h"
- #include "./destructorcall.h"
- #include "../Async/lock.h"
- #ifndef STACK_NEW
- #include <new>
- #define STACK_NEW(type, sa, ...) (type*)new (sa.AllocateObject(sizeof(type), &DestructorCall<type>)) type(__VA_ARGS__);
- #endif
- class ScopeStack
- {
- LinearAllocator& m_Allocator;
- void* m_RewindCursorPosition;
- Finalizer* m_FinalizerChain;
- Lock m_FinalizerChainLock;
- /**
- Included to make the compiler shut up with /W4.
- */
- ScopeStack& operator = (const ScopeStack&) { return *this; /* yeah, no. */ };
- public:
- explicit ScopeStack(LinearAllocator& allocator);
- ~ScopeStack(void);
- void* Allocate(unsigned int size);
- void* AllocateObject(size_t size, finalizer_function_t* ptr);
- };
- // START FILE: scopestack.cpp
- #include "scopestack.h"
- #include "linearallocator.h"
- #include "finalizer.h"
- #include "destructorcall.h"
- ScopeStack::ScopeStack(LinearAllocator& allocator)
- : m_Allocator(allocator),
- m_RewindCursorPosition(allocator.GetCursor()),
- m_FinalizerChain(nullptr)
- {
- return;
- }
- ScopeStack::~ScopeStack(void)
- {
- m_FinalizerChainLock.Acquire();
- for (auto f = m_FinalizerChain; nullptr != f; f = f->chain)
- {
- (*f->function)(GET_FINALIZER_OBJECT(f));
- }
- m_FinalizerChainLock.Release();
- m_Allocator.RewindCursor(m_RewindCursorPosition);
- }
- void* ScopeStack::Allocate(unsigned int size)
- {
- return m_Allocator.Allocate(size);
- }
- void* ScopeStack::AllocateObject(size_t size, finalizer_function_t* ptr)
- {
- auto finalizer = (Finalizer*)m_Allocator.Allocate(size + ALIGNED_SIZE(sizeof(Finalizer)));
- finalizer->function = ptr;
- m_FinalizerChainLock.Acquire();
- {
- finalizer->chain = m_FinalizerChain;
- m_FinalizerChain = finalizer;
- }
- m_FinalizerChainLock.Release();
- return GET_FINALIZER_OBJECT(finalizer);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement