Files
86Box/src/thread.cpp

138 lines
2.7 KiB
C++
Raw Normal View History

#include <mutex>
#include <thread>
#include <condition_variable>
#include <86box/plat.h>
2022-04-19 23:06:39 +02:00
#include <86box/thread.h>
2022-09-18 17:11:43 -04:00
struct event_cpp11_t {
std::condition_variable cond;
2022-09-18 17:11:43 -04:00
std::mutex mutex;
bool state = false;
};
extern "C" {
thread_t *
thread_create_named(void (*thread_rout)(void *param), void *param, const char *name)
{
auto thread = new std::thread([thread_rout, param, name] {
plat_set_thread_name(NULL, name);
2022-09-18 17:11:43 -04:00
thread_rout(param);
});
return thread;
}
int
thread_wait(thread_t *arg)
{
2022-09-18 17:11:43 -04:00
if (!arg)
return 0;
auto thread = reinterpret_cast<std::thread *>(arg);
thread->join();
return 0;
}
mutex_t *
thread_create_mutex(void)
{
auto mutex = new std::mutex;
return mutex;
}
int
thread_test_mutex(mutex_t *_mutex)
{
if (_mutex == nullptr)
2022-09-18 17:11:43 -04:00
return 0;
2022-09-18 17:11:43 -04:00
auto mutex = reinterpret_cast<std::mutex *>(_mutex);
return mutex->try_lock() ? 1 : 0;
}
int
thread_wait_mutex(mutex_t *_mutex)
{
if (_mutex == nullptr)
2022-09-18 17:11:43 -04:00
return 0;
2022-09-18 17:11:43 -04:00
auto mutex = reinterpret_cast<std::mutex *>(_mutex);
mutex->lock();
return 1;
}
int
thread_release_mutex(mutex_t *_mutex)
{
if (_mutex == nullptr)
2022-09-18 17:11:43 -04:00
return 0;
2022-09-18 17:11:43 -04:00
auto mutex = reinterpret_cast<std::mutex *>(_mutex);
mutex->unlock();
return 1;
}
void
thread_close_mutex(mutex_t *_mutex)
{
2022-09-18 17:11:43 -04:00
auto mutex = reinterpret_cast<std::mutex *>(_mutex);
delete mutex;
}
event_t *
thread_create_event()
{
2021-12-17 19:15:40 +01:00
auto ev = new event_cpp11_t;
return ev;
}
int
thread_wait_event(event_t *handle, int timeout)
{
2022-09-18 17:11:43 -04:00
auto event = reinterpret_cast<event_cpp11_t *>(handle);
auto lock = std::unique_lock<std::mutex>(event->mutex);
if (timeout < 0) {
2021-12-17 19:15:40 +01:00
event->cond.wait(lock, [event] { return event->state; });
} else {
2022-09-18 17:11:43 -04:00
auto to = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout);
std::cv_status status;
do {
status = event->cond.wait_until(lock, to);
2021-12-17 19:15:40 +01:00
} while ((status != std::cv_status::timeout) && !event->state);
if (status == std::cv_status::timeout) {
return 1;
}
}
return 0;
}
void
thread_set_event(event_t *handle)
{
2022-09-18 17:11:43 -04:00
auto event = reinterpret_cast<event_cpp11_t *>(handle);
2021-12-17 19:15:40 +01:00
{
2022-09-18 17:11:43 -04:00
auto lock = std::unique_lock<std::mutex>(event->mutex);
2021-12-17 19:15:40 +01:00
event->state = true;
}
event->cond.notify_all();
}
void
thread_reset_event(event_t *handle)
{
2022-09-18 17:11:43 -04:00
auto event = reinterpret_cast<event_cpp11_t *>(handle);
auto lock = std::unique_lock<std::mutex>(event->mutex);
event->state = false;
}
void
thread_destroy_event(event_t *handle)
{
2022-09-18 17:11:43 -04:00
auto event = reinterpret_cast<event_cpp11_t *>(handle);
delete event;
}
}