Merge pull request #2647 from oneandonlydean/fix/guest-stack-host-margin

fix(libkernel): keep host stack room below guest thread stacks
This commit is contained in:
Dean 2026-10-10 23:59:23 +13:00 committed by GitHub
commit b5f5362d3d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 8 additions and 4 deletions

View File

@ -29,6 +29,7 @@
static constexpr int SCE_OK = 0;
static constexpr std::size_t DEFAULT_STACK_SIZE = 1u << 20;
static constexpr std::size_t HOST_STACK_MARGIN = 1u << 20;
static constexpr int DETACH_DETACHED = 1;
static constexpr std::size_t THREAD_NAME_CAPACITY = 32;
@ -481,9 +482,9 @@ int APS5_VABI scePthreadCreate(Pthread* thread, const PthreadAttr* attr, Pthread
#ifdef _WIN32
SYSTEM_INFO system{};
GetSystemInfo(&system);
const std::size_t nativeStack = (p->stackSize + system.dwPageSize - 1) / system.dwPageSize * system.dwPageSize;
if (p->stackSize < 16384 || nativeStack > std::numeric_limits<unsigned>::max())
if (p->stackSize < 16384 || p->stackSize > std::numeric_limits<unsigned>::max() - HOST_STACK_MARGIN - system.dwPageSize)
throw std::runtime_error("scePthreadCreate: invalid Windows stack size");
const std::size_t nativeStack = (p->stackSize + HOST_STACK_MARGIN + system.dwPageSize - 1) / system.dwPageSize * system.dwPageSize;
auto native = std::make_unique<NativeThreadArgs>(NativeThreadArgs{std::move(args), start.get_future(), {}});
auto initialized = native->initialized.get_future();
const auto handle = _beginthreadex(nullptr, static_cast<unsigned>(nativeStack), StartNativeThread, native.get(), 0, nullptr);
@ -507,9 +508,9 @@ int APS5_VABI scePthreadCreate(Pthread* thread, const PthreadAttr* attr, Pthread
#else
const auto reserve = HostStackReserve();
const auto page = static_cast<std::size_t>(sysconf(_SC_PAGESIZE));
if (p->stackSize < 16384 || p->stackSize > std::numeric_limits<std::size_t>::max() - reserve - page)
if (p->stackSize < 16384 || p->stackSize > std::numeric_limits<std::size_t>::max() - reserve - HOST_STACK_MARGIN - page)
throw std::runtime_error("scePthreadCreate: invalid stack size");
const std::size_t nativeStack = (p->stackSize + reserve + page - 1) / page * page;
const std::size_t nativeStack = (p->stackSize + reserve + HOST_STACK_MARGIN + page - 1) / page * page;
auto native = std::make_unique<NativeThreadArgs>(NativeThreadArgs{std::move(args), start.get_future(), {}});
auto initialized = native->initialized.get_future();
pthread_attr_t nativeAttr;

View File

@ -17,6 +17,7 @@ Pthread APS5_VABI scePthreadSelf();
static constexpr int SCE_OK = 0;
static constexpr std::size_t FRAME_SIZE = 4096;
static constexpr std::size_t FRAME_MARGIN = 2 * FRAME_SIZE;
static constexpr std::size_t HOST_CALL_STACK = 256 * 1024;
static constexpr std::size_t STACK_SIZES[] = {16384, 65536, 1u << 20, 16u << 20};
thread_local unsigned char threadLocalBlock[512 * 1024];
@ -56,6 +57,8 @@ static void* APS5_VABI Worker(void* arg) {
Require(local - begin + FRAME_SIZE >= requested);
const auto deepest = Descend(begin);
Require(deepest >= begin && deepest < begin + FRAME_MARGIN);
const auto hostDeepest = descend(begin - HOST_CALL_STACK);
Require(hostDeepest < begin - HOST_CALL_STACK + FRAME_MARGIN);
Require(threadLocalBlock[0] == 1 && threadLocalBlock[sizeof(threadLocalBlock) - 1] == 2);
return arg;