]> Sergey Matveev's repositories - bfs.git/commitdiff
thread: Move thread wrapper functions out of line
authorTavian Barnes <tavianator@tavianator.com>
Fri, 27 Oct 2023 16:45:10 +0000 (12:45 -0400)
committerTavian Barnes <tavianator@tavianator.com>
Fri, 27 Oct 2023 16:45:10 +0000 (12:45 -0400)
GNUmakefile
src/thread.c [new file with mode: 0644]
src/thread.h

index 62f24fbc92175e43550d764a6030f9fd54753b16..2494b163da35bb90be3537c67f79c940e3a3c46c 100644 (file)
@@ -250,6 +250,7 @@ LIBBFS := \
     $(OBJ)/src/printf.o \
     $(OBJ)/src/pwcache.o \
     $(OBJ)/src/stat.o \
+    $(OBJ)/src/thread.o \
     $(OBJ)/src/trie.o \
     $(OBJ)/src/typo.o \
     $(OBJ)/src/xregex.o \
diff --git a/src/thread.c b/src/thread.c
new file mode 100644 (file)
index 0000000..200d8c3
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright © Tavian Barnes <tavianator@tavianator.com>
+// SPDX-License-Identifier: 0BSD
+
+#include "thread.h"
+#include "bfstd.h"
+#include "config.h"
+#include "diag.h"
+#include <errno.h>
+#include <pthread.h>
+
+#define THREAD_FALLIBLE(expr) \
+       do { \
+               int err = expr; \
+               if (err == 0) { \
+                       return 0; \
+               } else { \
+                       errno = err; \
+                       return -1; \
+               } \
+       } while (0)
+
+#define THREAD_INFALLIBLE(...) \
+       THREAD_INFALLIBLE_(__VA_ARGS__, 0, )
+
+#define THREAD_INFALLIBLE_(expr, allowed, ...) \
+       int err = expr; \
+       bfs_verify(err == 0 || err == allowed, "%s: %s", #expr, xstrerror(err)); \
+       (void)0
+
+int thread_create(pthread_t *thread, const pthread_attr_t *attr, thread_fn *fn, void *arg) {
+       THREAD_FALLIBLE(pthread_create(thread, attr, fn, arg));
+}
+
+void thread_join(pthread_t thread, void **ret) {
+       THREAD_INFALLIBLE(pthread_join(thread, ret));
+}
+
+int mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr) {
+       THREAD_FALLIBLE(pthread_mutex_init(mutex, attr));
+}
+
+void mutex_lock(pthread_mutex_t *mutex) {
+       THREAD_INFALLIBLE(pthread_mutex_lock(mutex));
+}
+
+bool mutex_trylock(pthread_mutex_t *mutex) {
+       THREAD_INFALLIBLE(pthread_mutex_trylock(mutex), EBUSY);
+       return err == 0;
+}
+
+void mutex_unlock(pthread_mutex_t *mutex) {
+       THREAD_INFALLIBLE(pthread_mutex_unlock(mutex));
+}
+
+void mutex_destroy(pthread_mutex_t *mutex) {
+       THREAD_INFALLIBLE(pthread_mutex_destroy(mutex));
+}
+
+int cond_init(pthread_cond_t *cond, pthread_condattr_t *attr) {
+       THREAD_FALLIBLE(pthread_cond_init(cond, attr));
+}
+
+void cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {
+       THREAD_INFALLIBLE(pthread_cond_wait(cond, mutex));
+}
+
+void cond_signal(pthread_cond_t *cond) {
+       THREAD_INFALLIBLE(pthread_cond_signal(cond));
+}
+
+void cond_broadcast(pthread_cond_t *cond) {
+       THREAD_INFALLIBLE(pthread_cond_broadcast(cond));
+}
+
+void cond_destroy(pthread_cond_t *cond) {
+       THREAD_INFALLIBLE(pthread_cond_destroy(cond));
+}
+
+void invoke_once(pthread_once_t *once, once_fn *fn) {
+       THREAD_INFALLIBLE(pthread_once(once, fn));
+}
index a59033c5609703e8b4960b2230632c315d661e0b..b37d45ff4b2d0f1e9f4e9d631dfa71bbc0f9abb3 100644 (file)
@@ -8,12 +8,8 @@
 #ifndef BFS_THREAD_H
 #define BFS_THREAD_H
 
