toyspp

toyspp.git
git clone git://git.lenczewski.org/toyspp.git
Log | Files | Refs | Submodules | README | LICENSE

memory.hpp (2102B)


      1 #ifndef MEMORY_HPP
      2 #define MEMORY_HPP
      3 
      4 #include <cstdint>
      5 #include <cstdlib>
      6 
      7 #include <new>
      8 #include <utility>
      9 
     10 #include "utility.hpp"
     11 
     12 namespace Test::Memory {
     13 	constexpr size_t MEM_ALIGN_4_KIB = 4 * 1024;
     14 	constexpr size_t MEM_ALIGN_2_MIB = 2 * 1024 * 1024;
     15 	constexpr size_t MEM_ALIGN_1_GIB = 1 * 1024 * 1024 * 1024;
     16 
     17 	uint8_t *GenAlloc(size_t size, size_t alignment);
     18 	uint8_t *PageAlloc(size_t size, size_t alignment);
     19 
     20 	struct MirrorAllocResult {
     21 		int memfd;
     22 		uint8_t *ptr;
     23 		size_t len, cap;
     24 	};
     25 
     26 	MirrorAllocResult MirrorAlloc(size_t size, size_t mirrors);
     27 
     28 	struct LinearAlloc {
     29 		void Init(uint8_t *buf, size_t cap);
     30 
     31 		void Reset();
     32 
     33 		uint8_t *AllocRaw(size_t size, size_t alignment);
     34 
     35 		template<typename T, size_t Count = 1, size_t Align = alignof(T)>
     36 		T* Alloc(auto&&... args) {
     37 			uint8_t *buffer = AllocRaw(sizeof(T) * Count, Align);
     38 			if (buffer == nullptr)
     39 				return nullptr;
     40 
     41 			return new (buffer) T(std::forward<decltype(args)>(args)...);
     42 		}
     43 
     44 	private:
     45 		uint8_t *ptr;
     46 		size_t cap, len;
     47 	};
     48 
     49 	struct BlockAlloc {
     50 		void Init(uint8_t *buf, size_t cap, size_t block_size, size_t block_alignment);
     51 
     52 		template <typename T>
     53 		void Init(T *buf, size_t cap) {
     54 			Init((uint8_t *) buf, cap * sizeof(T), sizeof(T), alignof(T));
     55 		}
     56 
     57 		void Reset();
     58 
     59 		uint8_t *AllocRaw();
     60 
     61 		template <typename T>
     62 		T *Alloc(auto&&... args) {
     63 			assert(sizeof(T) <= block_size);
     64 			assert(alignof(T) <= block_alignment);
     65 
     66 			uint8_t *block = AllocRaw();
     67 			if (block == nullptr)
     68 				return nullptr;
     69 
     70 			return new (block) T(std::forward<decltype(args)>(args)...);
     71 		}
     72 
     73 		void Free(uint8_t *ptr);
     74 
     75 	private:
     76 		uint8_t *ptr;
     77 		size_t cap, block_size, block_alignment;
     78 
     79 		struct FreeListNode {
     80 			FreeListNode *next;
     81 		};
     82 
     83 		FreeListNode *freelist;
     84 	};
     85 
     86 	struct StackAlloc {
     87 		void Init(uint8_t *buf, size_t cap);
     88 
     89 		void Reset();
     90 
     91 		struct Result {
     92 			uint8_t *ptr;
     93 			size_t len;
     94 
     95 		private:
     96 			uint8_t *saveptr;
     97 
     98 		friend StackAlloc;
     99 		};
    100 
    101 		Result AllocRaw(size_t size, size_t alignment);
    102 
    103 		void Free(Result region);
    104 
    105 	private:
    106 		uint8_t *ptr;
    107 		size_t cap, len;
    108 	};
    109 }
    110 
    111 #endif /* MEMORY_HPP */