#include #include #include #include <86box/plat.h> #include <86box/thread.h> struct event_cpp11_t { std::condition_variable cond; 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); thread_rout(param); }); return thread; } int thread_wait(thread_t *arg) { if (!arg) return 0; auto thread = reinterpret_cast(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) return 0; auto mutex = reinterpret_cast(_mutex); return mutex->try_lock() ? 1 : 0; } int thread_wait_mutex(mutex_t *_mutex) { if (_mutex == nullptr) return 0; auto mutex = reinterpret_cast(_mutex); mutex->lock(); return 1; } int thread_release_mutex(mutex_t *_mutex) { if (_mutex == nullptr) return 0; auto mutex = reinterpret_cast(_mutex); mutex->unlock(); return 1; } void thread_close_mutex(mutex_t *_mutex) { auto mutex = reinterpret_cast(_mutex); delete mutex; } event_t * thread_create_event() { auto ev = new event_cpp11_t; return ev; } int thread_wait_event(event_t *handle, int timeout) { auto event = reinterpret_cast(handle); auto lock = std::unique_lock(event->mutex); if (timeout < 0) { event->cond.wait(lock, [event] { return event->state; }); } else { auto to = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout); std::cv_status status; do { status = event->cond.wait_until(lock, to); } 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) { auto event = reinterpret_cast(handle); { auto lock = std::unique_lock(event->mutex); event->state = true; } event->cond.notify_all(); } void thread_reset_event(event_t *handle) { auto event = reinterpret_cast(handle); auto lock = std::unique_lock(event->mutex); event->state = false; } void thread_destroy_event(event_t *handle) { auto event = reinterpret_cast(handle); delete event; } }