Files
PS5_RetroArch/tests/memory_ps5_test.cpp
T
Mihawk d2a91b395b Port native mGBA and fix core/menu lifecycle rendering
Build pinned mGBA with this PS5 SDK, official metadata and both GB/GBA engines.
Support validated C initializer arrays, native directory/time imports and an
explicit config path. Map large title/core allocations so GBA archives load.
Correct mGBA callback colours and cached frame ownership, crop padded core
textures during presentation, and use the native shell exit after cleanup.

Verified: bash tools/verify.sh (format, unit, build, integration, evidence;
58 tests), then bash tools/run-title.sh --no-build --core-test=mgba --watch 180.
Owner confirms GB/GBC/GBA loading, correct colours/native Quit, and clean menu
and next game. Final capture has zero Vulkan refusals, GPU failure records or
kernel fatal-signal reports; normal frontend exit occurred before window end.

Evidence: evidence/mgba-native/{capture,expectation,iterations,build,abi}.json,
loader/recovery reports and exact linked-driver hashes. Replay with
bash tools/verify.sh evidence. Final build identity:
82024b89e74bbad4ad2ce2e2916d1a49baf26ac325fef20fc71a2c168b862337.

Patch count is deliberately 139: archive diagnostics, menu/cache ownership and
padded-source sampling edits. PS5_Vulkan was not modified. Saves/states,
long-run timing and a fresh FCEUmm/XMB transition matrix remain unverified.
2026-09-19 16:00:01 -04:00

79 lines
2.4 KiB
C++

#include <cassert>
#include <cerrno>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <thread>
#include <vector>
extern "C"
{
void *__wrap_malloc(size_t);
void *__wrap_calloc(size_t, size_t);
void *__wrap_realloc(void *, size_t);
void __wrap_free(void *);
// Host build binds these to libc, preserving genuinely foreign pointers.
void *__real_malloc(size_t n)
{
return std::malloc(n);
}
void *__real_calloc(size_t n, size_t s)
{
return std::calloc(n, s);
}
void *__real_realloc(void *p, size_t n)
{
return std::realloc(p, n);
}
void __real_free(void *p)
{
std::free(p);
}
}
int main()
{
constexpr size_t large = 16 * 1024 * 1024;
auto *p = static_cast<unsigned char *>(__wrap_malloc(large));
assert(p && uintptr_t(p) % alignof(std::max_align_t) == 0);
std::memset(p, 0xA5, large);
assert(!__wrap_realloc(p, SIZE_MAX));
assert(p[0] == 0xA5 && p[large - 1] == 0xA5);
p = static_cast<unsigned char *>(__wrap_realloc(p, large * 2));
assert(p && p[0] == 0xA5 && p[large - 1] == 0xA5);
p = static_cast<unsigned char *>(__wrap_realloc(p, 13));
assert(p && p[12] == 0xA5);
__wrap_free(p);
p = static_cast<unsigned char *>(__wrap_calloc(2, large));
assert(p);
for (size_t i = 0; i < 2 * large; ++i)
assert(p[i] == 0);
__wrap_free(p);
assert(!__wrap_calloc(SIZE_MAX, 2) && errno == ENOMEM);
assert(!__wrap_malloc(SIZE_MAX) && errno == ENOMEM);
// strdup/native library buffers must still be freed by libc.
char *foreign = strdup("native allocation");
foreign = static_cast<char *>(__wrap_realloc(foreign, 128));
assert(foreign && !strcmp(foreign, "native allocation"));
__wrap_free(foreign);
__wrap_free(nullptr);
void *empty = __wrap_calloc(0, SIZE_MAX);
assert(empty);
__wrap_free(empty);
assert(!__wrap_realloc(__wrap_malloc(large), 0));
std::vector<std::thread> workers;
for (int t = 0; t < 4; ++t)
workers.emplace_back(
[]
{
for (int i = 0; i < 50; ++i)
{
void *buffer = __wrap_malloc(1024 * 1024);
assert(buffer);
memset(buffer, i, 1024 * 1024);
__wrap_free(buffer);
}
});
for (auto &worker : workers)
worker.join();
}