summaryrefslogtreecommitdiff
path: root/src/util/thread
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2023-10-10 20:59:07 -0400
committerAndrew Opalach <andrew@akon.city> 2023-10-10 20:59:07 -0400
commita723efcc67b6c14ff0dd1efd1ba88596e959daaa (patch)
tree45384ce34e9601533fdc5bfbbdaf1b63ea7f1310 /src/util/thread
downloadlibnaunet-a723efcc67b6c14ff0dd1efd1ba88596e959daaa.tar.gz
libnaunet-a723efcc67b6c14ff0dd1efd1ba88596e959daaa.tar.bz2
libnaunet-a723efcc67b6c14ff0dd1efd1ba88596e959daaa.zip
Add libakiyo
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/util/thread')
-rw-r--r--src/util/thread/thread.h66
-rw-r--r--src/util/thread/thread_linux.c86
-rw-r--r--src/util/thread/thread_windows.c81
3 files changed, 233 insertions, 0 deletions
diff --git a/src/util/thread/thread.h b/src/util/thread/thread.h
new file mode 100644
index 0000000..eb63b8d
--- /dev/null
+++ b/src/util/thread/thread.h
@@ -0,0 +1,66 @@
+#pragma once
+
+#include <al/types.h>
+
+#ifndef _WIN32
+#include <pthread.h>
+#else
+#include "../../winwrap.h"
+#endif
+
+struct aki_thread {
+#ifndef _WIN32
+ pthread_t thread;
+#else
+ HANDLE thread;
+#endif
+};
+
+struct aki_mutex {
+#ifndef _WIN32
+ pthread_mutex_t mutex;
+#else
+ CRITICAL_SECTION mutex;
+#endif
+};
+
+struct aki_cond {
+#ifndef _WIN32
+ pthread_cond_t cond;
+#else
+ CONDITION_VARIABLE cond;
+#endif
+ bool condition;
+};
+
+typedef f64 aki_os_tstamp;
+
+#define AKI_TS_FROM_USEC(usec) (usec * 1e-6)
+
+#ifndef _WIN32
+#define AKI_THREADCALL
+typedef void * aki_thread_result;
+#else
+#define AKI_THREADCALL __stdcall
+typedef unsigned long aki_thread_result;
+#endif
+
+typedef aki_thread_result (AKI_THREADCALL * aki_thread_func)(void *);
+
+void aki_thread_sleep(aki_os_tstamp ts);
+
+void aki_thread_create(struct aki_thread *thread, aki_thread_func func, void *userdata);
+void aki_thread_join(struct aki_thread *thread);
+//void aki_thread_cancel(struct aki_thread *thread);
+//void aki_thread_detach(struct aki_thread *thread);
+
+void aki_mutex_init(struct aki_mutex *mutex);
+void aki_mutex_lock(struct aki_mutex *mutex);
+void aki_mutex_unlock(struct aki_mutex *mutex);
+void aki_mutex_destroy(struct aki_mutex *mutex);
+
+void aki_cond_init(struct aki_cond *cond);
+void aki_cond_wait(struct aki_cond *cond, struct aki_mutex *mutex);
+bool aki_cond_is_waiting(struct aki_cond *cond);
+void aki_cond_signal(struct aki_cond *cond);
+void aki_cond_destroy(struct aki_cond *cond);
diff --git a/src/util/thread/thread_linux.c b/src/util/thread/thread_linux.c
new file mode 100644
index 0000000..0214ed8
--- /dev/null
+++ b/src/util/thread/thread_linux.c
@@ -0,0 +1,86 @@
+#include <al/types.h>
+#include <time.h>
+
+#include "../error.h"
+
+#include "thread.h"
+
+void aki_thread_sleep(aki_os_tstamp ts)
+{
+ struct timespec tv;
+ tv.tv_sec = (s64)ts;
+ tv.tv_nsec = (s64)((ts - tv.tv_sec) * 1e9);
+ while (nanosleep(&tv, &tv) == -1 && errno == EINTR) {}
+}
+
+void aki_thread_create(struct aki_thread *thread, aki_thread_func func, void *userdata)
+{
+ pthread_create(&thread->thread, NULL, func, userdata);
+}
+
+void aki_thread_join(struct aki_thread *thread)
+{
+ pthread_join(thread->thread, NULL);
+}
+
+/*
+void aki_thread_cancel(struct aki_thread *thread)
+{
+ pthread_cancel(thread->thread);
+}
+
+void aki_thread_detach(struct aki_thread *thread)
+{
+ pthread_detach(thread->thread);
+}
+*/
+
+void aki_mutex_init(struct aki_mutex *mutex)
+{
+ pthread_mutex_init(&mutex->mutex, NULL);
+}
+
+void aki_mutex_lock(struct aki_mutex *mutex)
+{
+ pthread_mutex_lock(&mutex->mutex);
+}
+
+void aki_mutex_unlock(struct aki_mutex *mutex)
+{
+ pthread_mutex_unlock(&mutex->mutex);
+}
+
+void aki_mutex_destroy(struct aki_mutex *mutex)
+{
+ pthread_mutex_destroy(&mutex->mutex);
+}
+
+void aki_cond_init(struct aki_cond *cond)
+{
+ cond->condition = true;
+ pthread_cond_init(&cond->cond, NULL);
+}
+
+void aki_cond_wait(struct aki_cond *cond, struct aki_mutex *mutex)
+{
+ cond->condition = false;
+ while (!cond->condition) {
+ pthread_cond_wait(&cond->cond, &mutex->mutex);
+ }
+}
+
+bool aki_cond_is_waiting(struct aki_cond *cond)
+{
+ return !cond->condition;
+}
+
+void aki_cond_signal(struct aki_cond *cond)
+{
+ cond->condition = true;
+ pthread_cond_signal(&cond->cond);
+}
+
+void aki_cond_destroy(struct aki_cond *cond)
+{
+ pthread_cond_destroy(&cond->cond);
+}
diff --git a/src/util/thread/thread_windows.c b/src/util/thread/thread_windows.c
new file mode 100644
index 0000000..9ea9ead
--- /dev/null
+++ b/src/util/thread/thread_windows.c
@@ -0,0 +1,81 @@
+#include "thread.h"
+
+NTSTATUS(__stdcall *NtDelayExecution)(BOOL Alertable, PLARGE_INTEGER DelayInterval);
+
+void aki_thread_sleep(aki_os_tstamp ts)
+{
+ LARGE_INTEGER intr;
+ intr.QuadPart = -1 * (s64)(ts * 1e7);
+ NtDelayExecution(false, &intr);
+}
+
+void aki_thread_create(struct aki_thread *thread, aki_thread_func func, void *userdata)
+{
+ thread->thread = CreateThread(NULL, 0, func, userdata, 0, NULL);
+}
+
+void aki_thread_join(struct aki_thread *thread)
+{
+ WaitForSingleObject(thread->thread, INFINITE);
+ CloseHandle(thread->thread);
+}
+
+/*
+void aki_thread_cancel(struct aki_thread *thread)
+{
+}
+
+void aki_thread_detach(struct aki_thread *thread)
+{
+}
+*/
+
+void aki_mutex_init(struct aki_mutex *mutex)
+{
+ InitializeCriticalSection(&mutex->mutex);
+}
+
+void aki_mutex_lock(struct aki_mutex *mutex)
+{
+ EnterCriticalSection(&mutex->mutex);
+}
+
+void aki_mutex_unlock(struct aki_mutex *mutex)
+{
+ LeaveCriticalSection(&mutex->mutex);
+}
+
+void aki_mutex_destroy(struct aki_mutex *mutex)
+{
+ DeleteCriticalSection(&mutex->mutex);
+}
+
+void aki_cond_init(struct aki_cond *cond)
+{
+ cond->condition = true;
+ InitializeConditionVariable(&cond->cond);
+}
+
+void aki_cond_wait(struct aki_cond *cond, struct aki_mutex *mutex)
+{
+ cond->condition = false;
+ while (!cond->condition) {
+ SleepConditionVariableCS(&cond->cond, &mutex->mutex, INFINITE);
+ }
+}
+
+bool aki_cond_is_waiting(struct aki_cond *cond)
+{
+ return !cond->condition;
+}
+
+void aki_cond_signal(struct aki_cond *cond)
+{
+ cond->condition = true;
+ WakeConditionVariable(&cond->cond);
+}
+
+void aki_cond_destroy(struct aki_cond *cond)
+{
+ (void)cond;
+}