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; +}