From 42c051320d29a537c14df03f3fe18806bdcdc1db Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Tue, 3 Sep 2013 21:47:19 +0200 Subject: [PATCH] Add pthread_rwlock_{rdlock,wrlock}(3) and pthread_rwlock_unlock(3). --- libpthread/Makefile | 3 ++ libpthread/include/__/pthread.h | 24 ++++++++++++++- libpthread/include/pthread.h | 10 ++++--- libpthread/pthread_rwlock_rdlock.c++ | 37 +++++++++++++++++++++++ libpthread/pthread_rwlock_unlock.c++ | 45 ++++++++++++++++++++++++++++ libpthread/pthread_rwlock_wrlock.c++ | 37 +++++++++++++++++++++++ 6 files changed, 151 insertions(+), 5 deletions(-) create mode 100644 libpthread/pthread_rwlock_rdlock.c++ create mode 100644 libpthread/pthread_rwlock_unlock.c++ create mode 100644 libpthread/pthread_rwlock_wrlock.c++ diff --git a/libpthread/Makefile b/libpthread/Makefile index 43860bd8..b5f4b09c 100644 --- a/libpthread/Makefile +++ b/libpthread/Makefile @@ -32,6 +32,9 @@ pthread_mutex_init.o \ pthread_mutex_lock.o \ pthread_mutex_trylock.o \ pthread_mutex_unlock.o \ +pthread_rwlock_rdlock.o \ +pthread_rwlock_unlock.o \ +pthread_rwlock_wrlock.o \ pthread_self.o \ BINS:=libpthread.a diff --git a/libpthread/include/__/pthread.h b/libpthread/include/__/pthread.h index a3a5e227..1944c18e 100644 --- a/libpthread/include/__/pthread.h +++ b/libpthread/include/__/pthread.h @@ -101,7 +101,29 @@ typedef struct typedef int __pthread_once_t; -typedef int __pthread_rwlock_t; +#if defined(__is_sortix_libpthread) +typedef struct +{ + __pthread_cond_t reader_condition; + __pthread_cond_t writer_condition; + __pthread_mutex_t request_mutex; + unsigned long num_readers; + unsigned long num_writers; + unsigned long pending_readers; + unsigned long pending_writers; +} __pthread_rwlock_t; +#else +typedef struct +{ + __pthread_cond_t __pthread_reader_condition; + __pthread_cond_t __pthread_writer_condition; + __pthread_mutex_t __pthread_request_mutex; + unsigned long __pthread_num_readers; + unsigned long __pthread_num_writers; + unsigned long __pthread_pending_readers; + unsigned long __pthread_pending_writers; +} __pthread_rwlock_t; +#endif typedef int __pthread_rwlockattr_t; diff --git a/libpthread/include/pthread.h b/libpthread/include/pthread.h index fe52e916..2da9e4cd 100644 --- a/libpthread/include/pthread.h +++ b/libpthread/include/pthread.h @@ -152,7 +152,9 @@ struct pthread_cond_elem #define PTHREAD_COND_INITIALIZER { NULL, NULL, CLOCK_REALTIME } #define PTHREAD_MUTEX_INITIALIZER { 0, PTHREAD_MUTEX_DEFAULT, 0, 0 } -#define PTHREAD_RWLOCK_INITIALIZER 0 +#define PTHREAD_RWLOCK_INITIALIZER { PTHREAD_COND_INITIALIZER, \ + PTHREAD_COND_INITIALIZER, \ + PTHREAD_MUTEX_INITIALIZER, 0, 0, 0, 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 } @@ -240,13 +242,13 @@ int pthread_mutexattr_settype(pthread_mutexattr_t*, int); /* TODO: pthread_once */ /* TODO: pthread_rwlock_destroy */ /* TODO: pthread_rwlock_init */ -/* TODO: pthread_rwlock_rdlock */ +int pthread_rwlock_rdlock(pthread_rwlock_t*); /* TODO: pthread_rwlock_timedrdlock */ /* TODO: pthread_rwlock_timedwrlock */ /* TODO: pthread_rwlock_tryrdlock */ /* TODO: pthread_rwlock_trywrlock */ -/* TODO: pthread_rwlock_unlock */ -/* TODO: pthread_rwlock_wrlock */ +int pthread_rwlock_unlock(pthread_rwlock_t*); +int pthread_rwlock_wrlock(pthread_rwlock_t*); /* TODO: pthread_rwlockattr_destroy */ /* TODO: pthread_rwlockattr_getpshared */ /* TODO: pthread_rwlockattr_init */ diff --git a/libpthread/pthread_rwlock_rdlock.c++ b/libpthread/pthread_rwlock_rdlock.c++ new file mode 100644 index 00000000..146f31ea --- /dev/null +++ b/libpthread/pthread_rwlock_rdlock.c++ @@ -0,0 +1,37 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + 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_rwlock_rdlock.c++ + Acquires read access to a read-write lock. + +*******************************************************************************/ + +#include + +extern "C" int pthread_rwlock_rdlock(pthread_rwlock_t* rwlock) +{ + pthread_mutex_lock(&rwlock->request_mutex); + rwlock->pending_readers++; + while ( rwlock->num_writers || rwlock->pending_writers ) + pthread_cond_wait(&rwlock->reader_condition, &rwlock->request_mutex); + rwlock->pending_readers--; + rwlock->num_readers++; + pthread_mutex_unlock(&rwlock->request_mutex); + return 0; +} diff --git a/libpthread/pthread_rwlock_unlock.c++ b/libpthread/pthread_rwlock_unlock.c++ new file mode 100644 index 00000000..2ad5fbed --- /dev/null +++ b/libpthread/pthread_rwlock_unlock.c++ @@ -0,0 +1,45 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + 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_rwlock_unlock.c++ + Releases hold of a read-write lock. + +*******************************************************************************/ + +#include + +extern "C" int pthread_rwlock_unlock(pthread_rwlock_t* rwlock) +{ + pthread_mutex_lock(&rwlock->request_mutex); + if ( rwlock->num_writers ) + { + rwlock->num_writers = 0; + if ( rwlock->pending_writers ) + pthread_cond_signal(&rwlock->writer_condition); + else + pthread_cond_broadcast(&rwlock->reader_condition); + } + else + { + if ( --rwlock->num_readers == 0 && rwlock->pending_writers ) + pthread_cond_signal(&rwlock->writer_condition); + } + pthread_mutex_unlock(&rwlock->request_mutex); + return 0; +} diff --git a/libpthread/pthread_rwlock_wrlock.c++ b/libpthread/pthread_rwlock_wrlock.c++ new file mode 100644 index 00000000..bf36d14c --- /dev/null +++ b/libpthread/pthread_rwlock_wrlock.c++ @@ -0,0 +1,37 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + 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_rwlock_wrlock.c++ + Acquires write access to a read-write lock. + +*******************************************************************************/ + +#include + +extern "C" int pthread_rwlock_wrlock(pthread_rwlock_t* rwlock) +{ + pthread_mutex_lock(&rwlock->request_mutex); + rwlock->pending_writers++; + while ( rwlock->num_readers || rwlock->num_writers ) + pthread_cond_wait(&rwlock->writer_condition, &rwlock->request_mutex); + rwlock->pending_writers--; + rwlock->num_writers = 1; + pthread_mutex_unlock(&rwlock->request_mutex); + return 0; +}