summaryrefslogtreecommitdiffstats
path: root/src/posix
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2022-10-23 12:55:40 -0400
committerDavid Robillard <d@drobilla.net>2022-10-23 13:26:00 -0400
commite883ea50dd1154294e21e946e391dd38e04d6527 (patch)
tree2019aecf50e1eb2f73a2aaf567d0f4573d9efc31 /src/posix
parent07b1289cd4907aa3defe3fc600f3db1dcefcb719 (diff)
downloadzix-e883ea50dd1154294e21e946e391dd38e04d6527.tar.gz
zix-e883ea50dd1154294e21e946e391dd38e04d6527.tar.bz2
zix-e883ea50dd1154294e21e946e391dd38e04d6527.zip
Split up platform sources
This puts more onus on the build system to do things properly, but it's still easy enough to build, even manually: all the files in the appropriate system subdirectory just need to be included in the build. Otherwise, the several nested levels of preprocessor conditionals get confusing, and clang-format doesn't format code properly.
Diffstat (limited to 'src/posix')
-rw-r--r--src/posix/sem_posix.c89
-rw-r--r--src/posix/thread_posix.c34
2 files changed, 123 insertions, 0 deletions
diff --git a/src/posix/sem_posix.c b/src/posix/sem_posix.c
new file mode 100644
index 0000000..452830d
--- /dev/null
+++ b/src/posix/sem_posix.c
@@ -0,0 +1,89 @@
+// Copyright 2012-2022 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+#include "zix/sem.h"
+
+#include "../errno_status.h"
+#include "../zix_config.h"
+
+#include "zix/status.h"
+
+#include <semaphore.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <time.h>
+
+ZixStatus
+zix_sem_init(ZixSem* sem, unsigned initial)
+{
+ return zix_errno_status_if(sem_init(&sem->sem, 0, initial));
+}
+
+ZixStatus
+zix_sem_destroy(ZixSem* sem)
+{
+ return zix_errno_status_if(sem_destroy(&sem->sem));
+}
+
+ZixStatus
+zix_sem_post(ZixSem* sem)
+{
+ return zix_errno_status_if(sem_post(&sem->sem));
+}
+
+ZixStatus
+zix_sem_wait(ZixSem* sem)
+{
+ int r = 0;
+ while ((r = sem_wait(&sem->sem)) && errno == EINTR) {
+ // Interrupted, try again
+ }
+
+ return zix_errno_status_if(r);
+}
+
+ZixStatus
+zix_sem_try_wait(ZixSem* sem)
+{
+ int r = 0;
+ while ((r = sem_trywait(&sem->sem)) && errno == EINTR) {
+ // Interrupted, try again
+ }
+
+ return zix_errno_status_if(r);
+}
+
+ZixStatus
+zix_sem_timed_wait(ZixSem* sem,
+ const uint32_t seconds,
+ const uint32_t nanoseconds)
+{
+#if !USE_CLOCK_GETTIME || !USE_SEM_TIMEDWAIT
+
+ return ZIX_STATUS_NOT_SUPPORTED;
+
+#else
+# define NS_PER_SECOND 1000000000L
+
+ struct timespec ts = {0, 0};
+
+ int r = 0;
+ if (!(r = clock_gettime(CLOCK_REALTIME, &ts))) {
+ ts.tv_sec += (time_t)seconds;
+ ts.tv_nsec += (long)nanoseconds;
+ if (ts.tv_nsec >= NS_PER_SECOND) {
+ ts.tv_nsec -= NS_PER_SECOND;
+ ts.tv_sec++;
+ }
+
+ while ((r = sem_timedwait(&sem->sem, &ts)) && errno == EINTR) {
+ // Interrupted, try again
+ }
+ }
+
+ return zix_errno_status_if(r);
+
+# undef NS_PER_SECOND
+#endif
+}
diff --git a/src/posix/thread_posix.c b/src/posix/thread_posix.c
new file mode 100644
index 0000000..2073448
--- /dev/null
+++ b/src/posix/thread_posix.c
@@ -0,0 +1,34 @@
+// Copyright 2012-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+#include "zix/thread.h"
+
+#include "../errno_status.h"
+
+#include "zix/status.h"
+
+#include <pthread.h>
+
+#include <stddef.h>
+
+ZixStatus
+zix_thread_create(ZixThread* thread,
+ size_t stack_size,
+ ZixThreadFunc function,
+ void* arg)
+{
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, stack_size);
+
+ const int ret = pthread_create(thread, NULL, function, arg);
+
+ pthread_attr_destroy(&attr);
+ return zix_errno_status(ret);
+}
+
+ZixStatus
+zix_thread_join(ZixThread thread)
+{
+ return pthread_join(thread, NULL) ? ZIX_STATUS_ERROR : ZIX_STATUS_SUCCESS;
+}