-#include "bfstd.h"
 #include "config.h"
-#include "diag.h"
-#include <errno.h>
 #include <pthread.h>
-#include <string.h>
 
 #if __STDC_VERSION__ < 202311L && !defined(thread_local)
 #  if BFS_USE_THREADS_H
@@ -23,8 +19,8 @@
 #  endif
 #endif
 
-#define thread_verify(expr, cond) \
-       bfs_verify((errno = (expr), (cond)), "%s: %s", #expr, xstrerror(errno))
+/** Thread entry point type. */
+typedef void *thread_fn(void *arg);
 
 /**
  * Wrapper for pthread_create().
  * @return
  *         0 on success, -1 on error.
  */
-#define thread_create(thread, attr, fn, arg) \
-       ((errno = pthread_create(thread, attr, fn, arg)) ? -1 : 0)
+int thread_create(pthread_t *thread, const pthread_attr_t *attr, thread_fn *fn, void *arg);
 
 /**
  * Wrapper for pthread_join().
  */
-#define thread_join(thread, ret) \
-       thread_verify(pthread_join(thread, ret), errno == 0)
+void thread_join(pthread_t thread, void **ret);
 
 /**
  * Wrapper for pthread_mutex_init().
  */
-#define mutex_init(mutex, attr) \
-       ((errno = pthread_mutex_init(mutex, attr)) ? -1 : 0)
+int mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr);
 
 /**
  * Wrapper for pthread_mutex_lock().
  */
-#define mutex_lock(mutex) \
-       thread_verify(pthread_mutex_lock(mutex), errno == 0)
+void mutex_lock(pthread_mutex_t *mutex);
 
 /**
  * Wrapper for pthread_mutex_trylock().
  * @return
  *         Whether the mutex was locked.
  */
-#define mutex_trylock(mutex) \
-       (thread_verify(pthread_mutex_trylock(mutex), errno == 0 || errno == EBUSY), errno == 0)
+bool mutex_trylock(pthread_mutex_t *mutex);
 
 /**
  * Wrapper for pthread_mutex_unlock().
  */
-#define mutex_unlock(mutex) \
-       thread_verify(pthread_mutex_unlock(mutex), errno == 0)
+void mutex_unlock(pthread_mutex_t *mutex);
 
 /**
  * Wrapper for pthread_mutex_destroy().
  */
-#define mutex_destroy(mutex) \
-       thread_verify(pthread_mutex_destroy(mutex), errno == 0)
+void mutex_destroy(pthread_mutex_t *mutex);
 
 /**
  * Wrapper for pthread_cond_init().
  */
-#define cond_init(cond, attr) \
-       ((errno = pthread_cond_init(cond, attr)) ? -1 : 0)
+int cond_init(pthread_cond_t *cond, pthread_condattr_t *attr);
 
 /**
  * Wrapper for pthread_cond_wait().
  */
-#define cond_wait(cond, mutex) \
-       thread_verify(pthread_cond_wait(cond, mutex), errno == 0)
+void cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
 
 /**
  * Wrapper for pthread_cond_signal().
  */
-#define cond_signal(cond) \
-       thread_verify(pthread_cond_signal(cond), errno == 0)
+void cond_signal(pthread_cond_t *cond);
 
 /**
  * Wrapper for pthread_cond_broadcast().
  */
-#define cond_broadcast(cond) \
-       thread_verify(pthread_cond_broadcast(cond), errno == 0)
+void cond_broadcast(pthread_cond_t *cond);
 
 /**
  * Wrapper for pthread_cond_destroy().
  */
-#define cond_destroy(cond) \
-       thread_verify(pthread_cond_destroy(cond), errno == 0)
+void cond_destroy(pthread_cond_t *cond);
+
+/** pthread_once() callback type. */
+typedef void once_fn(void);
 
 /**
  * Wrapper for pthread_once().
  */
-#define invoke_once(once, fn) \
-       thread_verify(pthread_once(once, fn), errno == 0)
+void invoke_once(pthread_once_t *once, once_fn *fn);
 
 #endif // BFS_THREAD_H