Refactor default heap allocation code, see details:
- Use reslimit svcs to retrieve free mem (suggested by @TuxSH) - this removes the hardcoded assumption that the process is in APPLICATION. - The algorithm for calculating default app/linear heap sizes has been tweaked to ensure 32MB of linear heap are available for normal apps running on Old3DS consoles under appmemtype 0 (i.e. the default). - Misc cleanup and error checking.
This commit is contained in:
parent
da529aed21
commit
33a570b1c3
@ -2,8 +2,10 @@
|
||||
#include <3ds/allocator/mappable.h>
|
||||
#include <3ds/env.h>
|
||||
#include <3ds/os.h>
|
||||
#include <3ds/result.h>
|
||||
|
||||
#define DEFAULT_LINEAR_HEAP_SIZE (32 << 20) // 32MB
|
||||
#define HEAP_SPLIT_SIZE_CAP (24 << 20) // 24MB
|
||||
#define LINEAR_HEAP_SIZE_CAP (32 << 20) // 32MB
|
||||
|
||||
extern char* fake_heap_start;
|
||||
extern char* fake_heap_end;
|
||||
@ -15,17 +17,43 @@ __attribute__((weak)) u32 __ctru_heap_size = 0;
|
||||
__attribute__((weak)) u32 __ctru_linear_heap_size = 0;
|
||||
|
||||
void __attribute__((weak)) __system_allocateHeaps(void) {
|
||||
u32 tmp = 0;
|
||||
u32 remaining = osGetMemRegionFree(MEMREGION_APPLICATION) &~ 0xFFF;
|
||||
Result rc;
|
||||
|
||||
// Retrieve handle to the resource limit object for our process
|
||||
Handle reslimit = 0;
|
||||
rc = svcGetResourceLimit(&reslimit, CUR_PROCESS_HANDLE);
|
||||
if (R_FAILED(rc))
|
||||
svcBreak(USERBREAK_PANIC);
|
||||
|
||||
// Retrieve information about total/used memory
|
||||
s64 maxCommit = 0, currentCommit = 0;
|
||||
ResourceLimitType reslimitType = RESLIMIT_COMMIT;
|
||||
svcGetResourceLimitLimitValues(&maxCommit, reslimit, &reslimitType, 1); // for APPLICATION this is equal to APPMEMALLOC at all times
|
||||
svcGetResourceLimitCurrentValues(¤tCommit, reslimit, &reslimitType, 1);
|
||||
svcCloseHandle(reslimit);
|
||||
|
||||
// Calculate how much remaining free memory is available
|
||||
u32 remaining = (u32)(maxCommit - currentCommit) &~ 0xFFF;
|
||||
|
||||
if (__ctru_heap_size + __ctru_linear_heap_size > remaining)
|
||||
svcBreak(USERBREAK_PANIC);
|
||||
|
||||
if (__ctru_heap_size == 0 && __ctru_linear_heap_size == 0) {
|
||||
// By default, automatically allocate all remaining free memory, aligning to page size.
|
||||
// Split available memory equally between linear and application heaps (with rounding in favor of the latter)
|
||||
__ctru_linear_heap_size = (remaining / 2) & ~0xFFF;
|
||||
__ctru_linear_heap_size = __ctru_linear_heap_size <= DEFAULT_LINEAR_HEAP_SIZE ? __ctru_linear_heap_size : DEFAULT_LINEAR_HEAP_SIZE;
|
||||
__ctru_heap_size = remaining - __ctru_linear_heap_size;
|
||||
|
||||
// If the application heap size is bigger than the cap, prefer to grow linear heap instead
|
||||
if (__ctru_heap_size > HEAP_SPLIT_SIZE_CAP) {
|
||||
__ctru_heap_size = HEAP_SPLIT_SIZE_CAP;
|
||||
__ctru_linear_heap_size = remaining - __ctru_heap_size;
|
||||
|
||||
// However if the linear heap size is bigger than the cap, prefer to grow application heap
|
||||
if (__ctru_linear_heap_size > LINEAR_HEAP_SIZE_CAP) {
|
||||
__ctru_linear_heap_size = LINEAR_HEAP_SIZE_CAP;
|
||||
__ctru_heap_size = remaining - __ctru_linear_heap_size;
|
||||
}
|
||||
}
|
||||
} else if (__ctru_heap_size == 0) {
|
||||
__ctru_heap_size = remaining - __ctru_linear_heap_size;
|
||||
} else if (__ctru_linear_heap_size == 0) {
|
||||
@ -33,11 +61,14 @@ void __attribute__((weak)) __system_allocateHeaps(void) {
|
||||
}
|
||||
|
||||
// Allocate the application heap
|
||||
__ctru_heap = OS_HEAP_AREA_BEGIN;
|
||||
svcControlMemory(&tmp, __ctru_heap, 0x0, __ctru_heap_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE);
|
||||
rc = svcControlMemory(&__ctru_heap, OS_HEAP_AREA_BEGIN, 0x0, __ctru_heap_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE);
|
||||
if (R_FAILED(rc))
|
||||
svcBreak(USERBREAK_PANIC);
|
||||
|
||||
// Allocate the linear heap
|
||||
svcControlMemory(&__ctru_linear_heap, 0x0, 0x0, __ctru_linear_heap_size, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
|
||||
rc = svcControlMemory(&__ctru_linear_heap, 0x0, 0x0, __ctru_linear_heap_size, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
|
||||
if (R_FAILED(rc))
|
||||
svcBreak(USERBREAK_PANIC);
|
||||
|
||||
// Mappable allocator init
|
||||
mappableInit(OS_MAP_AREA_BEGIN, OS_MAP_AREA_END);
|
||||
|
Loading…
Reference in New Issue
Block a user