summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/pthread.h10
-rw-r--r--lib/libc_r/uthread/uthread_mattr_kind_np.c14
-rw-r--r--lib/libc_r/uthread/uthread_mutex.c67
-rw-r--r--lib/libkse/thread/thr_mattr_kind_np.c14
-rw-r--r--lib/libkse/thread/thr_mutex.c67
-rw-r--r--lib/libpthread/thread/thr_mattr_kind_np.c14
-rw-r--r--lib/libpthread/thread/thr_mutex.c67
7 files changed, 191 insertions, 62 deletions
diff --git a/include/pthread.h b/include/pthread.h
index 0c38271..dc8ebf0 100644
--- a/include/pthread.h
+++ b/include/pthread.h
@@ -164,11 +164,16 @@ struct pthread_once {
#endif
enum pthread_mutextype {
- MUTEX_TYPE_FAST = 1,
- MUTEX_TYPE_COUNTING_FAST = 2, /* Recursive */
+ PTHREAD_MUTEX_DEFAULT = 1,
+ PTHREAD_MUTEX_RECURSIVE = 2,
+ PTHREAD_MUTEX_NORMAL = 3,
+ PTHREAD_MUTEX_ERRORCHECK = 4,
MUTEX_TYPE_MAX
};
+#define MUTEX_TYPE_FAST PTHREAD_MUTEX_DEFAULT
+#define MUTEX_TYPE_COUNTING_FAST PTHREAD_MUTEX_RECURSIVE
+
/*
* Thread function prototype definitions:
*/
@@ -233,6 +238,7 @@ int pthread_mutexattr_setprotocol __P((pthread_mutexattr_t *,
int protocol));
int pthread_mutexattr_setpshared __P((pthread_mutexattr_t *,
int pshared));
+int pthread_mutexattr_settype __P((pthread_mutexattr_t *, int));
int pthread_mutex_destroy __P((pthread_mutex_t *));
int pthread_mutex_getprioceiling __P((pthread_mutex_t *));
int pthread_mutex_init __P((pthread_mutex_t *,
diff --git a/lib/libc_r/uthread/uthread_mattr_kind_np.c b/lib/libc_r/uthread/uthread_mattr_kind_np.c
index 3eeabff..c145a1f 100644
--- a/lib/libc_r/uthread/uthread_mattr_kind_np.c
+++ b/lib/libc_r/uthread/uthread_mattr_kind_np.c
@@ -61,4 +61,18 @@ pthread_mutexattr_getkind_np(pthread_mutexattr_t attr)
}
return(ret);
}
+
+int
+pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL || type >= MUTEX_TYPE_MAX) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ (*attr)->m_type = type;
+ ret = 0;
+ }
+ return(ret);
+}
#endif
diff --git a/lib/libc_r/uthread/uthread_mutex.c b/lib/libc_r/uthread/uthread_mutex.c
index a7e8dfe..d3801f1 100644
--- a/lib/libc_r/uthread/uthread_mutex.c
+++ b/lib/libc_r/uthread/uthread_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;
diff --git a/lib/libkse/thread/thr_mattr_kind_np.c b/lib/libkse/thread/thr_mattr_kind_np.c
index 3eeabff..c145a1f 100644
--- a/lib/libkse/thread/thr_mattr_kind_np.c
+++ b/lib/libkse/thread/thr_mattr_kind_np.c
@@ -61,4 +61,18 @@ pthread_mutexattr_getkind_np(pthread_mutexattr_t attr)
}
return(ret);
}
+
+int
+pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL || type >= MUTEX_TYPE_MAX) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ (*attr)->m_type = type;
+ ret = 0;
+ }
+ return(ret);
+}
#endif
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;
diff --git a/lib/libpthread/thread/thr_mattr_kind_np.c b/lib/libpthread/thread/thr_mattr_kind_np.c
index 3eeabff..c145a1f 100644
--- a/lib/libpthread/thread/thr_mattr_kind_np.c
+++ b/lib/libpthread/thread/thr_mattr_kind_np.c
@@ -61,4 +61,18 @@ pthread_mutexattr_getkind_np(pthread_mutexattr_t attr)
}
return(ret);
}
+
+int
+pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
+{
+ int ret;
+ if (attr == NULL || *attr == NULL || type >= MUTEX_TYPE_MAX) {
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ (*attr)->m_type = type;
+ ret = 0;
+ }
+ return(ret);
+}
#endif
diff --git a/lib/libpthread/thread/thr_mutex.c b/lib/libpthread/thread/thr_mutex.c
index a7e8dfe..d3801f1 100644
--- a/lib/libpthread/thread/thr_mutex.c
+++ b/lib/libpthread/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