summaryrefslogtreecommitdiffstats
path: root/lib/libthr/thread/thr_mutex.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libthr/thread/thr_mutex.c')
-rw-r--r--lib/libthr/thread/thr_mutex.c156
1 files changed, 89 insertions, 67 deletions
diff --git a/lib/libthr/thread/thr_mutex.c b/lib/libthr/thread/thr_mutex.c
index fdceadf..e79e014 100644
--- a/lib/libthr/thread/thr_mutex.c
+++ b/lib/libthr/thread/thr_mutex.c
@@ -77,7 +77,7 @@ int __pthread_mutex_timedlock(pthread_mutex_t *mutex,
static int mutex_self_trylock(pthread_mutex_t);
static int mutex_self_lock(pthread_mutex_t,
const struct timespec *abstime);
-static int mutex_unlock_common(pthread_mutex_t *, int);
+static int mutex_unlock_common(pthread_mutex_t *);
__weak_reference(__pthread_mutex_init, pthread_mutex_init);
__weak_reference(__pthread_mutex_lock, pthread_mutex_lock);
@@ -285,34 +285,36 @@ int
__pthread_mutex_trylock(pthread_mutex_t *mutex)
{
struct pthread *curthread = _get_curthread();
- int ret = 0;
+ int ret;
/*
* If the mutex is statically initialized, perform the dynamic
* initialization:
*/
- if ((*mutex != NULL) ||
- ((ret = init_static(curthread, mutex)) == 0))
- ret = mutex_trylock_common(curthread, mutex);
-
- return (ret);
+ if (__predict_false(*mutex == NULL)) {
+ ret = init_static(curthread, mutex);
+ if (__predict_false(ret))
+ return (ret);
+ }
+ return (mutex_trylock_common(curthread, mutex));
}
int
_pthread_mutex_trylock(pthread_mutex_t *mutex)
{
struct pthread *curthread = _get_curthread();
- int ret = 0;
+ int ret;
/*
* If the mutex is statically initialized, perform the dynamic
* initialization marking the mutex private (delete safe):
*/
- if ((*mutex != NULL) ||
- ((ret = init_static_private(curthread, mutex)) == 0))
- ret = mutex_trylock_common(curthread, mutex);
-
- return (ret);
+ if (__predict_false(*mutex == NULL)) {
+ ret = init_static_private(curthread, mutex);
+ if (__predict_false(ret))
+ return (ret);
+ }
+ return (mutex_trylock_common(curthread, mutex));
}
static int
@@ -321,7 +323,7 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *mutex,
{
struct timespec ts, ts2;
struct pthread_mutex *m;
- int ret = 0;
+ int ret;
m = *mutex;
ret = THR_UMTX_TRYLOCK(curthread, &m->m_lock);
@@ -336,6 +338,10 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *mutex,
if (abstime == NULL) {
THR_UMTX_LOCK(curthread, &m->m_lock);
ret = 0;
+ } else if (__predict_false(
+ abstime->tv_sec < 0 || abstime->tv_nsec < 0 ||
+ abstime->tv_nsec >= 1000000000)) {
+ ret = EINVAL;
} else {
clock_gettime(CLOCK_REALTIME, &ts);
TIMESPEC_SUB(&ts2, abstime, &ts);
@@ -361,7 +367,7 @@ int
__pthread_mutex_lock(pthread_mutex_t *m)
{
struct pthread *curthread;
- int ret = 0;
+ int ret;
_thr_check_init();
@@ -371,17 +377,19 @@ __pthread_mutex_lock(pthread_mutex_t *m)
* If the mutex is statically initialized, perform the dynamic
* initialization:
*/
- if ((*m != NULL) || ((ret = init_static(curthread, m)) == 0))
- ret = mutex_lock_common(curthread, m, NULL);
-
- return (ret);
+ if (__predict_false(*m == NULL)) {
+ ret = init_static(curthread, m);
+ if (__predict_false(ret))
+ return (ret);
+ }
+ return (mutex_lock_common(curthread, m, NULL));
}
int
_pthread_mutex_lock(pthread_mutex_t *m)
{
struct pthread *curthread;
- int ret = 0;
+ int ret;
_thr_check_init();
@@ -391,82 +399,74 @@ _pthread_mutex_lock(pthread_mutex_t *m)
* If the mutex is statically initialized, perform the dynamic
* initialization marking it private (delete safe):
*/
- if ((*m != NULL) ||
- ((ret = init_static_private(curthread, m)) == 0))
- ret = mutex_lock_common(curthread, m, NULL);
-
- return (ret);
+ if (__predict_false(*m == NULL)) {
+ ret = init_static_private(curthread, m);
+ if (__predict_false(ret))
+ return (ret);
+ }
+ return (mutex_lock_common(curthread, m, NULL));
}
int
__pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *abstime)
{
struct pthread *curthread;
- int ret = 0;
+ int ret;
_thr_check_init();
- if (abstime != NULL && (abstime->tv_sec < 0 || abstime->tv_nsec < 0 ||
- abstime->tv_nsec >= 1000000000))
- return (EINVAL);
-
curthread = _get_curthread();
/*
* If the mutex is statically initialized, perform the dynamic
* initialization:
*/
- if ((*m != NULL) || ((ret = init_static(curthread, m)) == 0))
- ret = mutex_lock_common(curthread, m, abstime);
-
- return (ret);
+ if (__predict_false(*m == NULL)) {
+ ret = init_static(curthread, m);
+ if (__predict_false(ret))
+ return (ret);
+ }
+ return (mutex_lock_common(curthread, m, abstime));
}
int
_pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *abstime)
{
struct pthread *curthread;
- int ret = 0;
+ int ret;
_thr_check_init();
- if (abstime != NULL && (abstime->tv_sec < 0 || abstime->tv_nsec < 0 ||
- abstime->tv_nsec >= 1000000000))
- return (EINVAL);
-
curthread = _get_curthread();
/*
* If the mutex is statically initialized, perform the dynamic
* initialization marking it private (delete safe):
*/
- if ((*m != NULL) ||
- ((ret = init_static_private(curthread, m)) == 0))
- ret = mutex_lock_common(curthread, m, abstime);
-
- return (ret);
+ if (__predict_false(*m == NULL)) {
+ ret = init_static_private(curthread, m);
+ if (__predict_false(ret))
+ return (ret);
+ }
+ return (mutex_lock_common(curthread, m, abstime));
}
int
_pthread_mutex_unlock(pthread_mutex_t *m)
{
- return (mutex_unlock_common(m, /* add reference */ 0));
-}
-
-int
-_mutex_cv_unlock(pthread_mutex_t *m)
-{
- return (mutex_unlock_common(m, /* add reference */ 1));
+ return (mutex_unlock_common(m));
}
int
-_mutex_cv_lock(pthread_mutex_t *m)
+_mutex_cv_lock(pthread_mutex_t *m, int count)
{
int ret;
ret = mutex_lock_common(_get_curthread(), m, NULL);
- if (ret == 0)
+ if (ret == 0) {
(*m)->m_refcount--;
+ (*m)->m_count += count;
+ }
return (ret);
}
@@ -557,11 +557,10 @@ mutex_self_lock(pthread_mutex_t m, const struct timespec *abstime)
}
static int
-mutex_unlock_common(pthread_mutex_t *mutex, int add_reference)
+mutex_unlock_common(pthread_mutex_t *mutex)
{
struct pthread *curthread = _get_curthread();
struct pthread_mutex *m;
- int ret = 0;
if (__predict_false((m = *mutex) == NULL))
return (EINVAL);
@@ -569,29 +568,52 @@ mutex_unlock_common(pthread_mutex_t *mutex, int add_reference)
/*
* Check if the running thread is not the owner of the mutex.
*/
- if (__predict_false(m->m_owner != curthread)) {
- ret = EPERM;
- } else if (__predict_false(
+ if (__predict_false(m->m_owner != curthread))
+ return (EPERM);
+
+ if (__predict_false(
m->m_type == PTHREAD_MUTEX_RECURSIVE &&
m->m_count > 0)) {
m->m_count--;
- if (add_reference)
- m->m_refcount++;
} else {
- /*
- * Clear the count in case this is a recursive mutex.
- */
- m->m_count = 0;
m->m_owner = NULL;
/* Remove the mutex from the threads queue. */
MUTEX_ASSERT_IS_OWNED(m);
TAILQ_REMOVE(&curthread->mutexq, m, m_qe);
MUTEX_INIT_LINK(m);
- if (add_reference)
- m->m_refcount++;
THR_UMTX_UNLOCK(curthread, &m->m_lock);
}
- return (ret);
+ return (0);
+}
+
+int
+_mutex_cv_unlock(pthread_mutex_t *mutex, int *count)
+{
+ struct pthread *curthread = _get_curthread();
+ struct pthread_mutex *m;
+
+ if (__predict_false((m = *mutex) == NULL))
+ return (EINVAL);
+
+ /*
+ * Check if the running thread is not the owner of the mutex.
+ */
+ if (__predict_false(m->m_owner != curthread))
+ return (EPERM);
+
+ /*
+ * Clear the count in case this is a recursive mutex.
+ */
+ *count = m->m_count;
+ m->m_refcount++;
+ m->m_count = 0;
+ m->m_owner = NULL;
+ /* Remove the mutex from the threads queue. */
+ MUTEX_ASSERT_IS_OWNED(m);
+ TAILQ_REMOVE(&curthread->mutexq, m, m_qe);
+ MUTEX_INIT_LINK(m);
+ THR_UMTX_UNLOCK(curthread, &m->m_lock);
+ return (0);
}
void
OpenPOWER on IntegriCloud