From 1313875b02c690ca5a40e585d24fdec240bb419d Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 26 Jun 2023 15:04:13 -0400 Subject: thread: Wrap more pthread APIs --- src/ioq.c | 9 ++---- src/lock.h | 85 ------------------------------------------------ src/main.c | 2 +- src/thread.h | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/xregex.c | 5 ++- 5 files changed, 109 insertions(+), 95 deletions(-) delete mode 100644 src/lock.h create mode 100644 src/thread.h diff --git a/src/ioq.c b/src/ioq.c index 457ead7..1160b34 100644 --- a/src/ioq.c +++ b/src/ioq.c @@ -9,7 +9,7 @@ #include "config.h" #include "diag.h" #include "dir.h" -#include "lock.h" +#include "thread.h" #include "sanity.h" #include #include @@ -335,8 +335,7 @@ struct ioq *ioq_create(size_t depth, size_t nthreads) { } for (size_t i = 0; i < nthreads; ++i) { - errno = pthread_create(&ioq->threads[i], NULL, ioq_work, ioq); - if (errno != 0) { + if (thread_create(&ioq->threads[i], NULL, ioq_work, ioq) != 0) { goto fail; } ++ioq->nthreads; @@ -417,9 +416,7 @@ void ioq_destroy(struct ioq *ioq) { ioq_cancel(ioq); for (size_t i = 0; i < ioq->nthreads; ++i) { - if (pthread_join(ioq->threads[i], NULL) != 0) { - abort(); - } + thread_join(ioq->threads[i], NULL); } ioqq_destroy(ioq->ready); diff --git a/src/lock.h b/src/lock.h deleted file mode 100644 index 2b5f951..0000000 --- a/src/lock.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright © Tavian Barnes -// SPDX-License-Identifier: 0BSD - -/** - * Wrappers for POSIX synchronization primitives. - */ - -#ifndef BFS_LOCK_H -#define BFS_LOCK_H - -#include "diag.h" -#include -#include -#include - -#define lock_verify(expr, cond) \ - bfs_verify((errno = (expr), (cond)), "%s: %s", #expr, strerror(errno)) - -/** - * Wrapper for pthread_mutex_init(). - * - * @return - * 0 on success, -1 on error. - */ -#define mutex_init(mutex, attr) \ - ((errno = pthread_mutex_init(mutex, attr)) ? -1 : 0) - -/** - * Wrapper for pthread_mutex_lock(). - */ -#define mutex_lock(mutex) \ - lock_verify(pthread_mutex_lock(mutex), errno == 0) - -/** - * Wrapper for pthread_mutex_trylock(). - * - * @return - * Whether the mutex was locked. - */ -#define mutex_trylock(mutex) \ - (lock_verify(pthread_mutex_trylock(mutex), errno == 0 || errno == EBUSY), errno == 0) - -/** - * Wrapper for pthread_mutex_unlock(). - */ -#define mutex_unlock(mutex) \ - lock_verify(pthread_mutex_unlock(mutex), errno == 0) - -/** - * Wrapper for pthread_mutex_destroy(). - */ -#define mutex_destroy(mutex) \ - lock_verify(pthread_mutex_destroy(mutex), errno == 0) - -/** - * Wrapper for pthread_cond_init(). - */ -#define cond_init(cond, attr) \ - ((errno = pthread_cond_init(cond, attr)) ? -1 : 0) - -/** - * Wrapper for pthread_cond_wait(). - */ -#define cond_wait(cond, mutex) \ - lock_verify(pthread_cond_wait(cond, mutex), errno == 0) - -/** - * Wrapper for pthread_cond_signal(). - */ -#define cond_signal(cond) \ - lock_verify(pthread_cond_signal(cond), errno == 0) - -/** - * Wrapper for pthread_cond_broadcast(). - */ -#define cond_broadcast(cond) \ - lock_verify(pthread_cond_broadcast(cond), errno == 0) - -/** - * Wrapper for pthread_cond_destroy(). - */ -#define cond_destroy(cond) \ - lock_verify(pthread_cond_destroy(cond), errno == 0) - -#endif // BFS_LOCK_H diff --git a/src/main.c b/src/main.c index b7a08c1..b26be85 100644 --- a/src/main.c +++ b/src/main.c @@ -34,11 +34,11 @@ * - fsade.[ch] (a facade over non-standard filesystem features) * - ioq.[ch] (an async I/O queue) * - list.h (linked list macros) - * - lock.h (mutexes, condition variables, etc.) * - mtab.[ch] (parses the system's mount table) * - pwcache.[ch] (a cache for the user/group tables) * - sanity.h (sanitizer interfaces) * - stat.[ch] (wraps stat(), or statx() on Linux) + * - thread.h (multi-threading) * - trie.[ch] (a trie set/map implementation) * - typo.[ch] (fuzzy matching for typos) * - xregex.[ch] (regular expression support) diff --git a/src/thread.h b/src/thread.h new file mode 100644 index 0000000..b2edf17 --- /dev/null +++ b/src/thread.h @@ -0,0 +1,103 @@ +// Copyright © Tavian Barnes +// SPDX-License-Identifier: 0BSD + +/** + * Wrappers for POSIX threading APIs. + */ + +#ifndef BFS_THREAD_H +#define BFS_THREAD_H + +#include "diag.h" +#include +#include +#include + +#define thread_verify(expr, cond) \ + bfs_verify((errno = (expr), (cond)), "%s: %s", #expr, strerror(errno)) + +/** + * 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) + +/** + * Wrapper for pthread_join(). + */ +#define thread_join(thread, ret) \ + thread_verify(pthread_join(thread, ret), errno == 0) + +/** + * Wrapper for pthread_mutex_init(). + */ +#define mutex_init(mutex, attr) \ + ((errno = pthread_mutex_init(mutex, attr)) ? -1 : 0) + +/** + * Wrapper for pthread_mutex_lock(). + */ +#define mutex_lock(mutex) \ + thread_verify(pthread_mutex_lock(mutex), errno == 0) + +/** + * 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) + +/** + * Wrapper for pthread_mutex_unlock(). + */ +#define mutex_unlock(mutex) \ + thread_verify(pthread_mutex_unlock(mutex), errno == 0) + +/** + * Wrapper for pthread_mutex_destroy(). + */ +#define mutex_destroy(mutex) \ + thread_verify(pthread_mutex_destroy(mutex), errno == 0) + +/** + * Wrapper for pthread_cond_init(). + */ +#define cond_init(cond, attr) \ + ((errno = pthread_cond_init(cond, attr)) ? -1 : 0) + +/** + * Wrapper for pthread_cond_wait(). + */ +#define cond_wait(cond, mutex) \ + thread_verify(pthread_cond_wait(cond, mutex), errno == 0) + +/** + * Wrapper for pthread_cond_signal(). + */ +#define cond_signal(cond) \ + thread_verify(pthread_cond_signal(cond), errno == 0) + +/** + * Wrapper for pthread_cond_broadcast(). + */ +#define cond_broadcast(cond) \ + thread_verify(pthread_cond_broadcast(cond), errno == 0) + +/** + * Wrapper for pthread_cond_destroy(). + */ +#define cond_destroy(cond) \ + thread_verify(pthread_cond_destroy(cond), errno == 0) + +/** + * Wrapper for pthread_once(). + */ +#define call_once(once, fn) \ + thread_verify(pthread_once(once, fn), errno == 0) + +#endif // BFS_THREAD_H diff --git a/src/xregex.c b/src/xregex.c index 88df082..beb6676 100644 --- a/src/xregex.c +++ b/src/xregex.c @@ -5,6 +5,7 @@ #include "alloc.h" #include "config.h" #include "diag.h" +#include "thread.h" #include "sanity.h" #include #include @@ -106,9 +107,7 @@ static void bfs_onig_once(void) { /** Initialize Oniguruma. */ static int bfs_onig_initialize(OnigEncoding *enc) { static pthread_once_t once = PTHREAD_ONCE_INIT; - if (pthread_once(&once, bfs_onig_once) != 0) { - return ONIGERR_FAIL_TO_INITIALIZE; - } + call_once(&once, bfs_onig_once); *enc = bfs_onig_enc; return bfs_onig_status; -- cgit v1.2.3