Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions core/libs/prx/libkernel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,16 @@ if(BUILD_TESTING)
set_tests_properties(guest_cond_timedwait PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libkernel>")
endif()
add_test_executable(guest_condattr_setclock_tests ${LIBS_INCLUDE_DIR}/tests/GuestCondattrSetclock.cpp)
target_include_directories(guest_condattr_setclock_tests PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(guest_condattr_setclock_tests PRIVATE libkernel libc)
configure_windows_unwind(guest_condattr_setclock_tests)
add_test(NAME guest_condattr_setclock COMMAND guest_condattr_setclock_tests)
set_tests_properties(guest_condattr_setclock PROPERTIES TIMEOUT 20)
if(WIN32)
set_tests_properties(guest_condattr_setclock PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libkernel>")
endif()
add_test_executable(guest_cpu_time_clocks_tests ${LIBS_INCLUDE_DIR}/tests/GuestCpuTimeClocks.cpp)
target_include_directories(guest_cpu_time_clocks_tests PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(guest_cpu_time_clocks_tests PRIVATE libkernel libc)
Expand Down
1 change: 1 addition & 0 deletions core/libs/prx/libkernel/Pthread/Posix/Cond.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ int APS5_VABI pthread_condattr_init_nid_postfix(PthreadCondattr* attr) {

int APS5_VABI pthread_condattr_setclock_nid_postfix(PthreadCondattr* attr, KernelClockid clock_id) {
if (!attr || !*attr) return PosixThread::GUEST_EINVAL;
if (clock_id != 0 && clock_id != 1 && clock_id != 2 && clock_id != 4) return PosixThread::GUEST_EINVAL;
return toPosix(scePthreadCondattrSetclock(attr, clock_id));
}

Expand Down
75 changes: 75 additions & 0 deletions core/libs/tests/GuestCondattrSetclock.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include "SceTypes.hpp"
#include <climits>
#include <cstdio>
#include <initializer_list>
#include <cstdlib>

extern "C" {
int APS5_VABI pthread_condattr_init_nid_postfix(PthreadCondattr* attr);
int APS5_VABI pthread_condattr_destroy_nid_postfix(PthreadCondattr* attr);
int APS5_VABI pthread_condattr_setclock_nid_postfix(PthreadCondattr* attr, KernelClockid clockId);
int APS5_VABI pthread_cond_init_nid_postfix(PthreadCond* cond, const PthreadCondattr* attr);
int APS5_VABI pthread_cond_destroy_nid_postfix(PthreadCond* cond);
int APS5_VABI pthread_cond_timedwait_nid_postfix(PthreadCond* cond, PthreadMutex* mutex, const KernelTimespec* abstime);
int APS5_VABI pthread_mutex_init_nid_postfix(PthreadMutex* mutex, const PthreadMutexattr* attr);
int APS5_VABI pthread_mutex_destroy_nid_postfix(PthreadMutex* mutex);
int APS5_VABI pthread_mutex_lock_nid_postfix(PthreadMutex* mutex);
int APS5_VABI pthread_mutex_unlock_nid_postfix(PthreadMutex* mutex);
int APS5_VABI clock_gettime_nid_postfix(KernelClockid clockId, KernelTimespec* tp);
int* APS5_VABI __error_nid_postfix();
}

static constexpr int GUEST_EINVAL = 22;
static constexpr int GUEST_ETIMEDOUT = 60;
static constexpr int GUEST_EINTR = 4;

static void RequireResult(const char* operation, int actual, int expected) {
if (actual != expected) {
std::fprintf(stderr, "%s: expected %d, got %d\n", operation, expected, actual);
std::abort();
}
}

static void RequireGuestErrno(const char* operation, int expected) {
const int actual = *__error_nid_postfix();
if (actual != expected) {
std::fprintf(stderr, "%s changed guest errno: expected %d, got %d\n", operation, expected, actual);
std::abort();
}
}

int main() {
PthreadCondattr attr = nullptr;
RequireResult("pthread_condattr_setclock null pointer", pthread_condattr_setclock_nid_postfix(nullptr, 4), GUEST_EINVAL);
RequireResult("pthread_condattr_setclock null attribute", pthread_condattr_setclock_nid_postfix(&attr, 4), GUEST_EINVAL);
RequireResult("pthread_condattr_init", pthread_condattr_init_nid_postfix(&attr), 0);

for (const KernelClockid clockId : {0, 1, 2, 4}) {
*__error_nid_postfix() = GUEST_EINTR;
RequireResult("pthread_condattr_setclock valid clock", pthread_condattr_setclock_nid_postfix(&attr, clockId), 0);
RequireGuestErrno("pthread_condattr_setclock valid clock", GUEST_EINTR);
}

const KernelClockid invalidClockIds[] = {3, 5, -1, INT_MAX};
for (const KernelClockid clockId : invalidClockIds) {
*__error_nid_postfix() = GUEST_EINTR;
RequireResult("pthread_condattr_setclock invalid clock", pthread_condattr_setclock_nid_postfix(&attr, clockId), GUEST_EINVAL);
RequireGuestErrno("pthread_condattr_setclock invalid clock", GUEST_EINTR);
}

PthreadCond cond = nullptr;
PthreadMutex mutex = nullptr;
RequireResult("pthread_cond_init", pthread_cond_init_nid_postfix(&cond, &attr), 0);
RequireResult("pthread_mutex_init", pthread_mutex_init_nid_postfix(&mutex, nullptr), 0);
RequireResult("pthread_mutex_lock", pthread_mutex_lock_nid_postfix(&mutex), 0);

KernelTimespec deadline{};
RequireResult("clock_gettime monotonic", clock_gettime_nid_postfix(4, &deadline), 0);
RequireResult("pthread_cond_timedwait expired monotonic deadline", pthread_cond_timedwait_nid_postfix(&cond, &mutex, &deadline), GUEST_ETIMEDOUT);

RequireResult("pthread_mutex_unlock", pthread_mutex_unlock_nid_postfix(&mutex), 0);
RequireResult("pthread_cond_destroy", pthread_cond_destroy_nid_postfix(&cond), 0);
RequireResult("pthread_mutex_destroy", pthread_mutex_destroy_nid_postfix(&mutex), 0);
RequireResult("pthread_condattr_destroy", pthread_condattr_destroy_nid_postfix(&attr), 0);
RequireResult("pthread_condattr_setclock destroyed attribute", pthread_condattr_setclock_nid_postfix(&attr, 4), GUEST_EINVAL);
}
Loading