Explorar el Código

Using the allocation header in SafePointer from Buffer and making sure that it is inherited in slices.

David Piuva hace 11 meses
padre
commit
1f7d26a807

+ 0 - 1
Source/DFPSR/api/bufferAPI.cpp

@@ -25,7 +25,6 @@
 #include "bufferAPI.h"
 #include "bufferAPI.h"
 #include "stringAPI.h"
 #include "stringAPI.h"
 #include "../math/scalar.h"
 #include "../math/scalar.h"
-#include "../base/heap.h"
 
 
 namespace dsr {
 namespace dsr {
 
 

+ 2 - 1
Source/DFPSR/api/bufferAPI.h

@@ -29,6 +29,7 @@
 #include <functional>
 #include <functional>
 #include "../base/SafePointer.h"
 #include "../base/SafePointer.h"
 #include "../settings.h"
 #include "../settings.h"
+#include "../base/heap.h"
 
 
 // The types of buffer handles to consider when designing algorithms:
 // The types of buffer handles to consider when designing algorithms:
 // * Null handle suggesting that there is nothing, such as when loading a file failed.
 // * Null handle suggesting that there is nothing, such as when loading a file failed.
@@ -109,7 +110,7 @@ namespace dsr {
 			return SafePointer<T>();
 			return SafePointer<T>();
 		} else {
 		} else {
 			uint8_t *data = buffer_dangerous_getUnsafeData(buffer);
 			uint8_t *data = buffer_dangerous_getUnsafeData(buffer);
-			return SafePointer<T>(name, (T*)data, buffer_getSize(buffer), (T*)data);
+			return SafePointer<T>(name, (T*)data, buffer_getSize(buffer), (T*)data, heap_getHeader(data));
 		}
 		}
 	}
 	}
 
 

+ 6 - 2
Source/DFPSR/base/SafePointer.h

@@ -86,6 +86,10 @@ public:
 	SafePointer(const char* name, T* regionStart, intptr_t regionByteSize, T* data, AllocationHeader *header = nullptr)
 	SafePointer(const char* name, T* regionStart, intptr_t regionByteSize, T* data, AllocationHeader *header = nullptr)
 	: data(data), regionStart(regionStart), regionEnd((T*)(((uint8_t*)regionStart) + (intptr_t)regionByteSize)), name(name), header(header) {
 	: data(data), regionStart(regionStart), regionEnd((T*)(((uint8_t*)regionStart) + (intptr_t)regionByteSize)), name(name), header(header) {
 		assertNonNegativeSize(regionByteSize);
 		assertNonNegativeSize(regionByteSize);
+		// If the pointer has a header, then store the allocation's identity in the pointer.
+		if (header != nullptr) {
+			this->allocationIdentity = header->allocationIdentity;
+		}
 	}
 	}
 	#else
 	#else
 	SafePointer() : data(nullptr) {}
 	SafePointer() : data(nullptr) {}
@@ -143,7 +147,7 @@ public:
 		T *newStart = (T*)(((uint8_t*)(this->data)) + byteOffset);
 		T *newStart = (T*)(((uint8_t*)(this->data)) + byteOffset);
 		#ifdef SAFE_POINTER_CHECKS
 		#ifdef SAFE_POINTER_CHECKS
 		assertInside("getSlice", newStart, size);
 		assertInside("getSlice", newStart, size);
-		return SafePointer<T>(name, newStart, size);
+		return SafePointer<T>(name, newStart, size, this->header);
 		#else
 		#else
 		return SafePointer<T>(name, newStart);
 		return SafePointer<T>(name, newStart);
 		#endif
 		#endif
@@ -152,7 +156,7 @@ public:
 		T *newStart = (T*)(((uint8_t*)(this->data)) + byteOffset);
 		T *newStart = (T*)(((uint8_t*)(this->data)) + byteOffset);
 		#ifdef SAFE_POINTER_CHECKS
 		#ifdef SAFE_POINTER_CHECKS
 		assertInside("getSlice", newStart, size);
 		assertInside("getSlice", newStart, size);
-		return SafePointer<T>(name, newStart, size);
+		return SafePointer<T>(name, newStart, size, this->header);
 		#else
 		#else
 		return SafePointer<T>(name, newStart);
 		return SafePointer<T>(name, newStart);
 		#endif
 		#endif

+ 8 - 4
Source/DFPSR/base/heap.cpp

@@ -72,15 +72,19 @@ namespace dsr {
 	};
 	};
 	static const uintptr_t heapHeaderPaddedSize = memory_getPaddedSize(sizeof(HeapHeader), heapAlignment);
 	static const uintptr_t heapHeaderPaddedSize = memory_getPaddedSize(sizeof(HeapHeader), heapAlignment);
 
 
-	inline HeapHeader *headerFromAllocation(uint8_t* allocation) {
+	AllocationHeader *heap_getHeader(uint8_t const * const allocation) {
+		return (AllocationHeader*)(allocation - heapHeaderPaddedSize);
+	}
+
+	inline HeapHeader *headerFromAllocation(uint8_t const * const allocation) {
 		return (HeapHeader*)(allocation - heapHeaderPaddedSize);
 		return (HeapHeader*)(allocation - heapHeaderPaddedSize);
 	}
 	}
 
 
-	inline uint8_t *allocationFromHeader(HeapHeader* header) {
+	inline uint8_t *allocationFromHeader(HeapHeader const * const header) {
 		return (uint8_t*)header + heapHeaderPaddedSize;
 		return (uint8_t*)header + heapHeaderPaddedSize;
 	}
 	}
 
 
