mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-04 13:07:32 +00:00
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.
70 lines
2.5 KiB
C++
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;
|
|
}
|