From a24473311cea098aa7c6548836138443595ac9d1 Mon Sep 17 00:00:00 2001 From: hypermist Date: Wed, 21 Oct 2026 17:25:01 +1300 Subject: [PATCH 1/3] feat(libc): add the std::__sce_v2 mutex, condition and thread calls The versioned Dinkumware entries operate on libkernel's own mutex, condition and thread handles: _Mtx_init(_with_name), _Mtx_destroy, _Mtx_lock, _Mtx_trylock, _Mtx_unlock, _Cnd_init(_with_name), _Cnd_destroy, _Cnd_wait, _Cnd_signal, _Cnd_broadcast, _Thrd_detach, _Thrd_join, _Thrd_yield, _Thrd_id and _Throw_Cpp_error. libkernel registers the pthread calls with libc next to the C11 forwards. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01RbLgECLQ2bpDM7oe2urGZK --- core/libs/prx/libc/include/General.hpp | 19 +++ core/libs/prx/libc/src/Threads.cpp | 122 ++++++++++++++++++ .../prx/libkernel/Pthread/Posix/Thread.cpp | 33 +++++ core/libs/tests/GuestLibcThreads.cpp | 83 ++++++++++++ 4 files changed, 257 insertions(+) diff --git a/core/libs/prx/libc/include/General.hpp b/core/libs/prx/libc/include/General.hpp index beaa7fd585..7e08b51ea1 100644 --- a/core/libs/prx/libc/include/General.hpp +++ b/core/libs/prx/libc/include/General.hpp @@ -69,6 +69,25 @@ struct ThreadForwards_nid_no_patch { void (APS5_VABI* exit)(void*); }; extern "C" void RegisterThreadForwards_nid_no_patch(const ThreadForwards_nid_no_patch* forwards); +struct PthreadSyncForwards_nid_no_patch { + int (APS5_VABI* mutexattrInit)(void**); + int (APS5_VABI* mutexattrSettype)(void**, int); + int (APS5_VABI* mutexattrDestroy)(void**); + int (APS5_VABI* mutexInit)(void**, void* const*, const char*); + int (APS5_VABI* mutexDestroy)(void**); + int (APS5_VABI* mutexLock)(void**); + int (APS5_VABI* mutexTrylock)(void**); + int (APS5_VABI* mutexUnlock)(void**); + int (APS5_VABI* condInit)(void**, void* const*, const char*); + int (APS5_VABI* condDestroy)(void**); + int (APS5_VABI* condWait)(void**, void**); + int (APS5_VABI* condSignal)(void**); + int (APS5_VABI* condBroadcast)(void**); + int (APS5_VABI* detach)(void*); + int (APS5_VABI* join)(void*, void**); + void (APS5_VABI* yield)(); +}; +extern "C" void RegisterPthreadSyncForwards_nid_no_patch(const PthreadSyncForwards_nid_no_patch* forwards); #define APS5_INVALID_ARG_EX throw std::invalid_argument(std::string(__func__) + ": invalid argument") diff --git a/core/libs/prx/libc/src/Threads.cpp b/core/libs/prx/libc/src/Threads.cpp index a00ba39463..02c0d2744a 100644 --- a/core/libs/prx/libc/src/Threads.cpp +++ b/core/libs/prx/libc/src/Threads.cpp @@ -546,5 +546,127 @@ int APS5_VABI _Mtx_current_owns_nid_postfix(void**) { return 1; } +static std::atomic registeredPthreadSyncForwards{nullptr}; + +void RegisterPthreadSyncForwards_nid_no_patch(const PthreadSyncForwards_nid_no_patch* forwards) { + registeredPthreadSyncForwards.store(forwards, std::memory_order_release); +} + +static const PthreadSyncForwards_nid_no_patch& PthreadSync(const char* function) { + const auto* forwards = registeredPthreadSyncForwards.load(std::memory_order_acquire); + if (!forwards) throw std::runtime_error(std::string(function) + ": libkernel synchronization is not registered"); + return *forwards; +} + +constexpr int KernelDeadlock = static_cast(0x8002000b); +constexpr int KernelNoMemory = static_cast(0x8002000c); +constexpr int KernelBusy = static_cast(0x80020010); +constexpr int RecursiveMutexType = 0x100; +constexpr int KernelRecursiveMutex = 2; + +static int CreateResult(int result) { + if (result == 0) return threadSuccess; + return result == KernelNoMemory ? threadNomem : threadError; +} + +static const char* SyncObjectName(const char* name) { + return name != nullptr && name[0] != '\0' ? name : nullptr; +} + +int APS5_VABI _ZNSt8__sce_v219_Mtx_init_with_nameEPP13pthread_mutexiPKc_nid_postfix(void** mutex, int type, const char* name) { + const auto& sync = PthreadSync(__func__); + *mutex = nullptr; + void* attr = nullptr; + const int created = sync.mutexattrInit(&attr); + if (created != 0) return CreateResult(created); + if ((type & RecursiveMutexType) != 0 && sync.mutexattrSettype(&attr, KernelRecursiveMutex) != 0) { + sync.mutexattrDestroy(&attr); + return threadError; + } + const int initialized = sync.mutexInit(mutex, &attr, SyncObjectName(name)); + const int released = sync.mutexattrDestroy(&attr); + if (initialized != 0) return CreateResult(initialized); + if (released != 0) { + sync.mutexDestroy(mutex); + return threadError; + } + return threadSuccess; +} + +int APS5_VABI _ZNSt8__sce_v29_Mtx_initEPP13pthread_mutexi_nid_postfix(void** mutex, int type) { + return _ZNSt8__sce_v219_Mtx_init_with_nameEPP13pthread_mutexiPKc_nid_postfix(mutex, type, "SceLibcI_Mtx"); +} + +int APS5_VABI _ZNSt8__sce_v212_Mtx_destroyEPP13pthread_mutex_nid_postfix(void** mutex) { + return PthreadSync(__func__).mutexDestroy(mutex); +} + +int APS5_VABI _ZNSt8__sce_v29_Mtx_lockEPP13pthread_mutex_nid_postfix(void** mutex) { + const int result = PthreadSync(__func__).mutexLock(mutex); + if (result == 0) return threadSuccess; + return result == KernelDeadlock ? threadBusy : threadError; +} + +int APS5_VABI _ZNSt8__sce_v212_Mtx_trylockEPP13pthread_mutex_nid_postfix(void** mutex) { + const int result = PthreadSync(__func__).mutexTrylock(mutex); + if (result == 0) return threadSuccess; + return result == KernelBusy ? threadBusy : threadError; +} + +int APS5_VABI _ZNSt8__sce_v211_Mtx_unlockEPP13pthread_mutex_nid_postfix(void** mutex) { + PthreadSync(__func__).mutexUnlock(mutex); + return threadSuccess; +} + +int APS5_VABI _ZNSt8__sce_v219_Cnd_init_with_nameEPP12pthread_condPKc_nid_postfix(void** condition, const char* name) { + return CreateResult(PthreadSync(__func__).condInit(condition, nullptr, SyncObjectName(name))); +} + +int APS5_VABI _ZNSt8__sce_v29_Cnd_initEPP12pthread_cond_nid_postfix(void** condition) { + return CreateResult(PthreadSync(__func__).condInit(condition, nullptr, "SceLibcI_Cnd")); +} + +int APS5_VABI _ZNSt8__sce_v212_Cnd_destroyEPP12pthread_cond_nid_postfix(void** condition) { + return PthreadSync(__func__).condDestroy(condition); +} + +int APS5_VABI _ZNSt8__sce_v29_Cnd_waitEPP12pthread_condPP13pthread_mutex_nid_postfix(void** condition, void** mutex) { + PthreadSync(__func__).condWait(condition, mutex); + return threadSuccess; +} + +int APS5_VABI _ZNSt8__sce_v211_Cnd_signalEPP12pthread_cond_nid_postfix(void** condition) { + PthreadSync(__func__).condSignal(condition); + return threadSuccess; +} + +int APS5_VABI _ZNSt8__sce_v214_Cnd_broadcastEPP12pthread_cond_nid_postfix(void** condition) { + PthreadSync(__func__).condBroadcast(condition); + return threadSuccess; +} + +int APS5_VABI _ZNSt8__sce_v212_Thrd_detachEP7pthread_nid_postfix(void* thread) { + return PthreadSync(__func__).detach(thread) == 0 ? threadSuccess : threadError; +} + +int APS5_VABI _ZNSt8__sce_v210_Thrd_joinEP7pthreadPi_nid_postfix(void* thread, int* code) { + void* result = nullptr; + if (PthreadSync(__func__).join(thread, &result) != 0) return threadError; + if (code) *code = static_cast(reinterpret_cast(result)); + return threadSuccess; +} + +void APS5_VABI _ZNSt8__sce_v211_Thrd_yieldEv_nid_postfix() { + PthreadSync(__func__).yield(); +} + +void* APS5_VABI _ZNSt8__sce_v28_Thrd_idEv_nid_postfix() { + return _Thrd_current_nid_postfix(); +} + +[[noreturn]] void APS5_VABI _ZNSt8__sce_v216_Throw_Cpp_errorEi_nid_postfix(int code) { + ThrowCppError_nid_no_patch(code); +} + } diff --git a/core/libs/prx/libkernel/Pthread/Posix/Thread.cpp b/core/libs/prx/libkernel/Pthread/Posix/Thread.cpp index 12589bc185..6de0cbb2e2 100644 --- a/core/libs/prx/libkernel/Pthread/Posix/Thread.cpp +++ b/core/libs/prx/libkernel/Pthread/Posix/Thread.cpp @@ -27,6 +27,20 @@ int APS5_VABI scePthreadKeyCreate(PthreadKey* key, pthread_key_destructor_func_t int APS5_VABI scePthreadKeyDelete(PthreadKey key); void* APS5_VABI scePthreadGetspecific(PthreadKey key); int APS5_VABI scePthreadSetspecific(PthreadKey key, void* value); +int APS5_VABI scePthreadMutexattrInit(PthreadMutexattr* attr); +int APS5_VABI scePthreadMutexattrSettype(PthreadMutexattr* attr, int type); +int APS5_VABI scePthreadMutexattrDestroy(PthreadMutexattr* attr); +int APS5_VABI scePthreadMutexInit(PthreadMutex* mutex, const PthreadMutexattr* attr, const char* name); +int APS5_VABI scePthreadMutexDestroy(PthreadMutex* mutex); +int APS5_VABI scePthreadMutexLock(PthreadMutex* mutex); +int APS5_VABI scePthreadMutexTrylock(PthreadMutex* mutex); +int APS5_VABI scePthreadMutexUnlock(PthreadMutex* mutex); +int APS5_VABI scePthreadCondInit(PthreadCond* cond, const PthreadCondattr* attr, const char* name); +int APS5_VABI scePthreadCondDestroy(PthreadCond* cond); +int APS5_VABI scePthreadCondWait(PthreadCond* cond, PthreadMutex* mutex); +int APS5_VABI scePthreadCondSignal(PthreadCond* cond); +int APS5_VABI scePthreadCondBroadcast(PthreadCond* cond); +void APS5_VABI scePthreadYield(); int APS5_VABI scePthreadCancel(Pthread thread); int APS5_VABI scePthreadSetcancelstate(int state, int* old_state); int APS5_VABI scePthreadSetcanceltype(int type, int* old_type); @@ -257,6 +271,25 @@ struct RegisterPthreadOnLoad { scePthreadExit, }; RegisterThreadForwards_nid_no_patch(&forwards); + static const PthreadSyncForwards_nid_no_patch sync{ + reinterpret_cast(scePthreadMutexattrInit), + reinterpret_cast(scePthreadMutexattrSettype), + reinterpret_cast(scePthreadMutexattrDestroy), + reinterpret_cast(scePthreadMutexInit), + reinterpret_cast(scePthreadMutexDestroy), + reinterpret_cast(scePthreadMutexLock), + reinterpret_cast(scePthreadMutexTrylock), + reinterpret_cast(scePthreadMutexUnlock), + reinterpret_cast(scePthreadCondInit), + reinterpret_cast(scePthreadCondDestroy), + reinterpret_cast(scePthreadCondWait), + reinterpret_cast(scePthreadCondSignal), + reinterpret_cast(scePthreadCondBroadcast), + reinterpret_cast(scePthreadDetach), + reinterpret_cast(scePthreadJoin), + scePthreadYield, + }; + RegisterPthreadSyncForwards_nid_no_patch(&sync); } }; const RegisterPthreadOnLoad gRegisterPthread; diff --git a/core/libs/tests/GuestLibcThreads.cpp b/core/libs/tests/GuestLibcThreads.cpp index 102b21ada0..c49db54831 100644 --- a/core/libs/tests/GuestLibcThreads.cpp +++ b/core/libs/tests/GuestLibcThreads.cpp @@ -54,6 +54,23 @@ int APS5_VABI _Tss_set_nid_postfix(int key, void* value); int APS5_VABI _Thrd_equal_nid_postfix(void* first, void* second); void* APS5_VABI _Thrd_current_nid_postfix(void); int APS5_VABI _Mtx_current_owns_nid_postfix(void** handle); +int APS5_VABI _ZNSt8__sce_v29_Mtx_initEPP13pthread_mutexi_nid_postfix(void** mutex, int type); +int APS5_VABI _ZNSt8__sce_v219_Mtx_init_with_nameEPP13pthread_mutexiPKc_nid_postfix(void** mutex, int type, const char* name); +int APS5_VABI _ZNSt8__sce_v212_Mtx_destroyEPP13pthread_mutex_nid_postfix(void** mutex); +int APS5_VABI _ZNSt8__sce_v29_Mtx_lockEPP13pthread_mutex_nid_postfix(void** mutex); +int APS5_VABI _ZNSt8__sce_v212_Mtx_trylockEPP13pthread_mutex_nid_postfix(void** mutex); +int APS5_VABI _ZNSt8__sce_v211_Mtx_unlockEPP13pthread_mutex_nid_postfix(void** mutex); +int APS5_VABI _ZNSt8__sce_v29_Cnd_initEPP12pthread_cond_nid_postfix(void** condition); +int APS5_VABI _ZNSt8__sce_v219_Cnd_init_with_nameEPP12pthread_condPKc_nid_postfix(void** condition, const char* name); +int APS5_VABI _ZNSt8__sce_v212_Cnd_destroyEPP12pthread_cond_nid_postfix(void** condition); +int APS5_VABI _ZNSt8__sce_v29_Cnd_waitEPP12pthread_condPP13pthread_mutex_nid_postfix(void** condition, void** mutex); +int APS5_VABI _ZNSt8__sce_v211_Cnd_signalEPP12pthread_cond_nid_postfix(void** condition); +int APS5_VABI _ZNSt8__sce_v214_Cnd_broadcastEPP12pthread_cond_nid_postfix(void** condition); +int APS5_VABI _ZNSt8__sce_v212_Thrd_detachEP7pthread_nid_postfix(void* thread); +int APS5_VABI _ZNSt8__sce_v210_Thrd_joinEP7pthreadPi_nid_postfix(void* thread, int* code); +void APS5_VABI _ZNSt8__sce_v211_Thrd_yieldEv_nid_postfix(); +void* APS5_VABI _ZNSt8__sce_v28_Thrd_idEv_nid_postfix(); +int APS5_VABI scePthreadCreate(void** thread, const void* attr, void* (APS5_VABI* entry)(void*), void* argument, const char* name); } static void Require(bool value) { if (!value) std::abort(); } @@ -372,8 +389,74 @@ static void ForwardedCalls() { RequireThrows([] { _Tss_get_nid_postfix(0); }); } +struct VersionedShared { + void* mutex = nullptr; + void* condition = nullptr; + std::atomic stage{0}; + int tryResult = -1; +}; + +static void* APS5_VABI VersionedWorker(void* argument) { + auto* shared = static_cast(argument); + shared->tryResult = _ZNSt8__sce_v212_Mtx_trylockEPP13pthread_mutex_nid_postfix(&shared->mutex); + shared->stage = 1; + Require(_ZNSt8__sce_v29_Mtx_lockEPP13pthread_mutex_nid_postfix(&shared->mutex) == success); + shared->stage = 2; + Require(_ZNSt8__sce_v211_Cnd_signalEPP12pthread_cond_nid_postfix(&shared->condition) == success); + Require(_ZNSt8__sce_v211_Mtx_unlockEPP13pthread_mutex_nid_postfix(&shared->mutex) == success); + return reinterpret_cast(std::intptr_t{42}); +} + +static void* APS5_VABI DetachedWorker(void*) { return nullptr; } + +static void VersionedSync() { + void* recursiveMutex = reinterpret_cast(std::uintptr_t{1}); + Require(_ZNSt8__sce_v29_Mtx_initEPP13pthread_mutexi_nid_postfix(&recursiveMutex, plain | recursive) == success && recursiveMutex != nullptr); + Require(_ZNSt8__sce_v29_Mtx_lockEPP13pthread_mutex_nid_postfix(&recursiveMutex) == success); + Require(_ZNSt8__sce_v29_Mtx_lockEPP13pthread_mutex_nid_postfix(&recursiveMutex) == success); + Require(_ZNSt8__sce_v212_Mtx_trylockEPP13pthread_mutex_nid_postfix(&recursiveMutex) == success); + for (int unlock = 0; unlock < 3; ++unlock) Require(_ZNSt8__sce_v211_Mtx_unlockEPP13pthread_mutex_nid_postfix(&recursiveMutex) == success); + Require(_ZNSt8__sce_v212_Mtx_destroyEPP13pthread_mutex_nid_postfix(&recursiveMutex) == success); + + void* plainMutex = nullptr; + Require(_ZNSt8__sce_v219_Mtx_init_with_nameEPP13pthread_mutexiPKc_nid_postfix(&plainMutex, plain, "") == success); + Require(_ZNSt8__sce_v29_Mtx_lockEPP13pthread_mutex_nid_postfix(&plainMutex) == success); + Require(_ZNSt8__sce_v29_Mtx_lockEPP13pthread_mutex_nid_postfix(&plainMutex) == busy); + Require(_ZNSt8__sce_v211_Mtx_unlockEPP13pthread_mutex_nid_postfix(&plainMutex) == success); + Require(_ZNSt8__sce_v212_Mtx_destroyEPP13pthread_mutex_nid_postfix(&plainMutex) == success); + + VersionedShared shared; + Require(_ZNSt8__sce_v29_Mtx_initEPP13pthread_mutexi_nid_postfix(&shared.mutex, plain) == success); + Require(_ZNSt8__sce_v219_Cnd_init_with_nameEPP12pthread_condPKc_nid_postfix(&shared.condition, "versioned") == success); + Require(_ZNSt8__sce_v29_Mtx_lockEPP13pthread_mutex_nid_postfix(&shared.mutex) == success); + void* thread = nullptr; + Require(scePthreadCreate(&thread, nullptr, VersionedWorker, &shared, "versioned") == 0); + while (shared.stage.load() == 0) std::this_thread::yield(); + while (shared.stage.load() == 1) Require(_ZNSt8__sce_v29_Cnd_waitEPP12pthread_condPP13pthread_mutex_nid_postfix(&shared.condition, &shared.mutex) == success); + Require(shared.tryResult == busy); + Require(_ZNSt8__sce_v211_Mtx_unlockEPP13pthread_mutex_nid_postfix(&shared.mutex) == success); + int code = 0; + Require(_ZNSt8__sce_v210_Thrd_joinEP7pthreadPi_nid_postfix(thread, &code) == success && code == 42); + Require(_ZNSt8__sce_v210_Thrd_joinEP7pthreadPi_nid_postfix(thread, &code) == 4); + Require(_ZNSt8__sce_v214_Cnd_broadcastEPP12pthread_cond_nid_postfix(&shared.condition) == success); + Require(_ZNSt8__sce_v212_Cnd_destroyEPP12pthread_cond_nid_postfix(&shared.condition) == success); + Require(_ZNSt8__sce_v212_Mtx_destroyEPP13pthread_mutex_nid_postfix(&shared.mutex) == success); + + void* condition = nullptr; + Require(_ZNSt8__sce_v29_Cnd_initEPP12pthread_cond_nid_postfix(&condition) == success); + Require(_ZNSt8__sce_v212_Cnd_destroyEPP12pthread_cond_nid_postfix(&condition) == success); + + void* detached = nullptr; + Require(scePthreadCreate(&detached, nullptr, DetachedWorker, nullptr, "detached") == 0); + Require(_ZNSt8__sce_v212_Thrd_detachEP7pthread_nid_postfix(detached) == success); + Require(_ZNSt8__sce_v212_Thrd_detachEP7pthread_nid_postfix(nullptr) == 4); + _ZNSt8__sce_v211_Thrd_yieldEv_nid_postfix(); + Require(_ZNSt8__sce_v28_Thrd_idEv_nid_postfix() != nullptr); +} + int main() { KernelKeys(); + VersionedSync(); ForwardedCalls(); MutexBasics(); RecursiveMutex(); From ae4d607a54d417818158bea13ba455a1d568634d Mon Sep 17 00:00:00 2001 From: hypermist Date: Wed, 21 Oct 2026 17:42:03 +1300 Subject: [PATCH 2/3] fix(libc): drop the versioned _Throw_Cpp_error and pin dropped results The console's std::__sce_v2::_Throw_Cpp_error raises a std::__sce_v2::system_error, not the unversioned std::system_error this forwarded to. It moves to the versioned exception change, which adds that type. Review on #8885: the versioned unlock, wait, signal and broadcast calls return 0 whatever the kernel returns, as the console's do (each calls the kernel and clears eax). The test now shows the kernel failing an unowned unlock and wait while the wrappers report success. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01RbLgECLQ2bpDM7oe2urGZK --- core/libs/prx/libc/src/Threads.cpp | 4 ---- core/libs/tests/GuestLibcThreads.cpp | 9 +++++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/core/libs/prx/libc/src/Threads.cpp b/core/libs/prx/libc/src/Threads.cpp index 02c0d2744a..622bccbb0a 100644 --- a/core/libs/prx/libc/src/Threads.cpp +++ b/core/libs/prx/libc/src/Threads.cpp @@ -664,9 +664,5 @@ void* APS5_VABI _ZNSt8__sce_v28_Thrd_idEv_nid_postfix() { return _Thrd_current_nid_postfix(); } -[[noreturn]] void APS5_VABI _ZNSt8__sce_v216_Throw_Cpp_errorEi_nid_postfix(int code) { - ThrowCppError_nid_no_patch(code); -} - } diff --git a/core/libs/tests/GuestLibcThreads.cpp b/core/libs/tests/GuestLibcThreads.cpp index c49db54831..eb34d7a050 100644 --- a/core/libs/tests/GuestLibcThreads.cpp +++ b/core/libs/tests/GuestLibcThreads.cpp @@ -71,6 +71,8 @@ int APS5_VABI _ZNSt8__sce_v210_Thrd_joinEP7pthreadPi_nid_postfix(void* thread, i void APS5_VABI _ZNSt8__sce_v211_Thrd_yieldEv_nid_postfix(); void* APS5_VABI _ZNSt8__sce_v28_Thrd_idEv_nid_postfix(); int APS5_VABI scePthreadCreate(void** thread, const void* attr, void* (APS5_VABI* entry)(void*), void* argument, const char* name); +int APS5_VABI scePthreadMutexUnlock(void** mutex); +int APS5_VABI scePthreadCondWait(void** condition, void** mutex); } static void Require(bool value) { if (!value) std::abort(); } @@ -423,6 +425,13 @@ static void VersionedSync() { Require(_ZNSt8__sce_v29_Mtx_lockEPP13pthread_mutex_nid_postfix(&plainMutex) == success); Require(_ZNSt8__sce_v29_Mtx_lockEPP13pthread_mutex_nid_postfix(&plainMutex) == busy); Require(_ZNSt8__sce_v211_Mtx_unlockEPP13pthread_mutex_nid_postfix(&plainMutex) == success); + void* unownedCondition = nullptr; + Require(_ZNSt8__sce_v29_Cnd_initEPP12pthread_cond_nid_postfix(&unownedCondition) == success); + Require(scePthreadMutexUnlock(&plainMutex) != 0); + Require(scePthreadCondWait(&unownedCondition, &plainMutex) != 0); + Require(_ZNSt8__sce_v211_Mtx_unlockEPP13pthread_mutex_nid_postfix(&plainMutex) == success); + Require(_ZNSt8__sce_v29_Cnd_waitEPP12pthread_condPP13pthread_mutex_nid_postfix(&unownedCondition, &plainMutex) == success); + Require(_ZNSt8__sce_v212_Cnd_destroyEPP12pthread_cond_nid_postfix(&unownedCondition) == success); Require(_ZNSt8__sce_v212_Mtx_destroyEPP13pthread_mutex_nid_postfix(&plainMutex) == success); VersionedShared shared; From f465759bcfca69fd504fb311b91dc4bfbd10c32d Mon Sep 17 00:00:00 2001 From: hypermist Date: Thu, 22 Oct 2026 21:57:55 +1300 Subject: [PATCH 3/3] fix(libkernel): drop the duplicate scePthreadYield declaration Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01RbLgECLQ2bpDM7oe2urGZK --- core/libs/prx/libkernel/Pthread/Posix/Thread.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/core/libs/prx/libkernel/Pthread/Posix/Thread.cpp b/core/libs/prx/libkernel/Pthread/Posix/Thread.cpp index c593bc0ae0..95573087f8 100644 --- a/core/libs/prx/libkernel/Pthread/Posix/Thread.cpp +++ b/core/libs/prx/libkernel/Pthread/Posix/Thread.cpp @@ -40,7 +40,6 @@ int APS5_VABI scePthreadCondDestroy(PthreadCond* cond); int APS5_VABI scePthreadCondWait(PthreadCond* cond, PthreadMutex* mutex); int APS5_VABI scePthreadCondSignal(PthreadCond* cond); int APS5_VABI scePthreadCondBroadcast(PthreadCond* cond); -void APS5_VABI scePthreadYield(); int APS5_VABI scePthreadCancel(Pthread thread); int APS5_VABI scePthreadSetcancelstate(int state, int* old_state); int APS5_VABI scePthreadSetcanceltype(int type, int* old_type);