From 69abe041b7849df896ab3ecb52937701104f1c4d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 19 Aug 2013 22:45:38 -0700 Subject: [PATCH 1/3] Properly handle off-grain allocations. This was causing sceKernelMaxFreeMemSize() to report a size that wasn't allocatable, since sizes are upaligned to grain. --- Core/Util/BlockAllocator.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Core/Util/BlockAllocator.cpp b/Core/Util/BlockAllocator.cpp index 0f181aa5c8..74f21a8521 100644 --- a/Core/Util/BlockAllocator.cpp +++ b/Core/Util/BlockAllocator.cpp @@ -15,9 +15,10 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Log.h" -#include "BlockAllocator.h" -#include "ChunkFile.h" +#include "Common/Log.h" +#include "Common/ChunkFile.h" +#include "Core/Util/BlockAllocator.h" +#include "Core/Reporting.h" // Slow freaking thing but works (eventually) :) @@ -150,11 +151,13 @@ u32 BlockAllocator::AllocAt(u32 position, u32 size, const char *tag) size = (size + grain_ - 1) & ~(grain_ - 1); // check that position is aligned + u32 bottomPosition = position; if (position & (grain_ - 1)) { - ERROR_LOG(HLE, "Position %08x does not align to grain. Grain will be off.", position); + DEBUG_LOG(HLE, "Position %08x does not align to grain.", position); + bottomPosition &= ~(grain_ - 1); } - Block *bp = GetBlockFromAddress(position); + Block *bp = GetBlockFromAddress(bottomPosition); if (bp != NULL) { Block &b = *bp; @@ -166,7 +169,7 @@ u32 BlockAllocator::AllocAt(u32 position, u32 size, const char *tag) else { //good to go - if (b.start == position) + if (b.start == bottomPosition) { InsertFreeAfter(&b, b.start + size, b.size - size); b.taken = true; @@ -177,12 +180,12 @@ u32 BlockAllocator::AllocAt(u32 position, u32 size, const char *tag) } else { - int size1 = position - b.start; + int size1 = bottomPosition - b.start; InsertFreeBefore(&b, b.start, size1); - if (b.start + b.size > position + size) - InsertFreeAfter(&b, position + size, b.size - (size + size1)); + if (b.start + b.size > bottomPosition + size) + InsertFreeAfter(&b, bottomPosition + size, b.size - (size + size1)); b.taken = true; - b.start = position; + b.start = bottomPosition; b.size = size; b.SetTag(tag); return position; @@ -376,6 +379,8 @@ u32 BlockAllocator::GetLargestFreeBlockSize() const maxFreeBlock = b.size; } } + if (maxFreeBlock & (grain_ - 1)) + WARN_LOG_REPORT(HLE, "GetLargestFreeBlockSize: free size %08x does not align to grain %08x.", maxFreeBlock, grain_); return maxFreeBlock; } @@ -390,6 +395,8 @@ u32 BlockAllocator::GetTotalFreeBytes() const sum += b.size; } } + if (sum & (grain_ - 1)) + WARN_LOG_REPORT(HLE, "GetTotalFreeBytes: free size %08x does not align to grain %08x.", sum, grain_); return sum; } From ad537a37731a84cf17cf8468e07b7d4c120b503d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 19 Aug 2013 23:04:45 -0700 Subject: [PATCH 2/3] Use normal Windows path logic for homebrew/demos. --- UI/MainScreen.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 3437c4bbcf..b1a5df99f4 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -290,6 +290,12 @@ void PathBrowser::Navigate(const std::string &path) { } } +static std::string GetMemCardDirectory() { + std::string memCardDirectory, ignore; + GetSysDirectories(memCardDirectory, ignore); + return memCardDirectory; +} + class GameBrowser : public UI::LinearLayout { public: GameBrowser(std::string path, bool allowBrowsing, bool *gridStyle_, std::string lastText, std::string lastLink, UI::LayoutParams *layoutParams = 0); @@ -333,7 +339,7 @@ UI::EventReturn GameBrowser::LastClick(UI::EventParams &e) { } UI::EventReturn GameBrowser::HomeClick(UI::EventParams &e) { - path_.SetPath(g_Config.memCardDirectory); + path_.SetPath(GetMemCardDirectory()); g_Config.currentDirectory = path_.GetPath(); Refresh(); return UI::EVENT_DONE; @@ -472,7 +478,7 @@ void MainScreen::CreateViews() { GameBrowser *tabAllGames = new GameBrowser(g_Config.currentDirectory, true, &g_Config.bGridView2, m->T("How to get games"), "http://www.ppsspp.org/faq.html", new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); - GameBrowser *tabHomebrew = new GameBrowser(g_Config.memCardDirectory + "PSP/GAME/", false, &g_Config.bGridView3, + GameBrowser *tabHomebrew = new GameBrowser(GetMemCardDirectory() + "PSP/GAME/", false, &g_Config.bGridView3, "", "", new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); From dc3de4dbffd3dcf8528277c3ba163b02bbf1f484 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 20 Aug 2013 00:58:38 -0700 Subject: [PATCH 3/3] For an off-grain alloc, properly align size. --- Core/Util/BlockAllocator.cpp | 38 +++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/Core/Util/BlockAllocator.cpp b/Core/Util/BlockAllocator.cpp index 74f21a8521..082d827724 100644 --- a/Core/Util/BlockAllocator.cpp +++ b/Core/Util/BlockAllocator.cpp @@ -146,18 +146,24 @@ u32 BlockAllocator::AllocAt(u32 position, u32 size, const char *tag) ERROR_LOG(HLE, "Clearly bogus size: %08x - failing allocation", size); return -1; } - - // upalign size to grain - size = (size + grain_ - 1) & ~(grain_ - 1); - // check that position is aligned - u32 bottomPosition = position; + // Downalign the position so we're allocating full blocks. + u32 alignedPosition = position; + u32 alignedSize = size; if (position & (grain_ - 1)) { DEBUG_LOG(HLE, "Position %08x does not align to grain.", position); - bottomPosition &= ~(grain_ - 1); + alignedPosition &= ~(grain_ - 1); + + // Since the position was decreased, size must increase. + alignedSize += alignedPosition - position; } - Block *bp = GetBlockFromAddress(bottomPosition); + // Upalign size to grain. + alignedSize = (alignedSize + grain_ - 1) & ~(grain_ - 1); + // Tell the caller the allocated size from their requested starting position. + size = alignedSize - (alignedPosition - position); + + Block *bp = GetBlockFromAddress(alignedPosition); if (bp != NULL) { Block &b = *bp; @@ -169,24 +175,24 @@ u32 BlockAllocator::AllocAt(u32 position, u32 size, const char *tag) else { //good to go - if (b.start == bottomPosition) + if (b.start == alignedPosition) { - InsertFreeAfter(&b, b.start + size, b.size - size); + InsertFreeAfter(&b, b.start + alignedSize, b.size - alignedSize); b.taken = true; - b.size = size; + b.size = alignedSize; b.SetTag(tag); CheckBlocks(); return position; } else { - int size1 = bottomPosition - b.start; + int size1 = alignedPosition - b.start; InsertFreeBefore(&b, b.start, size1); - if (b.start + b.size > bottomPosition + size) - InsertFreeAfter(&b, bottomPosition + size, b.size - (size + size1)); + if (b.start + b.size > alignedPosition + alignedSize) + InsertFreeAfter(&b, alignedPosition + alignedSize, b.size - (alignedSize + size1)); b.taken = true; - b.start = bottomPosition; - b.size = size; + b.start = alignedPosition; + b.size = alignedSize; b.SetTag(tag); return position; } @@ -200,7 +206,7 @@ u32 BlockAllocator::AllocAt(u32 position, u32 size, const char *tag) //Out of memory :( ListBlocks(); - ERROR_LOG(HLE, "Block Allocator failed to allocate %i bytes of contiguous memory", size); + ERROR_LOG(HLE, "Block Allocator failed to allocate %i bytes of contiguous memory", alignedSize); return -1; }