Files
AnyPS5/core/libs/tests/GuestPthreadMutexattr.cpp
T
ps54all 08728f95b9 feat(libkernel): implement pthread_mutexattr_setprioceiling and getprioceiling
The mutex attribute now keeps its protocol and priority ceiling the way
FreeBSD's libthr does: the ceiling can be set and read only under
PTHREAD_PRIO_PROTECT (EINVAL otherwise), and setting a protocol resets it
to the highest SCHED_RR priority. Mutexes still do not apply priority
protection; that is listed as a silent stub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit d10c024f8f)
2026-10-10 18:12:31 +00:00

63 lines
3.2 KiB
C++

#include "SceTypes.hpp"
#include <cstdlib>
#include <stdexcept>
extern "C" {
int APS5_VABI pthread_mutexattr_init_nid_postfix(PthreadMutexattr* attr);
int APS5_VABI pthread_mutexattr_destroy_nid_postfix(PthreadMutexattr* attr);
int APS5_VABI pthread_mutexattr_setprotocol_nid_postfix(PthreadMutexattr* attr, int protocol);
int APS5_VABI pthread_mutexattr_setprioceiling_nid_postfix(PthreadMutexattr* attr, int prioceiling);
int APS5_VABI pthread_mutexattr_getprioceiling_nid_postfix(const PthreadMutexattr* attr, int* prioceiling);
int APS5_VABI pthread_mutex_init_nid_postfix(PthreadMutex* mutex, const PthreadMutexattr* attr);
int APS5_VABI pthread_mutex_lock_nid_postfix(PthreadMutex* mutex);
int APS5_VABI pthread_mutex_unlock_nid_postfix(PthreadMutex* mutex);
int APS5_VABI pthread_mutex_destroy_nid_postfix(PthreadMutex* mutex);
int APS5_VABI sched_get_priority_max_nid_postfix(int policy);
}
static constexpr int GUEST_EINVAL = 22;
static constexpr int PRIO_NONE = 0;
static constexpr int PRIO_INHERIT = 1;
static constexpr int PRIO_PROTECT = 2;
static constexpr int SCHED_RR = 3;
static void Require(bool value) { if (!value) std::abort(); }
template <typename Call>
static bool Throws(Call call) {
try {
call();
} catch (const std::exception&) {
return true;
}
return false;
}
int main() {
PthreadMutexattr attr = nullptr;
Require(pthread_mutexattr_init_nid_postfix(&attr) == 0);
int ceiling = -1;
Require(pthread_mutexattr_getprioceiling_nid_postfix(&attr, &ceiling) == GUEST_EINVAL && ceiling == -1);
Require(pthread_mutexattr_setprioceiling_nid_postfix(&attr, 300) == GUEST_EINVAL);
Require(pthread_mutexattr_setprotocol_nid_postfix(&attr, PRIO_INHERIT) == 0);
Require(pthread_mutexattr_setprioceiling_nid_postfix(&attr, 300) == GUEST_EINVAL);
Require(pthread_mutexattr_setprotocol_nid_postfix(&attr, PRIO_PROTECT) == 0);
Require(pthread_mutexattr_getprioceiling_nid_postfix(&attr, &ceiling) == 0 && ceiling == sched_get_priority_max_nid_postfix(SCHED_RR));
Require(pthread_mutexattr_setprioceiling_nid_postfix(&attr, 300) == 0);
Require(pthread_mutexattr_getprioceiling_nid_postfix(&attr, &ceiling) == 0 && ceiling == 300);
PthreadMutex mutex = nullptr;
Require(pthread_mutex_init_nid_postfix(&mutex, &attr) == 0);
Require(pthread_mutex_lock_nid_postfix(&mutex) == 0);
Require(pthread_mutex_unlock_nid_postfix(&mutex) == 0);
Require(pthread_mutex_destroy_nid_postfix(&mutex) == 0);
Require(pthread_mutexattr_setprotocol_nid_postfix(&attr, PRIO_PROTECT) == 0);
Require(pthread_mutexattr_getprioceiling_nid_postfix(&attr, &ceiling) == 0 && ceiling == sched_get_priority_max_nid_postfix(SCHED_RR));
Require(pthread_mutexattr_setprotocol_nid_postfix(&attr, PRIO_NONE) == 0);
Require(pthread_mutexattr_getprioceiling_nid_postfix(&attr, &ceiling) == GUEST_EINVAL);
Require(Throws([&] { pthread_mutexattr_getprioceiling_nid_postfix(&attr, nullptr); }));
Require(pthread_mutexattr_destroy_nid_postfix(&attr) == 0);
Require(Throws([&] { pthread_mutexattr_setprioceiling_nid_postfix(&attr, 300); }));
Require(Throws([&] { pthread_mutexattr_getprioceiling_nid_postfix(&attr, &ceiling); }));
return 0;
}