An ulthread runs on its own guest thread, so it remembers its object for sceUltUlthreadGetSelf, yields that thread, and exits it with the status sceUltUlthreadJoin and sceUltUlthreadTryJoin return. Outside an ulthread the three return ULT_ERROR_STATE.
Readers share the lock while no writer holds it and a writer waits until it is free. Destroying a held or waited-on lock and destroying the waiting-queue pool of a lock a thread waits on return ULT_ERROR_BUSY, and sceUltFinalize wakes waiters with ULT_ERROR_STATE, as for the mutex.
It takes a free mutex or relocks one the caller holds, as sceUltMutexLock does, and returns ULT_ERROR_BUSY instead of waiting when another thread holds it.