]> Chaos Git - corbenik/ctrulib.git/commitdiff
Dynamically determine heap sizes.
authorSteven Smith <Steveice10@gmail.com>
Sat, 21 Nov 2015 18:37:22 +0000 (10:37 -0800)
committerSteven Smith <Steveice10@gmail.com>
Sat, 21 Nov 2015 18:43:50 +0000 (10:43 -0800)
libctru/include/3ds/os.h
libctru/source/os.c
libctru/source/system/allocateHeaps.c

index 34b47548f8667a48e2a4b69a5b91832e5a5d87fb..e9b26c57f3512609db569b5f9185c08f3dc1eeba 100644 (file)
 /// Retrieves the revision version from a packed system version.
 #define GET_VERSION_REVISION(version) (((version)>> 8)&0xFF)
 
-/*! OS_VersionBin. Format of the system version: "<major>.<minor>.<build>-<nupver><region>" */
+/// Memory regions.
+typedef enum
+{
+       MEMREGION_ALL = 0,         ///< All regions.
+       MEMREGION_APPLICATION = 1, ///< APPLICATION memory.
+       MEMREGION_SYSTEM = 2,      ///< SYSTEM memory.
+       MEMREGION_BASE = 3,        ///< BASE memory.
+} MemRegion;
+
+/// OS_VersionBin. Format of the system version: "<major>.<minor>.<build>-<nupver><region>"
 typedef struct
 {
        u8 build;
@@ -78,6 +87,37 @@ static inline u32 osGetKernelVersion(void)
        return (*(vu32*)0x1FF80000) & ~0xFF;
 }
 
+/**
+ * @brief Gets the size of the specified memory region.
+ * @param region Memory region to check.
+ * @return The size of the memory region, in bytes.
+ */
+static inline u32 osGetMemRegionSize(MemRegion region)
+{
+       if(region == MEMREGION_ALL) {
+               return osGetMemRegionSize(MEMREGION_APPLICATION) + osGetMemRegionSize(MEMREGION_SYSTEM) + osGetMemRegionSize(MEMREGION_BASE);
+       } else {
+               return *(vu32*) (0x1FF80040 + (region - 1) * 0x4);
+       }
+}
+
+/**
+ * @brief Gets the number of used bytes within the specified memory region.
+ * @param region Memory region to check.
+ * @return The number of used bytes of memory.
+ */
+s64 osGetMemRegionUsed(MemRegion region);
+
+/**
+ * @brief Gets the number of free bytes within the specified memory region.
+ * @param region Memory region to check.
+ * @return The number of free bytes of memory.
+ */
+static inline s64 osGetMemRegionFree(MemRegion region)
+{
+       return (s64) osGetMemRegionSize(region) - osGetMemRegionUsed(region);
+}
+
 /**
  * @brief Gets the current time.
  * @return The number of milliseconds since 1st Jan 1900 00:00.
index 8bbc0cc9127efc6227c91e061a2932cd45c33c3d..abd93e4a947e2d4117038d8ac65b9c4cc6031583 100644 (file)
@@ -51,6 +51,12 @@ void* osConvertOldLINEARMemToNew(const void* addr) {
        return 0;
 }
 
+s64 osGetMemRegionUsed(MemRegion region) {
+       s64 mem_used;
+       svcGetSystemInfo(&mem_used, 0, region);
+       return mem_used;
+}
+
 //---------------------------------------------------------------------------------
 static datetime_t getSysTime(void) {
 //---------------------------------------------------------------------------------
index 6bfcb62706fcc20566c73b9559bb1a7246ccfdfa..0d7859ce6bf5f607799a3537292c1426b5669e09 100644 (file)
@@ -1,6 +1,7 @@
 #include <3ds/types.h>
 #include <3ds/svc.h>
 #include <3ds/env.h>
+#include <3ds/os.h>
 
 extern char* fake_heap_start;
 extern char* fake_heap_end;
@@ -13,9 +14,16 @@ u32 __ctru_linear_heap_size;
 void __attribute__((weak)) __system_allocateHeaps() {
        u32 tmp=0;
 
-       // Retrieve heap sizes.
-       __ctru_heap_size = envGetHeapSize();
-       __ctru_linear_heap_size = envGetLinearHeapSize();
+       if(envIsHomebrew()) {
+               // Use launcher-provided heap information.
+               __ctru_heap_size = envGetHeapSize();
+               __ctru_linear_heap_size = envGetLinearHeapSize();
+       } else {
+               // Distribute available memory into halves, aligning to page size.
+               u32 size = (osGetMemRegionFree(MEMREGION_APPLICATION) / 2) & 0xFFFFF000;
+               __ctru_heap_size = size;
+               __ctru_linear_heap_size = size;
+       }
 
        // Allocate the application heap
        __ctru_heap = 0x08000000;