summaryrefslogtreecommitdiffstats
path: root/lib/libkse/thread/thr_mutex.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libkse/thread/thr_mutex.c')
-rw-r--r--lib/libkse/thread/thr_mutex.c64
1 files changed, 48 insertions, 16 deletions
diff --git a/lib/libkse/thread/thr_mutex.c b/lib/libkse/thread/thr_mutex.c
index b8877f8..f7662c7 100644
--- a/lib/libkse/thread/thr_mutex.c
+++ b/lib/libkse/thread/thr_mutex.c
@@ -79,7 +79,7 @@ static spinlock_t static_init_lock = _SPINLOCK_INITIALIZER;
int
_mutex_reinit(pthread_mutex_t * mutex)
{
- int ret = 0;
+ int ret = 0;
if (mutex == NULL)
ret = EINVAL;
@@ -113,7 +113,7 @@ pthread_mutex_init(pthread_mutex_t * mutex,
int protocol;
int ceiling;
pthread_mutex_t pmutex;
- int ret = 0;
+ int ret = 0;
if (mutex == NULL)
ret = EINVAL;
@@ -203,7 +203,7 @@ pthread_mutex_init(pthread_mutex_t * mutex,
int
pthread_mutex_destroy(pthread_mutex_t * mutex)
{
- int ret = 0;
+ int ret = 0;
if (mutex == NULL || *mutex == NULL)
ret = EINVAL;
@@ -245,7 +245,7 @@ pthread_mutex_destroy(pthread_mutex_t * mutex)
static int
init_static(pthread_mutex_t *mutex)
{
- int ret;
+ int ret;
_SPINLOCK(&static_init_lock);
@@ -262,7 +262,7 @@ init_static(pthread_mutex_t *mutex)
int
pthread_mutex_trylock(pthread_mutex_t * mutex)
{
- int ret = 0;
+ int ret = 0;
if (mutex == NULL)
ret = EINVAL;
@@ -400,7 +400,7 @@ pthread_mutex_trylock(pthread_mutex_t * mutex)
int
pthread_mutex_lock(pthread_mutex_t * mutex)
{
- int ret = 0;
+ int ret = 0;
if (mutex == NULL)
ret = EINVAL;
@@ -610,9 +610,8 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
* Check to see if this thread was interrupted and
* is still in the mutex queue of waiting threads:
*/
- if (_thread_run->interrupted != 0) {
+ if (_thread_run->interrupted != 0)
mutex_queue_remove(*mutex, _thread_run);
- }
/* Unlock the mutex structure: */
_SPINUNLOCK(&(*mutex)->lock);
@@ -647,7 +646,7 @@ _mutex_cv_unlock(pthread_mutex_t * mutex)
int
_mutex_cv_lock(pthread_mutex_t * mutex)
{
- int ret;
+ int ret;
if ((ret = pthread_mutex_lock(mutex)) == 0)
(*mutex)->m_refcount--;
return (ret);
@@ -656,7 +655,7 @@ _mutex_cv_lock(pthread_mutex_t * mutex)
static inline int
mutex_self_trylock(pthread_mutex_t mutex)
{
- int ret = 0;
+ int ret = 0;
switch (mutex->m_type) {
@@ -723,7 +722,7 @@ mutex_self_lock(pthread_mutex_t mutex)
static inline int
mutex_unlock_common(pthread_mutex_t * mutex, int add_reference)
{
- int ret = 0;
+ int ret = 0;
if (mutex == NULL || *mutex == NULL) {
ret = EINVAL;
@@ -1369,6 +1368,38 @@ _mutex_unlock_private(pthread_t pthread)
}
}
+void
+_mutex_lock_backout(pthread_t pthread)
+{
+ struct pthread_mutex *mutex;
+
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+ if (pthread->state == PS_MUTEX_WAIT) {
+ mutex = pthread->data.mutex;
+
+ /* Lock the mutex structure: */
+ _SPINLOCK(&mutex->lock);
+
+ mutex_queue_remove(mutex, pthread);
+
+ /* This thread is no longer waiting for the mutex: */
+ mutex->m_owner->data.mutex = NULL;
+
+ /* Unlock the mutex structure: */
+ _SPINUNLOCK(&mutex->lock);
+
+ }
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
+}
+
/*
* Dequeue a waiting thread from the head of a mutex queue in descending
* priority order.
@@ -1379,7 +1410,7 @@ mutex_queue_deq(pthread_mutex_t mutex)
pthread_t pthread;
while ((pthread = TAILQ_FIRST(&mutex->m_queue)) != NULL) {
- TAILQ_REMOVE(&mutex->m_queue, pthread, qe);
+ TAILQ_REMOVE(&mutex->m_queue, pthread, sqe);
pthread->flags &= ~PTHREAD_FLAGS_IN_MUTEXQ;
/*
@@ -1400,7 +1431,7 @@ static inline void
mutex_queue_remove(pthread_mutex_t mutex, pthread_t pthread)
{
if ((pthread->flags & PTHREAD_FLAGS_IN_MUTEXQ) != 0) {
- TAILQ_REMOVE(&mutex->m_queue, pthread, qe);
+ TAILQ_REMOVE(&mutex->m_queue, pthread, sqe);
pthread->flags &= ~PTHREAD_FLAGS_IN_MUTEXQ;
}
}
@@ -1413,18 +1444,19 @@ mutex_queue_enq(pthread_mutex_t mutex, pthread_t pthread)
{
pthread_t tid = TAILQ_LAST(&mutex->m_queue, mutex_head);
+ PTHREAD_ASSERT_NOT_IN_SYNCQ(pthread);
/*
* For the common case of all threads having equal priority,
* we perform a quick check against the priority of the thread
* at the tail of the queue.
*/
if ((tid == NULL) || (pthread->active_priority <= tid->active_priority))
- TAILQ_INSERT_TAIL(&mutex->m_queue, pthread, qe);
+ TAILQ_INSERT_TAIL(&mutex->m_queue, pthread, sqe);
else {
tid = TAILQ_FIRST(&mutex->m_queue);
while (pthread->active_priority <= tid->active_priority)
- tid = TAILQ_NEXT(tid, qe);
- TAILQ_INSERT_BEFORE(tid, pthread, qe);
+ tid = TAILQ_NEXT(tid, sqe);
+ TAILQ_INSERT_BEFORE(tid, pthread, sqe);
}
pthread->flags |= PTHREAD_FLAGS_IN_MUTEXQ;
}
OpenPOWER on IntegriCloud