Skip to content

Commit ecdffab

Browse files
Correct some vpl allocation logic.
Tricky. This makes more tests pass, seems right.
1 parent 4cec228 commit ecdffab

File tree

1 file changed

+9
-18
lines changed

1 file changed

+9
-18
lines changed

Core/HLE/sceKernelMemory.cpp

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -204,23 +204,24 @@ struct SceKernelVplHeader {
204204

205205
u32 Allocate(u32 size) {
206206
u32 allocBlocks = ((size + 7) / 8) + 1;
207-
auto prev = PSPPointer<SceKernelVplBlock>::Create(0);
208-
auto b = nextFreeBlock_;
207+
auto prev = nextFreeBlock_;
209208
do {
209+
auto b = prev->next;
210210
if (b->sizeInBlocks > allocBlocks) {
211+
if (nextFreeBlock_ == b) {
212+
nextFreeBlock_ = prev;
213+
}
211214
prev = b;
212215
b = SplitBlock(b, allocBlocks);
213216
}
214217

215218
if (b->sizeInBlocks == allocBlocks) {
216219
UnlinkFreeBlock(b, prev);
217-
_dbg_assert_msg_(SCEKERNEL, b->sizeInBlocks == allocBlocks, "Returned block of improper size.");
218220
return b.ptr + 8;
219221
}
220222

221223
prev = b;
222-
b = b->next;
223-
} while (b.IsValid() && b != nextFreeBlock_);
224+
} while (prev.IsValid() && prev != nextFreeBlock_);
224225

225226
return (u32)-1;
226227
}
@@ -281,21 +282,11 @@ struct SceKernelVplHeader {
281282
}
282283

283284
void UnlinkFreeBlock(PSPPointer<SceKernelVplBlock> b, PSPPointer<SceKernelVplBlock> prev) {
284-
// If this was the first we tried, we have to search for prev.
285-
if (!prev.IsValid()) {
286-
prev = LastBlock();
287-
while (prev->next != b) {
288-
prev = prev->next;
289-
if (prev == LastBlock()) {
290-
_dbg_assert_msg_(SCEKERNEL, prev != LastBlock(), "Should have found a previous free block.");
291-
break;
292-
}
293-
}
294-
}
295-
296285
allocatedInBlocks_ += b->sizeInBlocks;
297286
prev->next = b->next;
298-
nextFreeBlock_ = b->next;
287+
if (nextFreeBlock_ == b) {
288+
nextFreeBlock_ = prev;
289+
}
299290
b->next = SentinelPtr();
300291
}
301292

0 commit comments

Comments
 (0)