AnyPS5/core/libs/tests/PthreadStart.cpp

41 lines
2.0 KiB
C++

#include "prx/libkernel/Pthread/Pthread.hpp"
#include <future>
#include <iostream>
#include <stdexcept>
extern "C" int APS5_VABI scePthreadCreate(Pthread* thread, const PthreadAttr* attr, PthreadEntry entry, void* arg, const char* name);
extern "C" int APS5_VABI scePthreadJoin(Pthread thread, void** retval);
extern "C" int APS5_VABI scePthreadAttrInit(PthreadAttr* attr);
extern "C" int APS5_VABI scePthreadAttrDestroy(PthreadAttr* attr);
extern "C" int APS5_VABI scePthreadAttrGet(Pthread thread, PthreadAttr* attr);
struct ThreadContext {
Pthread thread = nullptr;
std::promise<void> checked;
};
static void* APS5_VABI CheckThread(void* arg) {
auto& context = *static_cast<ThreadContext*>(arg);
if (!context.thread) throw std::runtime_error("Thread handle was not published");
if (context.thread->_thr.get_id() != std::this_thread::get_id()) throw std::runtime_error("Thread object was not initialized");
if (!context.thread->_thr.joinable()) throw std::runtime_error("Thread object is not joinable");
PthreadAttr attr = nullptr;
if (scePthreadAttrInit(&attr) != 0) throw std::runtime_error("Attribute initialization failed");
if (scePthreadAttrGet(context.thread, &attr) != 0) throw std::runtime_error("Attribute query failed");
if (scePthreadAttrDestroy(&attr) != 0) throw std::runtime_error("Attribute destruction failed");
context.checked.set_value();
return arg;
}
int main() {
for (int iteration = 0; iteration < 10000; ++iteration) {
ThreadContext context;
if (scePthreadCreate(&context.thread, nullptr, CheckThread, &context, nullptr) != 0) throw std::runtime_error("Thread creation failed");
context.checked.get_future().get();
void* result = nullptr;
if (scePthreadJoin(context.thread, &result) != 0) throw std::runtime_error("Thread join failed");
if (result != &context) throw std::runtime_error("Thread return value was lost");
}
std::cout << "PASS: 10000 thread starts, initialized handles, attribute queries and joins\n";
}