diff --git a/libpthread/Makefile b/libpthread/Makefile
index f3248e9d..89aee0a0 100644
--- a/libpthread/Makefile
+++ b/libpthread/Makefile
@@ -13,6 +13,8 @@ CXXFLAGS:=$(CXXFLAGS) -Wall -Wextra -fno-exceptions -fno-rtti
OBJS=\
pthread_equal.o \
pthread_initialize.o \
+pthread_mutex_lock.o \
+pthread_mutex_unlock.o \
pthread_self.o \
BINS:=libpthread.a
diff --git a/libpthread/include/__/pthread.h b/libpthread/include/__/pthread.h
index de67c571..249c03ee 100644
--- a/libpthread/include/__/pthread.h
+++ b/libpthread/include/__/pthread.h
@@ -45,7 +45,23 @@ typedef int __pthread_condattr_t;
typedef int __pthread_key_t;
-typedef int __pthread_mutex_t;
+#if defined(__is_sortix_libpthread)
+typedef struct
+{
+ unsigned long lock;
+ unsigned long type;
+ unsigned long owner;
+ unsigned long recursion;
+} __pthread_mutex_t;
+#else
+typedef struct
+{
+ unsigned long __pthread_lock;
+ unsigned long __pthread_type;
+ unsigned long __pthread_owner;
+ unsigned long __pthread_recursion;
+} __pthread_mutex_t;
+#endif
typedef int __pthread_mutexattr_t;
diff --git a/libpthread/include/pthread.h b/libpthread/include/pthread.h
index 544c2ef2..8475fbde 100644
--- a/libpthread/include/pthread.h
+++ b/libpthread/include/pthread.h
@@ -55,10 +55,10 @@ __BEGIN_DECLS
/* TODO: #define PTHREAD_CREATE_JOINABLE */
/* TODO: #define PTHREAD_EXPLICIT_SCHED */
/* TODO: #define PTHREAD_INHERIT_SCHED */
-/* TODO: #define PTHREAD_MUTEX_DEFAULT */
+#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
/* TODO: #define PTHREAD_MUTEX_ERRORCHECK */
-/* TODO: #define PTHREAD_MUTEX_NORMAL */
-/* TODO: #define PTHREAD_MUTEX_RECURSIVE */
+#define PTHREAD_MUTEX_NORMAL 0
+#define PTHREAD_MUTEX_RECURSIVE 1
/* TODO: #define PTHREAD_MUTEX_ROBUST */
/* TODO: #define PTHREAD_MUTEX_STALLED */
/* TODO: #define PTHREAD_ONCE_INIT */
@@ -143,9 +143,12 @@ struct pthread
#endif
#define PTHREAD_COND_INITIALIZER 0
-#define PTHREAD_MUTEX_INITIALIZER 0
+#define PTHREAD_MUTEX_INITIALIZER { 0, PTHREAD_MUTEX_DEFAULT, 0, 0 }
#define PTHREAD_RWLOCK_INITIALIZER 0
+#define PTHREAD_NORMAL_MUTEX_INITIALIZER_NP { 0, PTHREAD_MUTEX_NORMAL, 0, 0 }
+#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP { 0, PTHREAD_MUTEX_RECURSIVE, 0, 0 }
+
void pthread_initialize(void);
/* TODO: pthread_atfork */
@@ -204,11 +207,11 @@ int pthread_equal(pthread_t, pthread_t);
/* TODO: pthread_mutex_destroy */
/* TODO: pthread_mutex_getprioceiling */
/* TODO: pthread_mutex_init */
-/* TODO: pthread_mutex_lock */
+int pthread_mutex_lock(pthread_mutex_t*);
/* TODO: pthread_mutex_setprioceiling */
/* TODO: pthread_mutex_timedlock */
/* TODO: pthread_mutex_trylock */
-/* TODO: pthread_mutex_unlock */
+int pthread_mutex_unlock(pthread_mutex_t*);
/* TODO: pthread_mutexattr_destroy */
/* TODO: pthread_mutexattr_getprioceiling */
/* TODO: pthread_mutexattr_getprotocol */
diff --git a/libpthread/pthread_mutex_lock.c++ b/libpthread/pthread_mutex_lock.c++
new file mode 100644
index 00000000..5605a22d
--- /dev/null
+++ b/libpthread/pthread_mutex_lock.c++
@@ -0,0 +1,45 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013, 2014.
+
+ This file is part of Sortix libpthread.
+
+ Sortix libpthread is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ Sortix libpthread is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with Sortix libpthread. If not, see .
+
+ pthread_mutex_lock.c++
+ Locks a mutex.
+
+*******************************************************************************/
+
+#include
+#include
+#include
+#include
+
+static const unsigned long UNLOCKED_VALUE = 0;
+static const unsigned long LOCKED_VALUE = 1;
+
+extern "C" int pthread_mutex_lock(pthread_mutex_t* mutex)
+{
+ while ( !__sync_bool_compare_and_swap(&mutex->lock, UNLOCKED_VALUE, LOCKED_VALUE) )
+ {
+ if ( mutex->type == PTHREAD_MUTEX_RECURSIVE &&
+ (pthread_t) mutex->owner == pthread_self() )
+ return mutex->recursion++, 0;
+ sched_yield();
+ }
+ mutex->owner = (unsigned long) pthread_self();
+ mutex->recursion = 0;
+ return 0;
+}
diff --git a/libpthread/pthread_mutex_unlock.c++ b/libpthread/pthread_mutex_unlock.c++
new file mode 100644
index 00000000..eb02a75a
--- /dev/null
+++ b/libpthread/pthread_mutex_unlock.c++
@@ -0,0 +1,37 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013, 2014.
+
+ This file is part of Sortix libpthread.
+
+ Sortix libpthread is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ Sortix libpthread is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with Sortix libpthread. If not, see .
+
+ pthread_mutex_unlock.c++
+ Unlocks a mutex.
+
+*******************************************************************************/
+
+#include
+
+static const unsigned long UNLOCKED_VALUE = 0;
+static const unsigned long LOCKED_VALUE = 1;
+
+extern "C" int pthread_mutex_unlock(pthread_mutex_t* mutex)
+{
+ if ( mutex->type == PTHREAD_MUTEX_RECURSIVE && mutex->recursion )
+ return mutex->recursion--, 0;
+ mutex->owner = 0;
+ mutex->lock = UNLOCKED_VALUE;
+ return 0;
+}