#include "SceTypes.hpp" #include #include extern "C" { int APS5_VABI scePthreadCreate(Pthread* thread, const PthreadAttr* attr, PthreadEntry entry, void* arg, const char* name); int APS5_VABI scePthreadJoin(Pthread thread, void** retval); Pthread APS5_VABI scePthreadSelf(void); int APS5_VABI pthread_join_nid_postfix(Pthread thread, void** retval); } static constexpr int SCE_OK = 0; static constexpr int SCE_KERNEL_ERROR_EDEADLK = static_cast(0x8002000Bu); static constexpr int GUEST_EDEADLK = 11; static void Require(bool value) { if (!value) std::abort(); } static void* APS5_VABI JoinSelf(void*) { void* result = reinterpret_cast(std::uintptr_t{0x55}); Require(scePthreadJoin(scePthreadSelf(), &result) == SCE_KERNEL_ERROR_EDEADLK); Require(pthread_join_nid_postfix(scePthreadSelf(), &result) == GUEST_EDEADLK); Require(result == reinterpret_cast(std::uintptr_t{0x55})); return reinterpret_cast(std::uintptr_t{0x1234}); } int main() { Pthread thread = nullptr; void* result = nullptr; Require(scePthreadCreate(&thread, nullptr, JoinSelf, nullptr, "join-self") == SCE_OK); Require(scePthreadJoin(thread, &result) == SCE_OK); Require(result == reinterpret_cast(std::uintptr_t{0x1234})); PthreadAttr unset = nullptr; thread = nullptr; result = nullptr; Require(scePthreadCreate(&thread, &unset, JoinSelf, nullptr, "unset-attr") == SCE_OK); Require(scePthreadJoin(thread, &result) == SCE_OK); Require(result == reinterpret_cast(std::uintptr_t{0x1234})); }