-	uint64_t heap_getAllocationSize(uint8_t* allocation) {
+	uint64_t heap_getAllocationSize(uint8_t const * const allocation) {
 		return headerFromAllocation(allocation)->totalSize - heapHeaderPaddedSize;
 		return headerFromAllocation(allocation)->totalSize - heapHeaderPaddedSize;
 	}
 	}
 
 
@@ -196,7 +200,7 @@ namespace dsr {
 		return result;
 		return result;
 	}
 	}
 
 
-	void heap_free(uint8_t *allocation) {
+	void heap_free(uint8_t * const allocation) {
 		defaultHeap.poolLock.lock();
 		defaultHeap.poolLock.lock();
 		if (!(defaultHeap.terminating)) {
 		if (!(defaultHeap.terminating)) {
 			HeapHeader *header = (HeapHeader*)(allocation - heapHeaderPaddedSize);
 			HeapHeader *header = (HeapHeader*)(allocation - heapHeaderPaddedSize);

+ 6 - 28
Source/DFPSR/base/heap.h

@@ -27,24 +27,6 @@
 #include "SafePointer.h"
 #include "SafePointer.h"
 
 
 namespace dsr {
 namespace dsr {
-	// TODO: Implement reference counting and connect a thread-safe handle type to replace std::shared_ptr.
-	//       This should build on top of a fixed size allocator that pre-computes which recycling bin to use.
-	//       Handles could be able to contain multiple elements with the same reference counter, which is useful for giving buffers value heads in images for faster access.
-	// TODO: Return the allocation size in UnsafeAllocation, to avoid extra calls to heap_getAllocationSize?
-	// TODO: Create a faster and simpler allocator for things that never live past a function call or frame.
-	//       Then you just free the whole thing when done with the allocations.
-	//       Good for small images and fixed size heads, but bad for lists being reallocated many times that should recycle memory instead.
-	//       A temporary allocator can then only allocate one thing at a time or free all allocations.
-	//       A fixed size can guarantee that there is no heap allocation done at runtime.
-	//       A dynamic size can have more memory added when needed.
-	//       In debug mode, each allocation will be properly destructed.
-	//       In release mode, everything is just left as it is.
-	//       The caller allocating memory decides if the memory should be cleared or not.
-	//       A thread local version would not need any locks, but should still align with cache lines for consistency with regular heap allocations.
-	// TODO: Allow reserving heap allocations for a specific thread to prevent accidental sharing.
-	//       This can have a separate memory pool in thread local memory to avoid using a mutex.
-	//       The thread local storage can be used for small allocations, while larger allocations can be placed among the shared memory.
-
 	// Allocate memory in the heap.
 	// Allocate memory in the heap.
 	//   The size argument is the minimum number of bytes to allocate, but the result may give you more than you asked for.
 	//   The size argument is the minimum number of bytes to allocate, but the result may give you more than you asked for.
 	// Post-condition: Returns pointers to the payload and header.
 	// Post-condition: Returns pointers to the payload and header.
@@ -55,7 +37,11 @@ namespace dsr {
 	//                 You may not read a single byte outside of it, because it might include padding that ends at uneven addresses.
 	//                 You may not read a single byte outside of it, because it might include padding that ends at uneven addresses.
 	//                 To use more memory than requested, you must round it down to whole elements.
 	//                 To use more memory than requested, you must round it down to whole elements.
 	//                 If the element's size is a power of two, you can pre-compute a bit mask using memory_createAlignmentAndMask for rounding down.
 	//                 If the element's size is a power of two, you can pre-compute a bit mask using memory_createAlignmentAndMask for rounding down.
-	uint64_t heap_getAllocationSize(uint8_t* allocation);
+	uint64_t heap_getAllocationSize(uint8_t const * const allocation);
+
+	// Pre-condition: The allocation pointer must point to the start of a payload allocated using heap_allocate, no offsets nor other allocators allowed.
+	// Post-condition: Returns a pointer to the heap allocation's header, which is used to construct safe pointers.
+	AllocationHeader *heap_getHeader(uint8_t const * const allocation);
 
 
 	// Only a pointer is needed, so that it can be sent as a function pointer to X11.
 	// Only a pointer is needed, so that it can be sent as a function pointer to X11.
 	// TODO: Use the allocation head's alignment as the minimum alignment by combining the masks in compile time.
 	// TODO: Use the allocation head's alignment as the minimum alignment by combining the masks in compile time.
@@ -63,15 +49,7 @@ namespace dsr {
 	//       No extra offsets are allowed on the pointer used to free the memory.
 	//       No extra offsets are allowed on the pointer used to free the memory.
 	// TODO: Have a global variable containing the default memory pool.
 	// TODO: Have a global variable containing the default memory pool.
 	//       When it is destructed, all allocations that are empty will be freed and a termination flag will be enabled so that any more allocations being freed after it will free the memory themselves.
 	//       When it is destructed, all allocations that are empty will be freed and a termination flag will be enabled so that any more allocations being freed after it will free the memory themselves.
-	void heap_free(uint8_t *allocation);
-
-	/*
-	// TODO: Apply additional safety checks when freeing the allocation using SafePointer, making sure that the correct allocation is freed.
-	template <typename T>
-	void heap_free(SafePointer<T> allocation) {
-		
-	}
-	*/
+	void heap_free(uint8_t * const allocation);
 }
 }
 
 
 #endif
 #endif