I don't recommend to commit this, but I wanted to resurrect the discussion, perhaps get some early feedback, and to find out if anyone else had been working on this :)
This experimental diff merges the two different (futex and non-futex) versions of struct pthread_mutex into one, and makes its members public, so that applications can know its size and control where it's stored. The futex version's 'lock' member is renamed to 'futex', and libc and rthread major versions are bumped. Bootstrap is kind of painful, since changing the size of pthread_mutex breaks ABI in a lot more than just libc and librthread, though. This is preparation for pshared mutexes, and applies on top of tedu@'s unmerged pshared semaphore diff from July 2020, which similarly made semaphores non-opaque. I made some regression test tweaks to that diff, but since the librthread part is unchanged from tedu's, I'm not sending it to the list at this time - you can find it with my modifications in git at https://git.sr.ht/~lotheac/openbsd/log/pthread in case you're interested in replicating my experiments. Because this removes dynamic allocations from pthread_mutex_init, it also allows making a few thing simpler, since pthread_mutex_init can no longer fail. I considered making pthread_mutex struct members hidden by only exposing correct-sized padding members, but that gets tricky due to alignment issues regarding _atomic_lock_t as kettenis@ pointed out in the previous thread back in July. Hiding and/or oversizing the user-visible struct for future expansion while keeping proper alignment might be possible, but not done in this diff - yet. I think hiding at least some of the members will have to be done, since including sys/queue.h in pthread.h (for the TAILQ in pthread_mutex) causes namespace pollution which fails eg. git build from ports. Suggestions welcome though. Since the non-futex version of pthread_mutex uses a tailq, static initialization is a bit tricky -- we can't use TAILQ_HEAD_INITIALIZER in PTHREAD_MUTEX_INITIALIZER, since the former requires the address of the tailq and the latter does not take arguments. So, I added a member called 'needinit' and kept part of the previous initialization logic: when a mutex is being locked, and it has only been statically initialized using PTHREAD_MUTEX_INITIALIZER, pthread_mutex_init will be called to perform the rest of the initialization. (side note: too bad C99 designated initializers can't be used here, since this header could be used with older -std=) I dropped 'volatile' from the pthread_mutex_t typedef with this, because libcxx was failing to convert from 'volatile pthread_mutex *' to 'void *', now that __libcpp_mutex_t is a struct and not just a pointer. I have to admit I don't really understand what the implications of dropping it are, though. After bootstrap, this survived a base build and make regress on amd64. I also lightly tested the non-futex version (rthread_sync.c) by running it through regress/lib/libpthread on amd64, and it seemed to work. I did not build ports or xenocara since this isn't quite finished yet. Thoughts? If this is the way to go, then pthread_cond, pthread_rwlock, and perhaps pthread_*attr should receive similar treatment - I just haven't gotten around to writing those diffs yet. They could (should?) be done as part of the same rthread&libc major bump as this. libc is still using NULL void*s as locks, expecting _MUTEX_LOCK to dynamically allocate them at first use. That still works with this diff, but for future work it might be better to convert those usages to actual pthread_mutex_t's. --- include/pthread.h | 19 +++++- lib/libc/include/thread_private.h | 17 ------ lib/libc/shlib_version | 2 +- lib/libc/thread/rthread_cond.c | 7 +-- lib/libc/thread/rthread_libc.c | 93 +++++++++++------------------ lib/libc/thread/rthread_mutex.c | 93 +++++++++-------------------- lib/libc/thread/rthread_sync.c | 55 +++++------------ lib/librthread/rthread_barrier.c | 3 +- lib/librthread/rthread_mutex_prio.c | 11 ++-- lib/librthread/shlib_version | 4 +- 10 files changed, 107 insertions(+), 197 deletions(-) diff --git a/include/pthread.h b/include/pthread.h index cfb1356a1d4..9b40c6a07af 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -40,9 +40,11 @@ /* * Header files. */ +#include <sys/queue.h> #include <sys/types.h> #include <sys/time.h> #include <sys/signal.h> +#include <machine/spinlock.h> #include <limits.h> #include <sched.h> @@ -111,7 +113,7 @@ struct pthread_rwlockattr; */ typedef struct pthread *pthread_t; typedef struct pthread_attr *pthread_attr_t; -typedef volatile struct pthread_mutex *pthread_mutex_t; +typedef struct pthread_mutex pthread_mutex_t; typedef struct pthread_mutex_attr *pthread_mutexattr_t; typedef struct pthread_cond *pthread_cond_t; typedef struct pthread_cond_attr *pthread_condattr_t; @@ -133,8 +135,19 @@ typedef void *pthread_addr_t; typedef void *(*pthread_startroutine_t)(void *); /* - * Once definitions. + * Non-opaque definitions. */ +struct pthread_mutex { + int needinit; + _atomic_lock_t lock; + TAILQ_HEAD(, pthread) lockers; + volatile unsigned int futex; + int type; + pthread_t owner; + int count; + int prioceiling; +}; + struct pthread_once { int state; pthread_mutex_t mutex; @@ -154,7 +167,7 @@ struct pthread_once { /* * Static initialization values. */ -#define PTHREAD_MUTEX_INITIALIZER NULL +#define PTHREAD_MUTEX_INITIALIZER { 1 } #define PTHREAD_COND_INITIALIZER NULL #define PTHREAD_RWLOCK_INITIALIZER NULL diff --git a/lib/libc/include/thread_private.h b/lib/libc/include/thread_private.h index 0c793b9a7f7..2d69ad9643b 100644 --- a/lib/libc/include/thread_private.h +++ b/lib/libc/include/thread_private.h @@ -284,14 +284,6 @@ TAILQ_HEAD(pthread_queue, pthread); #ifdef FUTEX -struct pthread_mutex { - volatile unsigned int lock; - int type; - pthread_t owner; - int count; - int prioceiling; -}; - struct pthread_cond { volatile unsigned int seq; clockid_t clock; @@ -304,15 +296,6 @@ struct pthread_rwlock { #else -struct pthread_mutex { - _atomic_lock_t lock; - struct pthread_queue lockers; - int type; - pthread_t owner; - int count; - int prioceiling; -}; - struct pthread_cond { _atomic_lock_t lock; struct pthread_queue waiters; diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version index 06f98b01084..ce5e454e2d5 100644 --- a/lib/libc/shlib_version +++ b/lib/libc/shlib_version @@ -1,4 +1,4 @@ -major=96 +major=97 minor=0 # note: If changes were made to include/thread_private.h or if system calls # were added/changed then librthread/shlib_version must also be updated. diff --git a/lib/libc/thread/rthread_cond.c b/lib/libc/thread/rthread_cond.c index 51e9f4f9967..f67da0623c7 100644 --- a/lib/libc/thread/rthread_cond.c +++ b/lib/libc/thread/rthread_cond.c @@ -68,10 +68,9 @@ pthread_cond_destroy(pthread_cond_t *condp) } int -_rthread_cond_timedwait(pthread_cond_t cond, pthread_mutex_t *mutexp, +_rthread_cond_timedwait(pthread_cond_t cond, pthread_mutex_t *mutex, const struct timespec *abs) { - struct pthread_mutex *mutex = (struct pthread_mutex *)*mutexp; struct tib *tib = TIB_GET(); pthread_t self = tib->tib_thread; int error, rv = 0, canceled = 0, mutex_count = 0; @@ -99,7 +98,7 @@ _rthread_cond_timedwait(pthread_cond_t cond, pthread_mutex_t *mutexp, if (mutex->type == PTHREAD_MUTEX_RECURSIVE) mutex_count = mutex->count; - pthread_mutex_unlock(mutexp); + pthread_mutex_unlock(mutex); do { /* If ``seq'' wraps you deserve to lose a signal. */ @@ -118,7 +117,7 @@ _rthread_cond_timedwait(pthread_cond_t cond, pthread_mutex_t *mutexp, else if (error == EINTR) canceled = 1; - pthread_mutex_lock(mutexp); + pthread_mutex_lock(mutex); /* restore the mutex's count */ if (mutex->type == PTHREAD_MUTEX_RECURSIVE) diff --git a/lib/libc/thread/rthread_libc.c b/lib/libc/thread/rthread_libc.c index 2a117c14f6e..83cb6b0909d 100644 --- a/lib/libc/thread/rthread_libc.c +++ b/lib/libc/thread/rthread_libc.c @@ -22,6 +22,7 @@ struct _thread_tag { * local mutex to protect against tag creation races. */ static pthread_mutex_t _thread_tag_mutex = PTHREAD_MUTEX_INITIALIZER; +static _atomic_lock_t mutex_alloc_lock = _SPINLOCK_UNLOCKED; /* * Initialize a thread tag structure once. This function is called @@ -122,52 +123,70 @@ _thread_tag_storage(void **tag, void *storage, size_t sz, void (*dt)(void *), return ret; } +static int +thread_mutex_init(pthread_mutex_t **mutex) +{ + _spinlock(&mutex_alloc_lock); + if (*mutex == NULL) { + *mutex = calloc(1, sizeof(*mutex)); + if (*mutex == NULL) { + _spinunlock(&mutex_alloc_lock); + return 1; + } + pthread_mutex_init(*mutex, NULL); + } + _spinunlock(&mutex_alloc_lock); + return 0; +} + void _thread_mutex_lock(void **mutex) { - pthread_mutex_t *pmutex = (pthread_mutex_t *)mutex; + pthread_mutex_t **pmutex = (pthread_mutex_t **)mutex; + + if (*pmutex == NULL) { + if (thread_mutex_init(pmutex) != 0) { + _rthread_debug(1, "mutex init failure"); + return; + } + } - if (pthread_mutex_lock(pmutex) != 0) + if (pthread_mutex_lock(*pmutex) != 0) _rthread_debug(1, "mutex lock failure"); } void _thread_mutex_unlock(void **mutex) { - pthread_mutex_t *pmutex = (pthread_mutex_t *)mutex; + pthread_mutex_t **pmutex = (pthread_mutex_t **)mutex; - if (pthread_mutex_unlock(pmutex) != 0) + if (pthread_mutex_unlock(*pmutex) != 0) _rthread_debug(1, "mutex unlock failure"); } void _thread_mutex_destroy(void **mutex) { - pthread_mutex_t *pmutex = (pthread_mutex_t *)mutex; + pthread_mutex_t **pmutex = (pthread_mutex_t **)mutex; - if (pthread_mutex_destroy(pmutex) != 0) + if (pthread_mutex_destroy(*pmutex) != 0) _rthread_debug(1, "mutex destroy failure"); + free(*pmutex); + pmutex = NULL; } /* * the malloc lock */ -#ifndef FUTEX #define MALLOC_LOCK_INITIALIZER(n) { \ + 0, \ _SPINLOCK_UNLOCKED, \ TAILQ_HEAD_INITIALIZER(malloc_lock[n].lockers), \ - PTHREAD_MUTEX_DEFAULT, \ - NULL, \ 0, \ - -1 } -#else -#define MALLOC_LOCK_INITIALIZER(n) { \ - _SPINLOCK_UNLOCKED, \ PTHREAD_MUTEX_DEFAULT, \ NULL, \ 0, \ -1 } -#endif static struct pthread_mutex malloc_lock[_MALLOC_MUTEXES] = { MALLOC_LOCK_INITIALIZER(0), @@ -204,51 +223,16 @@ static struct pthread_mutex malloc_lock[_MALLOC_MUTEXES] = { MALLOC_LOCK_INITIALIZER(31) }; -static pthread_mutex_t malloc_mutex[_MALLOC_MUTEXES] = { - &malloc_lock[0], - &malloc_lock[1], - &malloc_lock[2], - &malloc_lock[3], - &malloc_lock[4], - &malloc_lock[5], - &malloc_lock[6], - &malloc_lock[7], - &malloc_lock[8], - &malloc_lock[9], - &malloc_lock[10], - &malloc_lock[11], - &malloc_lock[12], - &malloc_lock[13], - &malloc_lock[14], - &malloc_lock[15], - &malloc_lock[16], - &malloc_lock[17], - &malloc_lock[18], - &malloc_lock[19], - &malloc_lock[20], - &malloc_lock[21], - &malloc_lock[22], - &malloc_lock[23], - &malloc_lock[24], - &malloc_lock[25], - &malloc_lock[26], - &malloc_lock[27], - &malloc_lock[28], - &malloc_lock[29], - &malloc_lock[30], - &malloc_lock[31] -}; - void _thread_malloc_lock(int i) { - pthread_mutex_lock(&malloc_mutex[i]); + pthread_mutex_lock(&malloc_lock[i]); } void _thread_malloc_unlock(int i) { - pthread_mutex_unlock(&malloc_mutex[i]); + pthread_mutex_unlock(&malloc_lock[i]); } static void @@ -257,12 +241,7 @@ _thread_malloc_reinit(void) int i; for (i = 0; i < _MALLOC_MUTEXES; i++) { - malloc_lock[i].lock = _SPINLOCK_UNLOCKED; -#ifndef FUTEX - TAILQ_INIT(&malloc_lock[i].lockers); -#endif - malloc_lock[i].owner = NULL; - malloc_lock[i].count = 0; + pthread_mutex_init(&malloc_lock[i], NULL); } } diff --git a/lib/libc/thread/rthread_mutex.c b/lib/libc/thread/rthread_mutex.c index c9a490033b3..ce3d25fc4db 100644 --- a/lib/libc/thread/rthread_mutex.c +++ b/lib/libc/thread/rthread_mutex.c @@ -46,14 +46,11 @@ enum { static _atomic_lock_t static_init_lock = _SPINLOCK_UNLOCKED; int -pthread_mutex_init(pthread_mutex_t *mutexp, const pthread_mutexattr_t *attr) +pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { - pthread_mutex_t mutex; - - mutex = calloc(1, sizeof(*mutex)); - if (mutex == NULL) - return (ENOMEM); - + pthread_t self = pthread_self(); + _rthread_debug(5, "%p: mutex_init %p\n", self, (void *)mutex); + *mutex = (pthread_mutex_t) { 0 }; if (attr == NULL) { mutex->type = PTHREAD_MUTEX_DEFAULT; mutex->prioceiling = -1; @@ -62,43 +59,33 @@ pthread_mutex_init(pthread_mutex_t *mutexp, const pthread_mutexattr_t *attr) mutex->prioceiling = (*attr)->ma_protocol == PTHREAD_PRIO_PROTECT ? (*attr)->ma_prioceiling : -1; } - *mutexp = mutex; - return (0); } DEF_STRONG(pthread_mutex_init); int -pthread_mutex_destroy(pthread_mutex_t *mutexp) +pthread_mutex_destroy(pthread_mutex_t *mutex) { - pthread_mutex_t mutex; - - if (mutexp == NULL || *mutexp == NULL) - return (EINVAL); - - mutex = *mutexp; if (mutex) { - if (mutex->lock != UNLOCKED) { + if (mutex->futex != UNLOCKED) { #define MSG "pthread_mutex_destroy on mutex with waiters!\n" write(2, MSG, sizeof(MSG) - 1); #undef MSG return (EBUSY); } - free((void *)mutex); - *mutexp = NULL; + *mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER; } - return (0); } DEF_STRONG(pthread_mutex_destroy); static int -_rthread_mutex_trylock(pthread_mutex_t mutex, int trywait, +_rthread_mutex_trylock(pthread_mutex_t *mutex, int trywait, const struct timespec *abs) { pthread_t self = pthread_self(); - if (atomic_cas_uint(&mutex->lock, UNLOCKED, LOCKED) == UNLOCKED) { + if (atomic_cas_uint(&mutex->futex, UNLOCKED, LOCKED) == UNLOCKED) { membar_enter_after_atomic(); mutex->owner = self; return (0); @@ -133,33 +120,24 @@ _rthread_mutex_trylock(pthread_mutex_t mutex, int trywait, } static int -_rthread_mutex_timedlock(pthread_mutex_t *mutexp, int trywait, +_rthread_mutex_timedlock(pthread_mutex_t *mutex, int trywait, const struct timespec *abs, int timed) { pthread_t self = pthread_self(); - pthread_mutex_t mutex; - unsigned int i, lock; + unsigned int i, futex; int error = 0; - if (mutexp == NULL) - return (EINVAL); - /* - * If the mutex is statically initialized, perform the dynamic - * initialization. Note: _thread_mutex_lock() in libc requires - * pthread_mutex_lock() to perform the mutex init when *mutexp - * is NULL. + * If the mutex is statically initialized, perform the actual + * initialization. */ - if (*mutexp == NULL) { + if (mutex->needinit) { _spinlock(&static_init_lock); - if (*mutexp == NULL) - error = pthread_mutex_init(mutexp, NULL); + if (mutex->needinit) + pthread_mutex_init(mutex, NULL); _spinunlock(&static_init_lock); - if (error != 0) - return (EINVAL); } - mutex = *mutexp; _rthread_debug(5, "%p: mutex_%slock %p (%p)\n", self, (timed ? "timed" : (trywait ? "try" : "")), (void *)mutex, (void *)mutex->owner); @@ -170,33 +148,34 @@ _rthread_mutex_timedlock(pthread_mutex_t *mutexp, int trywait, /* Try hard to not enter the kernel. */ for (i = 0; i < SPIN_COUNT; i++) { - if (mutex->lock == UNLOCKED) + if (mutex->futex == UNLOCKED) break; SPIN_WAIT(); } - lock = atomic_cas_uint(&mutex->lock, UNLOCKED, LOCKED); - if (lock == UNLOCKED) { + futex = atomic_cas_uint(&mutex->futex, UNLOCKED, LOCKED); + if (futex == UNLOCKED) { membar_enter_after_atomic(); mutex->owner = self; + return (0); } - if (lock != CONTENDED) { + if (futex != CONTENDED) { /* Indicate that we're waiting on this mutex. */ - lock = atomic_swap_uint(&mutex->lock, CONTENDED); + futex = atomic_swap_uint(&mutex->futex, CONTENDED); } - while (lock != UNLOCKED) { - error = _twait(&mutex->lock, CONTENDED, CLOCK_REALTIME, abs); + while (futex != UNLOCKED) { + error = _twait(&mutex->futex, CONTENDED, CLOCK_REALTIME, abs); if (error == ETIMEDOUT) return (error); /* * We cannot know if there's another waiter, so in * doubt set the state to CONTENDED. */ - lock = atomic_swap_uint(&mutex->lock, CONTENDED); + futex = atomic_swap_uint(&mutex->futex, CONTENDED); }; membar_enter_after_atomic(); @@ -224,24 +203,10 @@ pthread_mutex_lock(pthread_mutex_t *mutexp) DEF_STRONG(pthread_mutex_lock); int -pthread_mutex_unlock(pthread_mutex_t *mutexp) +pthread_mutex_unlock(pthread_mutex_t *mutex) { pthread_t self = pthread_self(); - pthread_mutex_t mutex; - - if (mutexp == NULL) - return (EINVAL); - - if (*mutexp == NULL) -#if PTHREAD_MUTEX_DEFAULT == PTHREAD_MUTEX_ERRORCHECK - return (EPERM); -#elif PTHREAD_MUTEX_DEFAULT == PTHREAD_MUTEX_NORMAL - return(0); -#else - abort(); -#endif - mutex = *mutexp; _rthread_debug(5, "%p: mutex_unlock %p (%p)\n", self, (void *)mutex, (void *)mutex->owner); @@ -276,9 +241,9 @@ pthread_mutex_unlock(pthread_mutex_t *mutexp) mutex->owner = NULL; membar_exit_before_atomic(); - if (atomic_dec_int_nv(&mutex->lock) != UNLOCKED) { - mutex->lock = UNLOCKED; - _wake(&mutex->lock, 1); + if (atomic_dec_int_nv(&mutex->futex) != UNLOCKED) { + mutex->futex = UNLOCKED; + _wake(&mutex->futex, 1); } return (0); diff --git a/lib/libc/thread/rthread_sync.c b/lib/libc/thread/rthread_sync.c index 42e1a7ee737..ad518c8d929 100644 --- a/lib/libc/thread/rthread_sync.c +++ b/lib/libc/thread/rthread_sync.c @@ -36,13 +36,12 @@ static _atomic_lock_t static_init_lock = _SPINLOCK_UNLOCKED; * mutexen */ int -pthread_mutex_init(pthread_mutex_t *mutexp, const pthread_mutexattr_t *attr) +pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { - struct pthread_mutex *mutex; + pthread_t self = pthread_self(); - mutex = calloc(1, sizeof(*mutex)); - if (!mutex) - return (errno); + _rthread_debug(5, "%p: mutex_init %p\n", self, (void *)mutex); + *mutex = (pthread_mutex_t) { 0 }; mutex->lock = _SPINLOCK_UNLOCKED; TAILQ_INIT(&mutex->lockers); if (attr == NULL) { @@ -53,19 +52,14 @@ pthread_mutex_init(pthread_mutex_t *mutexp, const pthread_mutexattr_t *attr) mutex->prioceiling = (*attr)->ma_protocol == PTHREAD_PRIO_PROTECT ? (*attr)->ma_prioceiling : -1; } - *mutexp = mutex; return (0); } DEF_STRONG(pthread_mutex_init); int -pthread_mutex_destroy(pthread_mutex_t *mutexp) +pthread_mutex_destroy(pthread_mutex_t *mutex) { - struct pthread_mutex *mutex; - - assert(mutexp); - mutex = (struct pthread_mutex *)*mutexp; if (mutex) { if (mutex->count || mutex->owner != NULL || !TAILQ_EMPTY(&mutex->lockers)) { @@ -74,36 +68,29 @@ pthread_mutex_destroy(pthread_mutex_t *mutexp) #undef MSG return (EBUSY); } - free(mutex); - *mutexp = NULL; + *mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER; } return (0); } DEF_STRONG(pthread_mutex_destroy); static int -_rthread_mutex_lock(pthread_mutex_t *mutexp, int trywait, +_rthread_mutex_lock(pthread_mutex_t *mutex, int trywait, const struct timespec *abstime) { - struct pthread_mutex *mutex; pthread_t self = pthread_self(); int ret = 0; /* - * If the mutex is statically initialized, perform the dynamic - * initialization. Note: _thread_mutex_lock() in libc requires - * _rthread_mutex_lock() to perform the mutex init when *mutexp - * is NULL. + * If the mutex is statically initialized, perform the actual + * initialization. */ - if (*mutexp == NULL) { + if (mutex->needinit) { _spinlock(&static_init_lock); - if (*mutexp == NULL) - ret = pthread_mutex_init(mutexp, NULL); + if (mutex->needinit) + pthread_mutex_init(mutex, NULL); _spinunlock(&static_init_lock); - if (ret != 0) - return (EINVAL); } - mutex = (struct pthread_mutex *)*mutexp; _rthread_debug(5, "%p: mutex_lock %p\n", (void *)self, (void *)mutex); _spinlock(&mutex->lock); @@ -185,23 +172,13 @@ pthread_mutex_timedlock(pthread_mutex_t *p, const struct timespec *abstime) } int -pthread_mutex_unlock(pthread_mutex_t *mutexp) +pthread_mutex_unlock(pthread_mutex_t *mutex) { pthread_t self = pthread_self(); - struct pthread_mutex *mutex = (struct pthread_mutex *)*mutexp; _rthread_debug(5, "%p: mutex_unlock %p\n", (void *)self, (void *)mutex); - if (mutex == NULL) -#if PTHREAD_MUTEX_DEFAULT == PTHREAD_MUTEX_ERRORCHECK - return (EPERM); -#elif PTHREAD_MUTEX_DEFAULT == PTHREAD_MUTEX_NORMAL - return(0); -#else - abort(); -#endif - if (mutex->owner != self) { if (mutex->type == PTHREAD_MUTEX_ERRORCHECK || mutex->type == PTHREAD_MUTEX_RECURSIVE) @@ -282,11 +259,10 @@ pthread_cond_destroy(pthread_cond_t *condp) } int -pthread_cond_timedwait(pthread_cond_t *condp, pthread_mutex_t *mutexp, +pthread_cond_timedwait(pthread_cond_t *condp, pthread_mutex_t *mutex, const struct timespec *abstime) { pthread_cond_t cond; - struct pthread_mutex *mutex = (struct pthread_mutex *)*mutexp; struct tib *tib = TIB_GET(); pthread_t self = tib->tib_thread; pthread_t next; @@ -439,10 +415,9 @@ pthread_cond_timedwait(pthread_cond_t *condp, pthread_mutex_t *mutexp, } int -pthread_cond_wait(pthread_cond_t *condp, pthread_mutex_t *mutexp) +pthread_cond_wait(pthread_cond_t *condp, pthread_mutex_t *mutex) { pthread_cond_t cond; - struct pthread_mutex *mutex = (struct pthread_mutex *)*mutexp; struct tib *tib = TIB_GET(); pthread_t self = tib->tib_thread; pthread_t next; diff --git a/lib/librthread/rthread_barrier.c b/lib/librthread/rthread_barrier.c index 1d7fb66de64..24991771174 100644 --- a/lib/librthread/rthread_barrier.c +++ b/lib/librthread/rthread_barrier.c @@ -59,8 +59,7 @@ pthread_barrier_init(pthread_barrier_t *barrier, pthread_barrierattr_t *attr, err: if (b) { - if (b->mutex) - pthread_mutex_destroy(&b->mutex); + pthread_mutex_destroy(&b->mutex); if (b->cond) pthread_cond_destroy(&b->cond); free(b); diff --git a/lib/librthread/rthread_mutex_prio.c b/lib/librthread/rthread_mutex_prio.c index d675b37ea5f..824731b027e 100644 --- a/lib/librthread/rthread_mutex_prio.c +++ b/lib/librthread/rthread_mutex_prio.c @@ -22,10 +22,8 @@ #include "rthread.h" int -pthread_mutex_getprioceiling(pthread_mutex_t *mutexp, int *prioceiling) +pthread_mutex_getprioceiling(pthread_mutex_t *mutex, int *prioceiling) { - pthread_mutex_t mutex = *mutexp; - if (mutex->prioceiling == -1) return (EINVAL); *prioceiling = mutex->prioceiling; @@ -34,20 +32,19 @@ pthread_mutex_getprioceiling(pthread_mutex_t *mutexp, int *prioceiling) } int -pthread_mutex_setprioceiling(pthread_mutex_t *mutexp, int prioceiling, +pthread_mutex_setprioceiling(pthread_mutex_t *mutex, int prioceiling, int *old_ceiling) { - pthread_mutex_t mutex = *mutexp; int ret; if (mutex->prioceiling == -1 || prioceiling < PTHREAD_MIN_PRIORITY || prioceiling > PTHREAD_MAX_PRIORITY) { ret = EINVAL; - } else if ((ret = pthread_mutex_lock(mutexp)) == 0) { + } else if ((ret = pthread_mutex_lock(mutex)) == 0) { *old_ceiling = mutex->prioceiling; mutex->prioceiling = prioceiling; - pthread_mutex_unlock(mutexp); + pthread_mutex_unlock(mutex); } return (ret); diff --git a/lib/librthread/shlib_version b/lib/librthread/shlib_version index 72168dfd16a..54ef0c4cc0c 100644 --- a/lib/librthread/shlib_version +++ b/lib/librthread/shlib_version @@ -1,2 +1,2 @@ -major=26 -minor=1 +major=27 +minor=0 -- 2.31.1 -- Lauri Tirkkonen | lotheac @ IRCnet