Files
AnyPS5/core/libs/tests/GuestKernelSysPthreadNp.cpp
T
Yunus Shaikh 0d81fe5712 feat(libkernel): add pthread_rwlockattr_settype_np
The POSIX name moves from a libkernel_sys stub to libkernel and stores the
type through its SCE twin scePthreadRwlockattrSettype, converting the
result as the other POSIX rwlock calls do.

guest_kernel_sys_pthread_np_rwlockattr checks types 0, 1 and 2 through
both names, a rwlock built from the attribute, and the throws for a
destroyed or null attribute.
2026-10-22 03:02:46 +00:00

70 lines
2.5 KiB
C++

#include "SceTypes.hpp"
#include <cstdio>
#include <exception>
#include <initializer_list>
#include <stdexcept>
#include <string_view>
extern "C" {
int APS5_VABI pthread_rwlock_init_nid_postfix(PthreadRwlock* rwlock, const PthreadRwlockattr* attr);
int APS5_VABI pthread_rwlock_wrlock_nid_postfix(PthreadRwlock* rwlock);
int APS5_VABI pthread_rwlock_unlock_nid_postfix(PthreadRwlock* rwlock);
int APS5_VABI pthread_rwlock_destroy_nid_postfix(PthreadRwlock* rwlock);
int APS5_VABI pthread_rwlockattr_init_nid_postfix(PthreadRwlockattr* attr);
int APS5_VABI pthread_rwlockattr_destroy_nid_postfix(PthreadRwlockattr* attr);
int APS5_VABI pthread_rwlockattr_settype_np_nid_postfix(PthreadRwlockattr* attr, int type);
int APS5_VABI scePthreadRwlockattrSettype(PthreadRwlockattr* attr, int type);
}
namespace {
int failures = 0;
template<typename TCall>
void Case(const char* name, TCall call) {
try {
if (call()) return;
std::printf("%s: wrong answer\n", name);
} catch (const std::exception& error) {
std::printf("%s: %s\n", name, error.what());
}
++failures;
}
template<typename TException, typename TCall>
bool Throws(TCall call) {
try {
static_cast<void>(call());
} catch (const TException&) {
return true;
}
return false;
}
void TestRwlockattr() {
Case("pthread_rwlockattr_settype_np", [] {
PthreadRwlockattr attr = nullptr;
if (pthread_rwlockattr_init_nid_postfix(&attr) != 0) return false;
for (const int type : {0, 1, 2}) {
if (pthread_rwlockattr_settype_np_nid_postfix(&attr, type) != 0 || scePthreadRwlockattrSettype(&attr, type) != 0) return false;
PthreadRwlock rwlock = nullptr;
if (pthread_rwlock_init_nid_postfix(&rwlock, &attr) != 0) return false;
const bool usable = pthread_rwlock_wrlock_nid_postfix(&rwlock) == 0 && pthread_rwlock_unlock_nid_postfix(&rwlock) == 0;
if (!usable || pthread_rwlock_destroy_nid_postfix(&rwlock) != 0) return false;
}
if (pthread_rwlockattr_destroy_nid_postfix(&attr) != 0) return false;
return Throws<std::runtime_error>([&] { return pthread_rwlockattr_settype_np_nid_postfix(&attr, 1); }) &&
Throws<std::runtime_error>([] { return pthread_rwlockattr_settype_np_nid_postfix(nullptr, 1); });
});
}
}
int main(int argc, char** argv) {
const std::string_view mode = argc > 1 ? argv[1] : "";
if (mode == "rwlockattr") TestRwlockattr();
else return 2;
if (failures == 0) std::printf("all cases passed\n");
return failures == 0 ? 0 : 1;
}