Browse Source

add C11 mutex functions

Jens Gustedt 10 years ago
parent
commit
8b0472932c

+ 5 - 0
src/thread/mtx_destroy.c

@@ -0,0 +1,5 @@
+#include <threads.h>
+
+void mtx_destroy(mtx_t *mtx)
+{
+}

+ 10 - 0
src/thread/mtx_init.c

@@ -0,0 +1,10 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+int mtx_init(mtx_t *m, int type)
+{
+	*m = (mtx_t){
+		._m_type = ((type&mtx_recursive) ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL),
+	};
+	return thrd_success;
+}

+ 12 - 0
src/thread/mtx_lock.c

@@ -0,0 +1,12 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+int mtx_lock(mtx_t *m)
+{
+	if (m->_m_type == PTHREAD_MUTEX_NORMAL && !a_cas(&m->_m_lock, 0, EBUSY))
+		return thrd_success;
+	/* Calling mtx_timedlock with a null pointer is an extension.
+	 * It is convenient, here to avoid duplication of the logic
+	 * for return values. */
+	return mtx_timedlock(m, 0);
+}

+ 14 - 0
src/thread/mtx_timedlock.c

@@ -0,0 +1,14 @@
+#include <threads.h>
+#include <errno.h>
+
+int __pthread_mutex_timedlock(mtx_t *restrict, const struct timespec *restrict);
+
+int mtx_timedlock(mtx_t *restrict m, const struct timespec *restrict ts)
+{
+	int ret = __pthread_mutex_timedlock(m, ts);
+	switch (ret) {
+	default:        return thrd_error;
+	case 0:         return thrd_success;
+	case ETIMEDOUT: return thrd_timedout;
+	}
+}

+ 17 - 0
src/thread/mtx_trylock.c

@@ -0,0 +1,17 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+int __pthread_mutex_trylock(mtx_t *);
+
+int mtx_trylock(mtx_t *m)
+{
+	if (m->_m_type == PTHREAD_MUTEX_NORMAL)
+		return (a_cas(&m->_m_lock, 0, EBUSY) & EBUSY) ? thrd_busy : thrd_success;
+
+	int ret = __pthread_mutex_trylock(m);
+	switch (ret) {
+	default:    return thrd_error;
+	case 0:     return thrd_success;
+	case EBUSY: return thrd_busy;
+	}
+}

+ 11 - 0
src/thread/mtx_unlock.c

@@ -0,0 +1,11 @@
+#include <threads.h>
+
+int __pthread_mutex_unlock(mtx_t *);
+
+int mtx_unlock(mtx_t *mtx)
+{
+	/* The only cases where pthread_mutex_unlock can return an
+	 * error are undefined behavior for C11 mtx_unlock, so we can
+	 * assume it does not return an error and simply tail call. */
+	return __pthread_mutex_unlock(mtx);
+}