Advertisement
EddyLuten

Full ScopeStack Source

Oct 8th, 2011
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.90 KB | None | 0 0
  1. // START FILE: destructorcall.h
  2. #pragma once
  3.  
  4. template <typename T>
  5. void DestructorCall(void *ptr)
  6. {
  7.   ((T*)ptr)->~T();
  8. }
  9.  
  10.  
  11.  
  12.  
  13. // START FILE: finalizer.h
  14. #pragma once
  15. struct Finalizer; // fwd decl
  16. typedef void (finalizer_function_t)(void*);
  17. #define GET_FINALIZER_OBJECT(f) (((uint8_t*)f) + ALIGNED_SIZE(sizeof(Finalizer)))
  18.  
  19. struct Finalizer
  20. {
  21.   finalizer_function_t* function;
  22.   Finalizer* chain;
  23. };
  24.  
  25.  
  26.  
  27.  
  28. // START FILE: linearallocator.h
  29. #pragma once
  30. #include "../types.h"
  31. #include "../Async/lock.h"
  32.  
  33. static const size_t kLinearAllocatorMemoryAlignment = 16;
  34. #define ALIGNED_SIZE(size) ((size + (kLinearAllocatorMemoryAlignment - 1)) & ~(kLinearAllocatorMemoryAlignment - 1))
  35.  
  36. class LinearAllocator
  37. {
  38.   uint8_t* m_Cursor;
  39.   uint8_t* m_End;
  40.   Lock m_Lock;
  41.  
  42. public:
  43.   LinearAllocator(void* buffer, size_t buffer_size);
  44.  
  45.   void* Allocate(size_t size);
  46.   void RewindCursor(void* cursor_position);
  47.   void* GetCursor(void) const;
  48. };
  49.  
  50.  
  51.  
  52.  
  53. // START FILE: linearallocator.cpp
  54. #include <assert.h>
  55. #include "linearallocator.h"
  56.  
  57. LinearAllocator::LinearAllocator(void* buffer, size_t buffer_size)
  58. {
  59.   assert(nullptr != buffer);
  60.   assert(buffer_size > 0);
  61.  
  62.   m_Lock.Acquire();
  63.   {
  64.     m_Cursor = (uint8_t*)buffer;
  65.     m_End = m_Cursor + buffer_size;
  66.   }
  67.   m_Lock.Release();
  68. }
  69.  
  70. void* LinearAllocator::Allocate(size_t size)
  71. {
  72.   size = ALIGNED_SIZE(size);
  73.   uint8_t* result = nullptr;
  74.  
  75.   // Lock to preserve the value of m_Cursor during allocation:
  76.   m_Lock.Acquire();
  77.   {
  78.     result = m_Cursor;
  79.     assert(m_Cursor + size <= m_End);
  80.     m_Cursor = m_Cursor + size;
  81.   }
  82.   m_Lock.Release();
  83.  
  84.   return result;
  85. }
  86.  
  87. void LinearAllocator::RewindCursor(void* cursor_position)
  88. {
  89.   assert(nullptr != cursor_position);
  90.   assert(cursor_position < m_End);
  91.  
  92.   // Lock to prevent allocation while rewinding:
  93.   m_Lock.Acquire();
  94.   {
  95.     m_Cursor = (uint8_t*)cursor_position;
  96.   }
  97.   m_Lock.Release();
  98. }
  99.  
  100. void* LinearAllocator::GetCursor(void) const
  101. {
  102.   return m_Cursor;
  103. }
  104.  
  105.  
  106.  
  107.  
  108. // START FILE: scopestack.h
  109. #pragma once
  110. #include "./linearallocator.h"
  111. #include "./finalizer.h"
  112. #include "./destructorcall.h"
  113. #include "../Async/lock.h"
  114.  
  115. #ifndef STACK_NEW
  116. #include <new>
  117. #define STACK_NEW(type, sa, ...) (type*)new (sa.AllocateObject(sizeof(type), &DestructorCall<type>)) type(__VA_ARGS__);
  118. #endif
  119.  
  120. class ScopeStack
  121. {
  122.   LinearAllocator& m_Allocator;
  123.   void* m_RewindCursorPosition;
  124.   Finalizer* m_FinalizerChain;
  125.   Lock m_FinalizerChainLock;
  126.  
  127.   /**
  128.   Included to make the compiler shut up with /W4.
  129.   */
  130.   ScopeStack& operator = (const ScopeStack&) { return *this; /* yeah, no. */ };
  131.  
  132. public:
  133.   explicit ScopeStack(LinearAllocator& allocator);
  134.   ~ScopeStack(void);
  135.  
  136.   void* Allocate(unsigned int size);
  137.   void* AllocateObject(size_t size, finalizer_function_t* ptr);
  138. };
  139.  
  140.  
  141.  
  142.  
  143. // START FILE: scopestack.cpp
  144. #include "scopestack.h"
  145. #include "linearallocator.h"
  146. #include "finalizer.h"
  147. #include "destructorcall.h"
  148.  
  149. ScopeStack::ScopeStack(LinearAllocator& allocator)
  150.   :  m_Allocator(allocator),
  151.      m_RewindCursorPosition(allocator.GetCursor()),
  152.      m_FinalizerChain(nullptr)
  153. {
  154.   return;
  155. }
  156.  
  157. ScopeStack::~ScopeStack(void)
  158. {
  159.   m_FinalizerChainLock.Acquire();
  160.     for (auto f = m_FinalizerChain; nullptr != f; f = f->chain)
  161.     {
  162.       (*f->function)(GET_FINALIZER_OBJECT(f));
  163.     }
  164.   m_FinalizerChainLock.Release();
  165.  
  166.   m_Allocator.RewindCursor(m_RewindCursorPosition);
  167. }
  168.  
  169. void* ScopeStack::Allocate(unsigned int size)
  170. {
  171.   return m_Allocator.Allocate(size);
  172. }
  173.  
  174. void* ScopeStack::AllocateObject(size_t size, finalizer_function_t* ptr)
  175. {
  176.   auto finalizer = (Finalizer*)m_Allocator.Allocate(size + ALIGNED_SIZE(sizeof(Finalizer)));
  177.   finalizer->function = ptr;
  178.  
  179.   m_FinalizerChainLock.Acquire();
  180.   {
  181.     finalizer->chain = m_FinalizerChain;
  182.     m_FinalizerChain = finalizer;
  183.   }
  184.   m_FinalizerChainLock.Release();
  185.  
  186.   return GET_FINALIZER_OBJECT(finalizer);
  187. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement