Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/WolfireGames/overgrowth.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Utility/block_allocator.h')
-rw-r--r--Source/Utility/block_allocator.h153
1 files changed, 153 insertions, 0 deletions
diff --git a/Source/Utility/block_allocator.h b/Source/Utility/block_allocator.h
new file mode 100644
index 00000000..49d8d5eb
--- /dev/null
+++ b/Source/Utility/block_allocator.h
@@ -0,0 +1,153 @@
+//-----------------------------------------------------------------------------
+// Name: block_allocator.h
+// Developer: Wolfire Games LLC
+// Description:
+// License: Read below
+//-----------------------------------------------------------------------------
+//
+// Copyright 2022 Wolfire Games LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-----------------------------------------------------------------------------
+#pragma once
+
+#include <iostream>
+#include <string>
+#include <thread>
+#include <mutex>
+#include <cstdint>
+#include <cstring>
+
+class BlockAlloctorThreadSafe {
+private:
+ struct DebugAllocationData {
+ uint32_t line;
+ const char* filename;
+ uint32_t allocationSize;
+ bool watched;
+ bool taken;
+
+
+
+ friend std::ostream& operator<<(std::ostream& os, const DebugAllocationData& data) {
+ os << data.filename << "\t: " << data.line << " size: " << data.allocationSize;
+
+ return os;
+ }
+ };
+ uint32_t size;
+ uint16_t blockSize;
+ uint32_t nrOfBlocks;
+ uint32_t nr_of_allocations;
+ DebugAllocationData * allocations; // tracks allocations from block number in size. Rounded to blocksize
+ bool * bitmap; // tracks free blocks
+ std::mutex bitmapLock;
+ uint8_t * pool;
+public:
+ BlockAlloctorThreadSafe(uint32_t size = 4096, uint16_t blockSize = 256); // size is initalize size of the avaiable pool of bytes
+ ~BlockAlloctorThreadSafe();
+
+ uint32_t GetSize() const;
+ uint32_t GetNrOfBlocks() const;
+
+ //uint8_t * Allocate(uint32_t size);
+
+ uint8_t* Allocate(uint32_t size, uint32_t line, const char * file, bool watched = false);
+
+ template <class T>
+ void DeAllocate(T* addr);
+
+ template<class T>
+ void DeAllocate(T* addr, uint32_t line, const char* file);
+
+ template <class T>
+ T* ReAllocate(T* addr, uint32_t size);
+
+private:
+ int32_t FindFirstFreeBlock(uint32_t size);
+
+};
+
+template<class T>
+void BlockAlloctorThreadSafe::DeAllocate(T * addr) {
+ std::lock_guard<std::mutex> guard(bitmapLock); // we can probably do without this in overgrowth.
+
+
+ nr_of_allocations--;
+
+ int32_t bytesFromStart = (int32_t)((uint8_t*)addr - pool); // we need to do some magic to make sure it's on block start.
+
+ if (bytesFromStart > size || bytesFromStart < 0) {
+ std::cout << "YOU DE-ALLOCATED AN ADDRES THAT WAS NEVER ALLOCATED" << std::endl;
+ return;
+ }
+
+
+
+ uint32_t startOfBlock = bytesFromStart / blockSize; // maybe warning here instead of solving a potential user error
+
+ if (allocations[startOfBlock].watched) {
+ std::cout << " deallocated from: " << allocations[startOfBlock].filename << " line: " << allocations[startOfBlock].line << std::endl;
+ }
+
+ if (allocations[startOfBlock].taken) {
+ for (uint32_t i = 0; i < allocations[startOfBlock].allocationSize / blockSize ; i++)
+ bitmap[((i * blockSize) + bytesFromStart) / blockSize] = false;
+
+ allocations[startOfBlock].taken = false;
+ }
+}
+
+template<class T>
+void BlockAlloctorThreadSafe::DeAllocate(T* addr, uint32_t line, const char* file) {
+
+ std::lock_guard<std::mutex> guard(bitmapLock); // we can probably do without this in overgrowth.
+ int32_t bytesFromStart = (int32_t)((uint8_t*)addr - pool); // we need to do some magic to make sure it's on block start.
+
+ if (bytesFromStart > size || bytesFromStart < 0) {
+ std::cout << "Deallocated line: " << line << " in file: " << file << " which where never allocated." << std::endl;
+ return;
+ }
+
+ nr_of_allocations--;
+
+ uint32_t startOfBlock = bytesFromStart / blockSize; // maybe warning here instead of solving a potential user error
+
+ if (allocations[startOfBlock].taken) {
+
+ DebugAllocationData temp = allocations[startOfBlock];
+
+ if (temp.watched) {
+ std::cout << " allocated from: " << temp.filename << " line: " << temp.line <<
+ " deallocated from: " << file << " on line " << line << std::endl;
+ }
+
+
+
+ for (uint32_t i = 0; i < allocations[startOfBlock].allocationSize / blockSize; i++)
+ bitmap[((i * blockSize) + bytesFromStart) / blockSize] = false;
+
+ allocations[startOfBlock].taken = false;
+ }
+ else {
+ std::cout << "No allocation where deallocated" << std::endl;
+ }
+}
+
+template<class T>
+T* BlockAlloctorThreadSafe::ReAllocate(T * addr, uint32_t size) {
+ DeAllocate(addr);
+
+ return Allocate(addr, size);
+}