#include "SceTypes.hpp" #include "prx/libc/include/general/VabiMacros.hpp" #include #include #include #include #include extern "C" { int APS5_VABI sem_init_nid_postfix(void*, int, unsigned int); int APS5_VABI sem_destroy_nid_postfix(void*); int APS5_VABI sem_post_nid_postfix(void*); int APS5_VABI sem_trywait_nid_postfix(void*); int APS5_VABI sem_getvalue_nid_postfix(void*, int*); int* APS5_VABI __error_nid_postfix(); } static void Require(bool condition, const char* message) { if (!condition) { std::fprintf(stderr, "%s\n", message); std::abort(); } } int main(int argc, char** argv) { constexpr unsigned int maximum = 0x7fffffffu; std::uintptr_t sem = 0; int value = -1; if (argc > 1 && std::strcmp(argv[1], "init") == 0) { for (const unsigned int initial : {maximum + 1, 0xffffffffu}) { sem = 0x1234; *__error_nid_postfix() = 0; const int result = sem_init_nid_postfix(&sem, 0, initial); std::fprintf(stderr, "sem_init(%u): result=%d errno=%d\n", initial, result, *__error_nid_postfix()); Require(result == -1 && *__error_nid_postfix() == 22, "initial count above maximum must fail with EINVAL"); Require(sem == 0x1234, "failed initialization changed semaphore storage"); } return 0; } Require(sem_init_nid_postfix(&sem, 0, maximum) == 0, "maximum count must initialize"); Require(sem_getvalue_nid_postfix(&sem, &value) == 0 && value == static_cast(maximum), "maximum count must be readable"); *__error_nid_postfix() = 0; const int result = sem_post_nid_postfix(&sem); std::fprintf(stderr, "sem_post(maximum): result=%d errno=%d\n", result, *__error_nid_postfix()); Require(result == -1 && *__error_nid_postfix() == 84, "post at maximum must fail with guest EOVERFLOW"); Require(sem_getvalue_nid_postfix(&sem, &value) == 0 && value == static_cast(maximum), "overflow changed count"); Require(sem_trywait_nid_postfix(&sem) == 0, "wait at maximum must succeed"); Require(sem_getvalue_nid_postfix(&sem, &value) == 0 && value == static_cast(maximum - 1), "wait must decrement"); Require(sem_post_nid_postfix(&sem) == 0, "post below maximum must succeed"); Require(sem_getvalue_nid_postfix(&sem, &value) == 0 && value == static_cast(maximum), "post must reach maximum"); Require(sem_post_nid_postfix(&sem) == -1 && *__error_nid_postfix() == 84, "repeated overflow must fail"); Require(sem_getvalue_nid_postfix(&sem, &value) == 0 && value == static_cast(maximum), "repeated overflow changed count"); Require(sem_destroy_nid_postfix(&sem) == 0, "destroy must succeed"); Require(sem_init_nid_postfix(&sem, 0, 0) == 0, "zero count must initialize"); Require(sem_trywait_nid_postfix(&sem) == -1 && *__error_nid_postfix() == 35, "empty semaphore must report EAGAIN"); Require(sem_post_nid_postfix(&sem) == 0, "normal post must succeed"); Require(sem_getvalue_nid_postfix(&sem, &value) == 0 && value == 1, "normal post must increment"); Require(sem_trywait_nid_postfix(&sem) == 0, "normal wait must succeed"); Require(sem_getvalue_nid_postfix(&sem, &value) == 0 && value == 0, "normal wait must decrement"); Require(sem_destroy_nid_postfix(&sem) == 0, "normal destroy must succeed"); }