mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-05 13:20:11 +00:00
test(libkernel): query a detached thread after its handle was released
This commit is contained in:
1 parent
2118c99134
commit
2b4cb67755
2 files changed
+81
No files matched your search
@@ -738,6 +738,16 @@ if(BUILD_TESTING)
|
||||
set_tests_properties(guest_pthread_join_detach PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libkernel>")
|
||||
endif()
|
||||
add_test_executable(guest_pthread_handle_after_exit_tests ${LIBS_INCLUDE_DIR}/tests/GuestPthreadHandleAfterExit.cpp)
|
||||
target_include_directories(guest_pthread_handle_after_exit_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_pthread_handle_after_exit_tests PRIVATE libkernel libc)
|
||||
configure_windows_unwind(guest_pthread_handle_after_exit_tests)
|
||||
add_test(NAME guest_pthread_handle_after_exit COMMAND guest_pthread_handle_after_exit_tests)
|
||||
set_tests_properties(guest_pthread_handle_after_exit PROPERTIES TIMEOUT 20)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_pthread_handle_after_exit PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libkernel>")
|
||||
endif()
|
||||
add_test_executable(guest_pthread_attr_errors_tests ${LIBS_INCLUDE_DIR}/tests/GuestPthreadAttrErrors.cpp)
|
||||
target_include_directories(guest_pthread_attr_errors_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_pthread_attr_errors_tests PRIVATE libkernel libc)
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#include "prx/libkernel/include/Api.hpp"
|
||||
#include "prx/libkernel/Pthread/include/Pthread.hpp"
|
||||
#include "prx/libkernel/KernelErrors.hpp"
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include <thread>
|
||||
|
||||
static constexpr int SCE_OK = 0;
|
||||
|
||||
static void Require(bool condition) { if (!condition) std::abort(); }
|
||||
|
||||
struct Worker {
|
||||
std::atomic<bool> started{false};
|
||||
std::atomic<bool> release{false};
|
||||
};
|
||||
|
||||
static void* APS5_VABI Wait(void* opaque) {
|
||||
auto* worker = static_cast<Worker*>(opaque);
|
||||
worker->started.store(true);
|
||||
while (!worker->release.load()) std::this_thread::yield();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void RequireAlive(Pthread thread) {
|
||||
char name[32];
|
||||
int priority = 0;
|
||||
KernelCpumask mask = 0;
|
||||
Require(scePthreadGetname(thread, name) == SCE_OK);
|
||||
Require(scePthreadGetprio(thread, &priority) == SCE_OK);
|
||||
Require(scePthreadGetaffinity(thread, &mask) == SCE_OK && mask != 0);
|
||||
Require(scePthreadSetaffinity(thread, mask) == SCE_OK);
|
||||
Require(scePthreadRename(thread, "renamed") == SCE_OK);
|
||||
}
|
||||
|
||||
static void RequireEnded(Pthread thread) {
|
||||
char name[32];
|
||||
int priority = 0;
|
||||
KernelCpumask mask = 0;
|
||||
Require(scePthreadGetname(thread, name) == SCE_KERNEL_ERROR_ESRCH);
|
||||
Require(scePthreadGetprio(thread, &priority) == SCE_KERNEL_ERROR_ESRCH);
|
||||
Require(scePthreadGetaffinity(thread, &mask) == SCE_KERNEL_ERROR_ESRCH);
|
||||
Require(scePthreadSetaffinity(thread, 1) == SCE_KERNEL_ERROR_ESRCH);
|
||||
Require(scePthreadRename(thread, "renamed") == SCE_KERNEL_ERROR_ESRCH);
|
||||
}
|
||||
|
||||
static void WaitUntilReleased(Pthread thread) {
|
||||
const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(5);
|
||||
int priority = 0;
|
||||
while (scePthreadGetprio(thread, &priority) != SCE_KERNEL_ERROR_ESRCH) {
|
||||
Require(std::chrono::steady_clock::now() < deadline);
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
RequireAlive(scePthreadSelf());
|
||||
|
||||
for (int round = 0; round < 20; ++round) {
|
||||
Worker detached;
|
||||
Pthread detachedThread = nullptr;
|
||||
Require(scePthreadCreate(&detachedThread, nullptr, Wait, &detached, "detached") == SCE_OK);
|
||||
while (!detached.started.load()) std::this_thread::yield();
|
||||
RequireAlive(detachedThread);
|
||||
Require(scePthreadDetach(detachedThread) == SCE_OK);
|
||||
detached.release.store(true);
|
||||
WaitUntilReleased(detachedThread);
|
||||
RequireEnded(detachedThread);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user