From 8f12a5f6f96ba5bac6588b8dc5886732cd1263f8 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Tue, 3 Sep 2013 15:17:13 +0200 Subject: [PATCH] Add pthread_cond_{broadcast,signal}(3) and pthread_cond_wait(3). --- libpthread/Makefile | 3 ++ libpthread/include/__/pthread.h | 14 +++++++- libpthread/include/pthread.h | 16 ++++++--- libpthread/pthread_cond_broadcast.c++ | 33 ++++++++++++++++++ libpthread/pthread_cond_signal.c++ | 37 ++++++++++++++++++++ libpthread/pthread_cond_wait.c++ | 50 +++++++++++++++++++++++++++ 6 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 libpthread/pthread_cond_broadcast.c++ create mode 100644 libpthread/pthread_cond_signal.c++ create mode 100644 libpthread/pthread_cond_wait.c++ diff --git a/libpthread/Makefile b/libpthread/Makefile index fce68a45..c8827fcd 100644 --- a/libpthread/Makefile +++ b/libpthread/Makefile @@ -11,6 +11,9 @@ CPPFLAGS:=$(CPPFLAGS) -D__is_sortix_libpthread -I include CXXFLAGS:=$(CXXFLAGS) -Wall -Wextra -fno-exceptions -fno-rtti OBJS=\ +pthread_cond_broadcast.o \ +pthread_cond_signal.o \ +pthread_cond_wait.o \ pthread_equal.o \ pthread_initialize.o \ pthread_mutexattr_destroy.o \ diff --git a/libpthread/include/__/pthread.h b/libpthread/include/__/pthread.h index 506515a2..b277c744 100644 --- a/libpthread/include/__/pthread.h +++ b/libpthread/include/__/pthread.h @@ -39,7 +39,19 @@ typedef int __pthread_barrier_t; typedef int __pthread_barrierattr_t; -typedef int __pthread_cond_t; +#if defined(__is_sortix_libpthread) +typedef struct +{ + struct pthread_cond_elem* first; + struct pthread_cond_elem* last; +} __pthread_cond_t; +#else +typedef struct +{ + void* __pthread_first; + void* __pthread_last; +} __pthread_cond_t; +#endif typedef int __pthread_condattr_t; diff --git a/libpthread/include/pthread.h b/libpthread/include/pthread.h index f11d8956..d9924a83 100644 --- a/libpthread/include/pthread.h +++ b/libpthread/include/pthread.h @@ -142,7 +142,15 @@ struct pthread }; #endif -#define PTHREAD_COND_INITIALIZER 0 +#if defined(__is_sortix_libpthread) +struct pthread_cond_elem +{ + struct pthread_cond_elem* next; + volatile unsigned long woken; +}; +#endif + +#define PTHREAD_COND_INITIALIZER { NULL, NULL } #define PTHREAD_MUTEX_INITIALIZER { 0, PTHREAD_MUTEX_DEFAULT, 0, 0 } #define PTHREAD_RWLOCK_INITIALIZER 0 @@ -180,12 +188,12 @@ void pthread_initialize(void); /* TODO: pthread_cancel */ /* TODO: pthread_cleanup_pop */ /* TODO: pthread_cleanup_push */ -/* TODO: pthread_cond_broadcast */ +int pthread_cond_broadcast(pthread_cond_t*); /* TODO: pthread_cond_destroy */ /* TODO: pthread_cond_init */ -/* TODO: pthread_cond_signal */ +int pthread_cond_signal(pthread_cond_t*); /* TODO: pthread_cond_timedwait */ -/* TODO: pthread_cond_wait */ +int pthread_cond_wait(pthread_cond_t* __restrict, pthread_mutex_t* __restrict); /* TODO: pthread_condattr_destroy */ /* TODO: pthread_condattr_getclock */ /* TODO: pthread_condattr_getpshared */ diff --git a/libpthread/pthread_cond_broadcast.c++ b/libpthread/pthread_cond_broadcast.c++ new file mode 100644 index 00000000..43b0dff9 --- /dev/null +++ b/libpthread/pthread_cond_broadcast.c++ @@ -0,0 +1,33 @@ +/******************************************************************************* + + 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_cond_broadcast.c++ + Broadcasts a condition. + +*******************************************************************************/ + +#include + +extern "C" int pthread_cond_broadcast(pthread_cond_t* cond) +{ + while ( cond->first ) + if ( int ret = pthread_cond_signal(cond) ) + return ret; + return 0; +} diff --git a/libpthread/pthread_cond_signal.c++ b/libpthread/pthread_cond_signal.c++ new file mode 100644 index 00000000..c754ea13 --- /dev/null +++ b/libpthread/pthread_cond_signal.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_cond_signal.c++ + Signals a condition. + +*******************************************************************************/ + +#include + +extern "C" int pthread_cond_signal(pthread_cond_t* cond) +{ + struct pthread_cond_elem* elem = cond->first; + if ( !elem ) + return 0; + if ( !(cond->first = elem->next) ) + cond->last = NULL; + elem->next = NULL; + elem->woken = 1; + return 0; +} diff --git a/libpthread/pthread_cond_wait.c++ b/libpthread/pthread_cond_wait.c++ new file mode 100644 index 00000000..70457ec1 --- /dev/null +++ b/libpthread/pthread_cond_wait.c++ @@ -0,0 +1,50 @@ +/******************************************************************************* + + 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_cond_wait.c++ + Waits on a condition. + +*******************************************************************************/ + +#include +#include +#include +#include +#include + +extern "C" +int pthread_cond_wait(pthread_cond_t* restrict cond, + pthread_mutex_t* restrict mutex) +{ + struct pthread_cond_elem elem; + elem.next = NULL; + elem.woken = 0; + if ( cond->last ) + cond->last->next = &elem; + if ( !cond->last ) + cond->first = &elem; + cond->last = &elem; + while ( !elem.woken ) + { + pthread_mutex_unlock(mutex); + sched_yield(); + pthread_mutex_lock(mutex); + } + return 0; +}