# libSceUlt technical debt ### Unknown function info - [Bound condition variables](../../../core/libs/prx/libSceUlt/Export.cpp) use the creation-time mutex, inferred from PPSA28061 callers of `_sceUltConditionVariableCreate`; the wait caller reloads only the condition argument. Error precedence, busy/state errors, FIFO signal selection and unsupported recursive waits have not been measured on PS5 hardware. Non-null options and waits at recursion depth above one throw. A live condition prevents destroying its bound mutex. Finalization follows the existing host mutex lifecycle: it invalidates conditions and wakes queued or reacquiring waiters with a state error. Scheduling priority and build-version validation are not implemented. - [libSceUlt ulthreads](../../../core/libs/prx/libSceUlt/Export.cpp) - Runtime option defaults still omit the native header, stack size, worker affinity and priority fields; affinity depends on unresolved process configuration queries. Concurrent join ownership is not modeled: the native runtime distinguishes an ordinary running thread from one with another joiner. Host threads do not use the guest context or worker scheduler. - [libSceUlt queues](../../../core/libs/prx/libSceUlt/Export.cpp) - Queue-data pool destruction and shared slot limits still require comparison with the native node allocator. - [Ult factory and creation exports](../../../core/libs/prx/libSceUlt/Export.cpp) without a leading underscore are absent from the supplied module; their signatures remain unresolved. Diagnostic signatures and synchronization argument lists are recovered. - [sceUltMutexTryLock, the reader-writer lock and sceUltUlthreadGetSelf, sceUltUlthreadYield and sceUltUlthreadExit](../../../core/libs/prx/libSceUlt/src/ReaderWriterLock.cpp) (libSceUlt) - the signatures follow the PS Vita libult in [RPCS3](https://github.com/RPCS3/rpcs3/blob/13aa88c3c4d66ea8799e987f7d762d90943ab17b/rpcs3/Emu/PSP2/Modules/sceUlt.cpp) (a 256-byte lock and 128-byte option structures), not a PS5 binary. The rules are assumed: readers may take the lock while a writer waits, a thread that holds the write lock gets `ULT_ERROR_STATE` for any further lock instead of waiting on itself, a reader asking for the write lock waits on its own read lock, and the try forms return `ULT_ERROR_BUSY`. Outside an ulthread, `sceUltUlthreadGetSelf`, `sceUltUlthreadYield` and `sceUltUlthreadExit` return `ULT_ERROR_STATE`; inside one they act on the guest thread it runs on, since ulthreads are not scheduled cooperatively here ### Functional - [libSceUlt queues](../../../core/libs/prx/libSceUlt/Export.cpp) use preallocated host storage instead of the supplied guest work area; the guest object layouts remain incomplete. Waiting-queue pool thread limits and waiter priority ordering are not implemented. Finalization wakes blocked queue callers with `ULT_ERROR_STATE`. - [sceUltWaitingQueueResourcePoolDestroy](../../../core/libs/prx/libSceUlt/Export.cpp) refuses with `ULT_ERROR_STATE` only when a thread is currently waiting on a pool-backed mutex, semaphore or queue, matching the PS5 libSceUlt disassembly (0x473a in or55417wcDk); bound but idle objects do not block pool destruction. Waiting-queue pool guest work area node accounting is not implemented. - The following pending declarations have unverified signatures and behavior; they are parameterless import-resolution declarations and throw through `NotImplemented_nid_no_patch`: [`_sceUltConditionVariableOptParamInitialize`](../../../core/libs/prx/libSceUlt/Export.cpp).