From ecdffabf26f38a6bbfee7e99317cedb0602aa82b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 2 Feb 2014 08:13:41 -0800 Subject: [PATCH] Correct some vpl allocation logic. Tricky. This makes more tests pass, seems right. --- Core/HLE/sceKernelMemory.cpp | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index e04ee3a45e72..bb25280379a0 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -204,23 +204,24 @@ struct SceKernelVplHeader { u32 Allocate(u32 size) { u32 allocBlocks = ((size + 7) / 8) + 1; - auto prev = PSPPointer::Create(0); - auto b = nextFreeBlock_; + auto prev = nextFreeBlock_; do { + auto b = prev->next; if (b->sizeInBlocks > allocBlocks) { + if (nextFreeBlock_ == b) { + nextFreeBlock_ = prev; + } prev = b; b = SplitBlock(b, allocBlocks); } if (b->sizeInBlocks == allocBlocks) { UnlinkFreeBlock(b, prev); - _dbg_assert_msg_(SCEKERNEL, b->sizeInBlocks == allocBlocks, "Returned block of improper size."); return b.ptr + 8; } prev = b; - b = b->next; - } while (b.IsValid() && b != nextFreeBlock_); + } while (prev.IsValid() && prev != nextFreeBlock_); return (u32)-1; } @@ -281,21 +282,11 @@ struct SceKernelVplHeader { } void UnlinkFreeBlock(PSPPointer b, PSPPointer prev) { - // If this was the first we tried, we have to search for prev. - if (!prev.IsValid()) { - prev = LastBlock(); - while (prev->next != b) { - prev = prev->next; - if (prev == LastBlock()) { - _dbg_assert_msg_(SCEKERNEL, prev != LastBlock(), "Should have found a previous free block."); - break; - } - } - } - allocatedInBlocks_ += b->sizeInBlocks; prev->next = b->next; - nextFreeBlock_ = b->next; + if (nextFreeBlock_ == b) { + nextFreeBlock_ = prev; + } b->next = SentinelPtr(); }