mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-29 11:06:18 +00:00
os: Add wrappers for threading primitives
This commit is contained in:
parent
e82f3616c9
commit
0d09d225dd
|
@ -14,6 +14,7 @@ set(OS_SOURCE_FILES
|
|||
os/os_documentation.h
|
||||
os/os_hid.h
|
||||
os/os_hid_hidraw.c
|
||||
os/os_threading.h
|
||||
)
|
||||
|
||||
set(TRACKING_SOURCE_FILES
|
||||
|
|
309
src/xrt/auxiliary/os/os_threading.h
Normal file
309
src/xrt/auxiliary/os/os_threading.h
Normal file
|
@ -0,0 +1,309 @@
|
|||
// Copyright 2019, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Wrapper around OS threading native functions.
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
*
|
||||
* @ingroup aux_os
|
||||
*/
|
||||
|
||||
#include "xrt/xrt_compiler.h"
|
||||
|
||||
#ifdef XRT_OS_LINUX
|
||||
#include <pthread.h>
|
||||
#else
|
||||
#error "OS not supported"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
* @ingroup aux_os
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Mutex
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* A wrapper around a native mutex.
|
||||
*/
|
||||
struct os_mutex
|
||||
{
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Init.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static int
|
||||
os_mutex_init(struct os_mutex *om)
|
||||
{
|
||||
return pthread_mutex_init(&om->mutex, NULL);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Lock.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static void
|
||||
os_mutex_lock(struct os_mutex *om)
|
||||
{
|
||||
pthread_mutex_lock(&om->mutex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Unlock.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static void
|
||||
os_mutex_unlock(struct os_mutex *om)
|
||||
{
|
||||
pthread_mutex_unlock(&om->mutex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Clean up.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static void
|
||||
os_mutex_destroy(struct os_mutex *om)
|
||||
{
|
||||
pthread_mutex_destroy(&om->mutex);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Thread.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
* A wrapper around a native mutex.
|
||||
*/
|
||||
struct os_thread
|
||||
{
|
||||
pthread_t thread;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Run function.
|
||||
*/
|
||||
typedef void *(*os_run_func)(void *);
|
||||
|
||||
/*!
|
||||
* Init.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static int
|
||||
os_thread_init(struct os_thread *ost)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Start thread.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static int
|
||||
os_thread_start(struct os_thread *ost, os_run_func func, void *ptr)
|
||||
{
|
||||
return pthread_create(&ost->thread, NULL, func, ptr);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Joon.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static void
|
||||
os_thread_join(struct os_thread *ost)
|
||||
{
|
||||
void *retval;
|
||||
|
||||
pthread_join(ost->thread, &retval);
|
||||
memset(&ost->thread, 0, sizeof(ost->thread));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destruction.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static void
|
||||
os_thread_destroy(struct os_thread *ost)
|
||||
{}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Fancy helper.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* All in one helper that handles locking, waiting for change and starting a
|
||||
* thread.
|
||||
*/
|
||||
struct os_thread_helper
|
||||
{
|
||||
pthread_t thread;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
|
||||
bool running;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Initialize the thread helper.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static int
|
||||
os_thread_helper_init(struct os_thread_helper *oth)
|
||||
{
|
||||
int ret = pthread_mutex_init(&oth->mutex, NULL);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = pthread_cond_init(&oth->cond, NULL);
|
||||
if (ret) {
|
||||
pthread_mutex_destroy(&oth->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Start the internal thread.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static int
|
||||
os_thread_helper_start(struct os_thread_helper *oth,
|
||||
os_run_func func,
|
||||
void *ptr)
|
||||
{
|
||||
pthread_mutex_lock(&oth->mutex);
|
||||
|
||||
if (oth->running) {
|
||||
pthread_mutex_unlock(&oth->mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = pthread_create(&oth->thread, NULL, func, ptr);
|
||||
if (ret != 0) {
|
||||
pthread_mutex_unlock(&oth->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
oth->running = true;
|
||||
|
||||
pthread_mutex_unlock(&oth->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Stop the thread.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static int
|
||||
os_thread_helper_stop(struct os_thread_helper *oth)
|
||||
{
|
||||
void *retval = NULL;
|
||||
|
||||
// The fields are protected.
|
||||
pthread_mutex_lock(&oth->mutex);
|
||||
|
||||
if (!oth->running) {
|
||||
pthread_mutex_unlock(&oth->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Stop the thread.
|
||||
oth->running = false;
|
||||
|
||||
// Wake up the thread if it is waiting.
|
||||
pthread_cond_signal(&oth->cond);
|
||||
|
||||
// No longer need to protect fields.
|
||||
pthread_mutex_unlock(&oth->mutex);
|
||||
|
||||
// Wait for thread to finish.
|
||||
pthread_join(oth->thread, &retval);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destroy the thread helper, externally syncronizable.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static void
|
||||
os_thread_helper_destroy(struct os_thread_helper *oth)
|
||||
{
|
||||
// Stop the thread.
|
||||
os_thread_helper_stop(oth);
|
||||
|
||||
// Destroy resources.
|
||||
pthread_mutex_destroy(&oth->mutex);
|
||||
pthread_cond_destroy(&oth->cond);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Lock the helper.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static void
|
||||
os_thread_helper_lock(struct os_thread_helper *oth)
|
||||
{
|
||||
pthread_mutex_lock(&oth->mutex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Unlock the helper.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static void
|
||||
os_thread_helper_unlock(struct os_thread_helper *oth)
|
||||
{
|
||||
pthread_mutex_unlock(&oth->mutex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Is the thread running, or suppised to be running.
|
||||
*
|
||||
* Must be called with the helper locked.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static bool
|
||||
os_thread_helper_is_running_locked(struct os_thread_helper *oth)
|
||||
{
|
||||
return oth->running;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Wait for a signal.
|
||||
*
|
||||
* Must be called with the helper locked.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static void
|
||||
os_thread_helper_wait_locked(struct os_thread_helper *oth)
|
||||
{
|
||||
pthread_cond_wait(&oth->cond, &oth->mutex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Signal a waiting thread to wake up.
|
||||
*
|
||||
* Must be called with the helper locked.
|
||||
*/
|
||||
XRT_MAYBE_UNUSED static void
|
||||
os_thread_helper_signal_locked(struct os_thread_helper *oth)
|
||||
{
|
||||
pthread_cond_signal(&oth->cond);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
Loading…
Reference in a new issue