summaryrefslogtreecommitdiffstats
path: root/lib/libkse/thread/thr_mutex.c
diff options
context:
space:
mode:
authoreivind <eivind@FreeBSD.org>1998-11-28 23:52:58 +0000
committereivind <eivind@FreeBSD.org>1998-11-28 23:52:58 +0000
commit083b0d7688fa9abeb57de744e997044767be0259 (patch)
tree5f53d2cbe90934f9d98b0d8ba5cf3407e6fba004 /lib/libkse/thread/thr_mutex.c
parent9eb948517872cbf893bb6f18d88ff5016b9fd899 (diff)
downloadFreeBSD-src-083b0d7688fa9abeb57de744e997044767be0259.zip
FreeBSD-src-083b0d7688fa9abeb57de744e997044767be0259.tar.gz
Add support for pthread_mutexattr_settype(). As a side effect of
testing this, fix MUTEX_TYPE_COUNTING_FAST. Recursive locks now work.
Diffstat (limited to 'lib/libkse/thread/thr_mutex.c')
-rw-r--r--lib/libkse/thread/thr_mutex.c67
1 files changed, 47 insertions, 20 deletions
diff --git a/lib/libkse/thread/thr_mutex.c b/lib/libkse/thread/thr_mutex.c
index a7e8dfe..d3801f1 100644
--- a/lib/libkse/thread/thr_mutex.c
+++ b/lib/libkse/thread/thr_mutex.c
@@ -53,7 +53,7 @@ pthread_mutex_init(pthread_mutex_t * mutex,
/* Check if default mutex attributes: */
if (mutex_attr == NULL || *mutex_attr == NULL)
/* Default to a fast mutex: */
- type = MUTEX_TYPE_FAST;
+ type = PTHREAD_MUTEX_DEFAULT;
else if ((*mutex_attr)->m_type >= MUTEX_TYPE_MAX)
/* Return an invalid argument error: */
@@ -74,12 +74,14 @@ pthread_mutex_init(pthread_mutex_t * mutex,
/* Process according to mutex type: */
switch (type) {
/* Fast mutex: */
- case MUTEX_TYPE_FAST:
+ case PTHREAD_MUTEX_DEFAULT:
+ case PTHREAD_MUTEX_NORMAL:
+ case PTHREAD_MUTEX_ERRORCHECK:
/* Nothing to do here. */
break;
/* Counting mutex: */
- case MUTEX_TYPE_COUNTING_FAST:
+ case PTHREAD_MUTEX_RECURSIVE:
/* Reset the mutex count: */
pmutex->m_data.m_count = 0;
break;
@@ -174,7 +176,9 @@ pthread_mutex_trylock(pthread_mutex_t * mutex)
/* Process according to mutex type: */
switch ((*mutex)->m_type) {
/* Fast mutex: */
- case MUTEX_TYPE_FAST:
+ case PTHREAD_MUTEX_NORMAL:
+ case PTHREAD_MUTEX_DEFAULT:
+ case PTHREAD_MUTEX_ERRORCHECK:
/* Check if this mutex is not locked: */
if ((*mutex)->m_owner == NULL) {
/* Lock the mutex for the running thread: */
@@ -186,7 +190,7 @@ pthread_mutex_trylock(pthread_mutex_t * mutex)
break;
/* Counting mutex: */
- case MUTEX_TYPE_COUNTING_FAST:
+ case PTHREAD_MUTEX_RECURSIVE:
/* Check if this mutex is locked: */
if ((*mutex)->m_owner != NULL) {
/*
@@ -239,8 +243,26 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
/* Process according to mutex type: */
switch ((*mutex)->m_type) {
+ /* What SS2 define as a 'normal' mutex. This has to deadlock
+ on attempts to get a lock you already own. */
+ case PTHREAD_MUTEX_NORMAL:
+ if ((*mutex)->m_owner == _thread_run) {
+ /* Intetionally deadlock */
+ for (;;)
+ _thread_kern_sched_state(PS_MUTEX_WAIT, __FILE__, __LINE__);
+ }
+ goto COMMON_LOCK;
+
+ /* Return error (not OK) on attempting to re-lock */
+ case PTHREAD_MUTEX_ERRORCHECK:
+ if ((*mutex)->m_owner == _thread_run) {
+ ret = EDEADLK;
+ break;
+ }
+
/* Fast mutexes do not check for any error conditions: */
- case MUTEX_TYPE_FAST:
+ case PTHREAD_MUTEX_DEFAULT:
+ COMMON_LOCK:
/*
* Enter a loop to wait for the mutex to be locked by the
* current thread:
@@ -269,7 +291,7 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
break;
/* Counting mutex: */
- case MUTEX_TYPE_COUNTING_FAST:
+ case PTHREAD_MUTEX_RECURSIVE:
/*
* Enter a loop to wait for the mutex to be locked by the
* current thread:
@@ -331,12 +353,15 @@ pthread_mutex_unlock(pthread_mutex_t * mutex)
/* Process according to mutex type: */
switch ((*mutex)->m_type) {
- /* Fast mutexes do not check for any error conditions: */
- case MUTEX_TYPE_FAST:
+ /* Default & normal mutexes do not really need to check for
+ any error conditions: */
+ case PTHREAD_MUTEX_NORMAL:
+ case PTHREAD_MUTEX_DEFAULT:
+ case PTHREAD_MUTEX_ERRORCHECK:
/* Check if the running thread is not the owner of the mutex: */
if ((*mutex)->m_owner != _thread_run) {
/* Return an invalid argument error: */
- ret = EINVAL;
+ ret = (*mutex)->m_owner ? EPERM : EINVAL;
}
/*
* Get the next thread from the queue of threads waiting on
@@ -349,24 +374,26 @@ pthread_mutex_unlock(pthread_mutex_t * mutex)
break;
/* Counting mutex: */
- case MUTEX_TYPE_COUNTING_FAST:
+ case PTHREAD_MUTEX_RECURSIVE:
/* Check if the running thread is not the owner of the mutex: */
if ((*mutex)->m_owner != _thread_run) {
/* Return an invalid argument error: */
ret = EINVAL;
}
/* Check if there are still counts: */
- else if ((*mutex)->m_data.m_count) {
+ else if ((*mutex)->m_data.m_count > 1) {
/* Decrement the count: */
(*mutex)->m_data.m_count--;
- }
- /*
- * Get the next thread from the queue of threads waiting on
- * the mutex:
- */
- else if (((*mutex)->m_owner = _thread_queue_deq(&(*mutex)->m_queue)) != NULL) {
- /* Allow the new owner of the mutex to run: */
- PTHREAD_NEW_STATE((*mutex)->m_owner,PS_RUNNING);
+ } else {
+ (*mutex)->m_data.m_count = 0;
+ /*
+ * Get the next thread from the queue of threads waiting on
+ * the mutex:
+ */
+ if (((*mutex)->m_owner = _thread_queue_deq(&(*mutex)->m_queue)) != NULL) {
+ /* Allow the new owner of the mutex to run: */
+ PTHREAD_NEW_STATE((*mutex)->m_owner,PS_RUNNING);
+ }
}
break;
OpenPOWER on IntegriCloud