From d36d3610ca1a8e16007c0391a225b1f66fb7e8a2 Mon Sep 17 00:00:00 2001 From: Maschell Date: Tue, 28 Sep 2021 17:58:20 +0200 Subject: [PATCH] Use a global spinlock to lock the alloc/free functions --- source/CThread.h | 2 +- source/main.cpp | 4 ++-- source/memory_mapping.cpp | 45 +++++++++++++++++---------------------- source/memory_mapping.h | 14 ++++++------ 4 files changed, 29 insertions(+), 36 deletions(-) diff --git a/source/CThread.h b/source/CThread.h index 0ff1ce8..d5e8194 100644 --- a/source/CThread.h +++ b/source/CThread.h @@ -101,7 +101,7 @@ public: } //! Shutdown thread - virtual void shutdownThread() { + void shutdownThread() { //! wait for thread to finish if (pThread && !(iAttributes & eAttributeDetach)) { while (isThreadSuspended()) { diff --git a/source/main.cpp b/source/main.cpp index bfe17d7..e3a39d4 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -68,13 +68,13 @@ void *MemoryMappingAlloc(uint32_t size) { return res; } -void *MemoryMappingAllocEx(uint32_t size, uint32_t align) { +void *MemoryMappingAllocEx(uint32_t size, int32_t align) { void *res = MemoryMapping_alloc(size, align); //DEBUG_FUNCTION_LINE("[res %08X] allocEX %d %d ", res, size, align); return res; } -void *MemoryMappingAllocForGX2Ex(uint32_t size, uint32_t align) { +void *MemoryMappingAllocForGX2Ex(uint32_t size, int32_t align) { void *res = MemoryMapping_allocVideoMemory(size, align); //DEBUG_FUNCTION_LINE("[res %08X] allocEX %d %d ", res, size, align); return res; diff --git a/source/memory_mapping.cpp b/source/memory_mapping.cpp index 24af2dd..52ac7e2 100644 --- a/source/memory_mapping.cpp +++ b/source/memory_mapping.cpp @@ -13,6 +13,8 @@ #include #include +OSSpinLock allocFreeSpinlock; + // #define DEBUG_FUNCTION_LINE(x,...) void runOnAllCores(CThread::Callback callback, void *callbackArg, int32_t iAttr = 0, int32_t iPriority = 16, int32_t iStackSize = 0x8000) { @@ -382,17 +384,22 @@ void MemoryMapping_setupMemoryMapping() { //runOnAllCores(writeSegmentRegister,&srTableCpy); } -void *MemoryMapping_alloc(uint32_t size, uint32_t align) { +void *MemoryMapping_allocEx(uint32_t size, int32_t align, bool videoOnly) { + OSUninterruptibleSpinLock_Acquire(&allocFreeSpinlock); void *res = nullptr; for (int32_t i = 0; /* waiting for a break */; i++) { if (mem_mapping[i].physical_addresses == nullptr) { break; } - auto heapHandle = (MEMHeapHandle) mem_mapping[i].effective_start_address; + uint32_t effectiveAddress = mem_mapping[i].effective_start_address; + auto heapHandle = (MEMHeapHandle) effectiveAddress; auto *heap = (MEMExpHeap *) heapHandle; - auto header = (MEMHeapHeader *) heap; - OSUninterruptibleSpinLock_Acquire(&header->lock); + // Skip non-video memory + if (videoOnly && ((effectiveAddress < MEMORY_START_VIDEO) || (effectiveAddress > MEMORY_END_VIDEO))) { + continue; + } + res = MEMAllocFromExpHeapEx(heapHandle, size, align); auto cur = heap->usedList.head; while (cur != nullptr) { @@ -404,39 +411,27 @@ void *MemoryMapping_alloc(uint32_t size, uint32_t align) { DCFlushRange(cur, sizeof(MEMExpHeapBlock)); cur = cur->next; } - OSUninterruptibleSpinLock_Release(&header->lock); if (res != nullptr) { break; } } + OSUninterruptibleSpinLock_Release(&allocFreeSpinlock); return res; } -void *MemoryMapping_allocVideoMemory(uint32_t size, uint32_t align) { - void *res = nullptr; - for (int32_t i = 0; /* waiting for a break */; i++) { - if (mem_mapping[i].physical_addresses == nullptr) { - break; - } - uint32_t effectiveAddress = mem_mapping[i].effective_start_address; - - // Skip non-video memory - if (effectiveAddress < MEMORY_START_VIDEO || effectiveAddress > MEMORY_END_VIDEO) { - continue; - } - res = MEMAllocFromExpHeapEx((MEMHeapHandle) mem_mapping[i].effective_start_address, size, align); - if (res != nullptr) { - break; - } - } - return res; +void *MemoryMapping_alloc(uint32_t size, int32_t align) { + return MemoryMapping_allocEx(size, align, false); } +void *MemoryMapping_allocVideoMemory(uint32_t size, int32_t align) { + return MemoryMapping_allocEx(size, align, true); +} void MemoryMapping_free(void *ptr) { if (ptr == nullptr) { return; } + OSUninterruptibleSpinLock_Acquire(&allocFreeSpinlock); auto ptr_val = (uint32_t) ptr; for (int32_t i = 0; /* waiting for a break */; i++) { if (mem_mapping[i].physical_addresses == nullptr) { @@ -445,9 +440,7 @@ void MemoryMapping_free(void *ptr) { if (ptr_val > mem_mapping[i].effective_start_address && ptr_val < mem_mapping[i].effective_end_address) { auto heapHandle = (MEMHeapHandle) mem_mapping[i].effective_start_address; auto *heap = (MEMExpHeap *) heapHandle; - auto *header = (MEMHeapHeader *) heapHandle; - OSUninterruptibleSpinLock_Acquire(&header->lock); MEMFreeToExpHeap((MEMHeapHandle) mem_mapping[i].effective_start_address, ptr); auto cur = heap->usedList.head; while (cur != nullptr) { @@ -459,10 +452,10 @@ void MemoryMapping_free(void *ptr) { DCFlushRange(cur, sizeof(MEMExpHeapBlock)); cur = cur->next; } - OSUninterruptibleSpinLock_Release(&header->lock); break; } } + OSUninterruptibleSpinLock_Release(&allocFreeSpinlock); } uint32_t MemoryMapping_MEMGetAllocatableSize() { diff --git a/source/memory_mapping.h b/source/memory_mapping.h index 11f3fcf..784e690 100644 --- a/source/memory_mapping.h +++ b/source/memory_mapping.h @@ -52,7 +52,7 @@ const memory_values_t mem_vals_heap_2[] = { }; #define MEMORY_HEAP1_SIZE 0xE20000 -#define MEMORY_HEAP1 MEMORY_HEAP0 + MEMORY_HEAP0_SIZE +#define MEMORY_HEAP1 (MEMORY_HEAP0 + MEMORY_HEAP0_SIZE) const memory_values_t mem_vals_heap_3[] = { {0x28000000 + 0x058E0000, 0x28000000 + 0x06000000}, // size: 7296 kB @@ -60,7 +60,7 @@ const memory_values_t mem_vals_heap_3[] = { }; #define MEMORY_HEAP2_SIZE 0x720000 -#define MEMORY_HEAP2 MEMORY_HEAP1 + MEMORY_HEAP1_SIZE +#define MEMORY_HEAP2 (MEMORY_HEAP1 + MEMORY_HEAP1_SIZE) const memory_values_t mem_vals_heap_4[] = { {0x28000000 + 0x053C0000, 0x28000000 + 0x05880000}, // size: 4864 kB @@ -68,9 +68,9 @@ const memory_values_t mem_vals_heap_4[] = { }; #define MEMORY_HEAP3_SIZE 0x4C0000 -#define MEMORY_HEAP3 MEMORY_HEAP2 + MEMORY_HEAP2_SIZE +#define MEMORY_HEAP3 (MEMORY_HEAP2 + MEMORY_HEAP2_SIZE) -#define MEMORY_HEAP4 MEMORY_HEAP3 + MEMORY_HEAP3_SIZE +#define MEMORY_HEAP4 (MEMORY_HEAP3 + MEMORY_HEAP3_SIZE) const memory_values_t mem_vals_video[] = { // The GPU doesn't have access to the 0x28000000 - 0x32000000 area, so we need memory from somewhere else. @@ -107,7 +107,7 @@ const memory_values_t mem_vals_video[] = { }; #define MEMORY_START_VIDEO MEMORY_START_VIDEO_BASE -#define MEMORY_END_VIDEO MEMORY_START_VIDEO + 0xE60000 +#define MEMORY_END_VIDEO (MEMORY_START_VIDEO + 0xE60000) const memory_mapping_t mem_mapping[] = { {MEMORY_HEAP0, MEMORY_HEAP1, mem_vals_heap_1}, @@ -186,9 +186,9 @@ void MemoryMapping_readTestValuesFromMemory(); void MemoryMapping_searchEmptyMemoryRegions(); -void *MemoryMapping_alloc(uint32_t size, uint32_t align); +void *MemoryMapping_alloc(uint32_t size, int32_t align); -void *MemoryMapping_allocVideoMemory(uint32_t size, uint32_t align); +void *MemoryMapping_allocVideoMemory(uint32_t size, int32_t align); void MemoryMapping_free(void *ptr);