mirror of
https://github.com/wiiu-env/MemoryMappingModule.git
synced 2024-11-22 09:49:20 +01:00
Use a global spinlock to lock the alloc/free functions
This commit is contained in:
parent
01a2396b83
commit
d36d3610ca
@ -101,7 +101,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Shutdown thread
|
//! Shutdown thread
|
||||||
virtual void shutdownThread() {
|
void shutdownThread() {
|
||||||
//! wait for thread to finish
|
//! wait for thread to finish
|
||||||
if (pThread && !(iAttributes & eAttributeDetach)) {
|
if (pThread && !(iAttributes & eAttributeDetach)) {
|
||||||
while (isThreadSuspended()) {
|
while (isThreadSuspended()) {
|
||||||
|
@ -68,13 +68,13 @@ void *MemoryMappingAlloc(uint32_t size) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *MemoryMappingAllocEx(uint32_t size, uint32_t align) {
|
void *MemoryMappingAllocEx(uint32_t size, int32_t align) {
|
||||||
void *res = MemoryMapping_alloc(size, align);
|
void *res = MemoryMapping_alloc(size, align);
|
||||||
//DEBUG_FUNCTION_LINE("[res %08X] allocEX %d %d ", res, size, align);
|
//DEBUG_FUNCTION_LINE("[res %08X] allocEX %d %d ", res, size, align);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *MemoryMappingAllocForGX2Ex(uint32_t size, uint32_t align) {
|
void *MemoryMappingAllocForGX2Ex(uint32_t size, int32_t align) {
|
||||||
void *res = MemoryMapping_allocVideoMemory(size, align);
|
void *res = MemoryMapping_allocVideoMemory(size, align);
|
||||||
//DEBUG_FUNCTION_LINE("[res %08X] allocEX %d %d ", res, size, align);
|
//DEBUG_FUNCTION_LINE("[res %08X] allocEX %d %d ", res, size, align);
|
||||||
return res;
|
return res;
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
#include <coreinit/debug.h>
|
#include <coreinit/debug.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
OSSpinLock allocFreeSpinlock;
|
||||||
|
|
||||||
// #define DEBUG_FUNCTION_LINE(x,...)
|
// #define DEBUG_FUNCTION_LINE(x,...)
|
||||||
|
|
||||||
void runOnAllCores(CThread::Callback callback, void *callbackArg, int32_t iAttr = 0, int32_t iPriority = 16, int32_t iStackSize = 0x8000) {
|
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);
|
//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;
|
void *res = nullptr;
|
||||||
for (int32_t i = 0; /* waiting for a break */; i++) {
|
for (int32_t i = 0; /* waiting for a break */; i++) {
|
||||||
if (mem_mapping[i].physical_addresses == nullptr) {
|
if (mem_mapping[i].physical_addresses == nullptr) {
|
||||||
break;
|
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 *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);
|
res = MEMAllocFromExpHeapEx(heapHandle, size, align);
|
||||||
auto cur = heap->usedList.head;
|
auto cur = heap->usedList.head;
|
||||||
while (cur != nullptr) {
|
while (cur != nullptr) {
|
||||||
@ -404,39 +411,27 @@ void *MemoryMapping_alloc(uint32_t size, uint32_t align) {
|
|||||||
DCFlushRange(cur, sizeof(MEMExpHeapBlock));
|
DCFlushRange(cur, sizeof(MEMExpHeapBlock));
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
OSUninterruptibleSpinLock_Release(&header->lock);
|
|
||||||
if (res != nullptr) {
|
if (res != nullptr) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
OSUninterruptibleSpinLock_Release(&allocFreeSpinlock);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *MemoryMapping_allocVideoMemory(uint32_t size, uint32_t align) {
|
void *MemoryMapping_alloc(uint32_t size, int32_t align) {
|
||||||
void *res = nullptr;
|
return MemoryMapping_allocEx(size, align, false);
|
||||||
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_allocVideoMemory(uint32_t size, int32_t align) {
|
||||||
|
return MemoryMapping_allocEx(size, align, true);
|
||||||
|
}
|
||||||
|
|
||||||
void MemoryMapping_free(void *ptr) {
|
void MemoryMapping_free(void *ptr) {
|
||||||
if (ptr == nullptr) {
|
if (ptr == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
OSUninterruptibleSpinLock_Acquire(&allocFreeSpinlock);
|
||||||
auto ptr_val = (uint32_t) ptr;
|
auto ptr_val = (uint32_t) ptr;
|
||||||
for (int32_t i = 0; /* waiting for a break */; i++) {
|
for (int32_t i = 0; /* waiting for a break */; i++) {
|
||||||
if (mem_mapping[i].physical_addresses == nullptr) {
|
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) {
|
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 heapHandle = (MEMHeapHandle) mem_mapping[i].effective_start_address;
|
||||||
auto *heap = (MEMExpHeap *) heapHandle;
|
auto *heap = (MEMExpHeap *) heapHandle;
|
||||||
auto *header = (MEMHeapHeader *) heapHandle;
|
|
||||||
|
|
||||||
OSUninterruptibleSpinLock_Acquire(&header->lock);
|
|
||||||
MEMFreeToExpHeap((MEMHeapHandle) mem_mapping[i].effective_start_address, ptr);
|
MEMFreeToExpHeap((MEMHeapHandle) mem_mapping[i].effective_start_address, ptr);
|
||||||
auto cur = heap->usedList.head;
|
auto cur = heap->usedList.head;
|
||||||
while (cur != nullptr) {
|
while (cur != nullptr) {
|
||||||
@ -459,10 +452,10 @@ void MemoryMapping_free(void *ptr) {
|
|||||||
DCFlushRange(cur, sizeof(MEMExpHeapBlock));
|
DCFlushRange(cur, sizeof(MEMExpHeapBlock));
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
OSUninterruptibleSpinLock_Release(&header->lock);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
OSUninterruptibleSpinLock_Release(&allocFreeSpinlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t MemoryMapping_MEMGetAllocatableSize() {
|
uint32_t MemoryMapping_MEMGetAllocatableSize() {
|
||||||
|
@ -52,7 +52,7 @@ const memory_values_t mem_vals_heap_2[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define MEMORY_HEAP1_SIZE 0xE20000
|
#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[] = {
|
const memory_values_t mem_vals_heap_3[] = {
|
||||||
{0x28000000 + 0x058E0000, 0x28000000 + 0x06000000}, // size: 7296 kB
|
{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_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[] = {
|
const memory_values_t mem_vals_heap_4[] = {
|
||||||
{0x28000000 + 0x053C0000, 0x28000000 + 0x05880000}, // size: 4864 kB
|
{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_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[] = {
|
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.
|
// 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_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[] = {
|
const memory_mapping_t mem_mapping[] = {
|
||||||
{MEMORY_HEAP0, MEMORY_HEAP1, mem_vals_heap_1},
|
{MEMORY_HEAP0, MEMORY_HEAP1, mem_vals_heap_1},
|
||||||
@ -186,9 +186,9 @@ void MemoryMapping_readTestValuesFromMemory();
|
|||||||
|
|
||||||
void MemoryMapping_searchEmptyMemoryRegions();
|
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);
|
void MemoryMapping_free(void *ptr);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user