From: Christian Thalinger Date: Fri, 27 Jun 2008 16:12:09 +0000 (+0200) Subject: * src/threads/mutex.h: Renamed to... X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=61fb7f16bca49237e5cb7cf856c6d393fc58d95e;p=cacao.git * src/threads/mutex.h: Renamed to... * src/threads/mutex.hpp: New file. * src/threads/posix/mutex-posix.h: Renamed to... * src/threads/posix/mutex-posix.hpp: New file. * src/threads/condition.hpp: Likewise. * src/threads/posix/condition-posix.hpp: Likewise. * src/threads/removeme.cpp: New file which contains legacy C wrapper. This one should be removed ASAP. * src/threads/Makefile.am (libthreads_la_SOURCES): Removed mutex.h, added condition.hpp and removeme.cpp and mutex.hpp. * src/threads/posix/Makefile.am (libthreadsposix_la_SOURCES): Removed mutex-posix.h, added condition-posix.hpp and mutex-posix.hpp. * src/cacao/cacao.c (threads/mutex.h): Removed. (main) [ENABLE_JVMTI]: Comment added. * src/vm/vm.c (threads/mutex.h): Removed. (vm_shutdown) [ENABLE_JVMTI]: Comment added. * src/threads/posix/lock.c, src/threads/posix/lock.h, src/threads/posix/thread-posix.c, src/threads/posix/thread-posix.h, src/threads/thread.h, src/threads/threadlist.c: Use new Mutex and Condition functions. --HG-- rename : src/threads/mutex.h => src/threads/mutex.hpp rename : src/threads/posix/mutex-posix.h => src/threads/posix/mutex-posix.hpp --- diff --git a/src/cacao/cacao.c b/src/cacao/cacao.c index c65a890f1..83b98d9ea 100644 --- a/src/cacao/cacao.c +++ b/src/cacao/cacao.c @@ -44,7 +44,6 @@ #if defined(ENABLE_JVMTI) # include "native/jvmti/jvmti.h" # include "native/jvmti/cacaodbg.h" -# include "threads/mutex.h" #endif #include "vmcore/system.h" @@ -172,7 +171,8 @@ int main(int argc, char **argv) (void) vm_createjvm(&vm, (void *) &env, vm_args); #if defined(ENABLE_JVMTI) - mutex_init(&dbgcomlock); +# error This should be a JVMTI function. + Mutex_init(&dbgcomlock); if (jvmti) jvmti_set_phase(JVMTI_PHASE_START); #endif diff --git a/src/threads/Makefile.am b/src/threads/Makefile.am index 1aa9df94f..6f69df0f0 100644 --- a/src/threads/Makefile.am +++ b/src/threads/Makefile.am @@ -49,8 +49,10 @@ noinst_LTLIBRARIES = \ if ENABLE_THREADS libthreads_la_SOURCES = \ + condition.hpp \ lock-common.h \ - mutex.h \ + removeme.cpp \ + mutex.hpp \ threadlist.c \ threadlist.h \ thread.c \ diff --git a/src/threads/condition.hpp b/src/threads/condition.hpp new file mode 100644 index 000000000..b2378357e --- /dev/null +++ b/src/threads/condition.hpp @@ -0,0 +1,52 @@ +/* src/threads/condition.hpp - condition variable + + Copyright (C) 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO + + This file is part of CACAO. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + +*/ + + +#ifndef _CONDITION_HPP +#define _CONDITION_HPP + +#include "config.h" + +#include "threads/mutex.hpp" + +#if defined(ENABLE_THREADS) +# include "threads/posix/condition-posix.hpp" +#endif + +#endif /* _CONDITION_HPP */ + + +/* + * These are local overrides for various environment variables in Emacs. + * Please do not remove this and leave it at the end of the file, where + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c++ + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + * vim:noexpandtab:sw=4:ts=4: + */ diff --git a/src/threads/mutex.h b/src/threads/mutex.h deleted file mode 100644 index 7458b0d8e..000000000 --- a/src/threads/mutex.h +++ /dev/null @@ -1,51 +0,0 @@ -/* src/threads/mutex.h - machine independent mutual exclusion functions - - Copyright (C) 2008 - CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO - - This file is part of CACAO. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - This program 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 - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. - -*/ - - -#ifndef _MUTEX_H -#define _MUTEX_H - -#include "config.h" - -#if defined(ENABLE_THREADS) -# include "threads/posix/mutex-posix.h" -#endif - - -#endif /* _MUTEX_H */ - - -/* - * These are local overrides for various environment variables in Emacs. - * Please do not remove this and leave it at the end of the file, where - * Emacs will automagically detect them. - * --------------------------------------------------------------------- - * Local variables: - * mode: c - * indent-tabs-mode: t - * c-basic-offset: 4 - * tab-width: 4 - * End: - * vim:noexpandtab:sw=4:ts=4: - */ diff --git a/src/threads/mutex.hpp b/src/threads/mutex.hpp new file mode 100644 index 000000000..e8bbce33c --- /dev/null +++ b/src/threads/mutex.hpp @@ -0,0 +1,50 @@ +/* src/threads/mutex.hpp - machine independent mutual exclusion functions + + Copyright (C) 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO + + This file is part of CACAO. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + +*/ + + +#ifndef _MUTEX_HPP +#define _MUTEX_HPP + +#include "config.h" + +#if defined(ENABLE_THREADS) +# include "threads/posix/mutex-posix.hpp" +#endif + +#endif /* _MUTEX_HPP */ + + +/* + * These are local overrides for various environment variables in Emacs. + * Please do not remove this and leave it at the end of the file, where + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c++ + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + * vim:noexpandtab:sw=4:ts=4: + */ diff --git a/src/threads/posix/Makefile.am b/src/threads/posix/Makefile.am index 880d47f29..bb18964f0 100644 --- a/src/threads/posix/Makefile.am +++ b/src/threads/posix/Makefile.am @@ -29,9 +29,10 @@ noinst_LTLIBRARIES = \ libthreadsposix.la libthreadsposix_la_SOURCES = \ + condition-posix.hpp \ lock.c \ lock.h \ - mutex-posix.h \ + mutex-posix.hpp \ thread-posix.c \ thread-posix.h diff --git a/src/threads/posix/condition-posix.hpp b/src/threads/posix/condition-posix.hpp new file mode 100644 index 000000000..ed7432c34 --- /dev/null +++ b/src/threads/posix/condition-posix.hpp @@ -0,0 +1,173 @@ +/* src/threads/posix/condition-posix.hpp - POSIX condition variable + + Copyright (C) 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO + + This file is part of CACAO. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + +*/ + + +#ifndef _CONDITION_POSIX_HPP +#define _CONDITION_POSIX_HPP + +#include "config.h" + +#include +#include + +#include "vm/vm.h" + +#ifdef __cplusplus + +/** + * POSIX condition variable. + */ +class Condition { +private: + // POSIX condition structure. + pthread_cond_t _cond; + +public: + Condition(); + ~Condition(); + + void broadcast(); + void signal(); + void timedwait(Mutex* mutex, const struct timespec* abstime); + void wait(Mutex* mutex); +}; + + +/** + * Initialize a POSIX condition variable. + */ +inline Condition::Condition() +{ + int result; + + result = pthread_cond_init(&_cond, NULL); + + if (result != 0) + vm_abort_errnum(result, "Condition::Condition(): pthread_cond_init failed"); +} + + +/** + * Destroys a POSIX condition variable. + */ +inline Condition::~Condition() +{ + int result; + + result = pthread_cond_destroy(&_cond); + + if (result != 0) + vm_abort_errnum(result, "Condition::~Condition(): pthread_cond_destroy failed"); +} + + +/** + * Restarts all the threads that are waiting on the condition + * variable. + */ +inline void Condition::broadcast() +{ + int result; + + result = pthread_cond_broadcast(&_cond); + + if (result != 0) + vm_abort_errnum(result, "Condition::broadcast(): pthread_cond_broadcast failed"); +} + + +/** + * Restarts one of the threads that are waiting on this condition + * variable. + */ +inline void Condition::signal() +{ + int result; + + result = pthread_cond_signal(&_cond); + + if (result != 0) + vm_abort_errnum(result, "Condition::signal(): pthread_cond_signal failed"); +} + + +/** + * Waits on the condition variable, as wait() does, but it also bounds + * the duration of the wait. + */ +inline void Condition::timedwait(Mutex* mutex, const struct timespec* abstime) +{ + // This function can return return values which are valid. + (void) pthread_cond_timedwait(&_cond, &(mutex->_mutex), abstime); +} + + +/** + * Waits for the condition variable. + */ +inline void Condition::wait(Mutex* mutex) +{ + int result; + + result = pthread_cond_wait(&_cond, &(mutex->_mutex)); + + if (result != 0) + vm_abort_errnum(result, "Condition::wait(): pthread_cond_wait failed"); +} + +#else + +// This structure must have the same layout as the class above. +typedef struct Condition { + pthread_mutex_t _mutex; + pthread_cond_t _cond; +} Condition; + +Condition* Condition_new(); +void Condition_delete(Condition* cond); +void Condition_lock(Condition* cond); +void Condition_unlock(Condition* cond); +void Condition_broadcast(Condition* cond); +void Condition_signal(Condition* cond); +void Condition_timedwait(Condition* cond, Mutex *mutex, const struct timespec* abstime); +void Condition_wait(Condition* cond, Mutex* mutex); + +#endif + +#endif /* _CONDITION_POSIX_HPP */ + + +/* + * These are local overrides for various environment variables in Emacs. + * Please do not remove this and leave it at the end of the file, where + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c++ + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + * vim:noexpandtab:sw=4:ts=4: + */ diff --git a/src/threads/posix/lock.c b/src/threads/posix/lock.c index 71e5a0077..a858ae423 100644 --- a/src/threads/posix/lock.c +++ b/src/threads/posix/lock.c @@ -39,7 +39,7 @@ #include "native/llni.h" #include "threads/lock-common.h" -#include "threads/mutex.h" +#include "threads/mutex.hpp" #include "threads/threadlist.h" #include "threads/thread.h" @@ -273,7 +273,7 @@ static lock_record_t *lock_record_new(void) /* initialize the mutex */ - mutex_init(&(lr->mutex)); + lr->mutex = Mutex_new(); DEBUGLOCKS(("[lock_record_new : lr=%p]", (void *) lr)); @@ -296,7 +296,7 @@ static void lock_record_free(lock_record_t *lr) /* Destroy the mutex. */ - mutex_destroy(&(lr->mutex)); + Mutex_delete(lr->mutex); #if defined(ENABLE_GC_CACAO) /* unregister the lock object reference with the GC */ @@ -331,7 +331,7 @@ static void lock_record_free(lock_record_t *lr) static void lock_hashtable_init(void) { - mutex_init(&(lock_hashtable.mutex)); + lock_hashtable.mutex = Mutex_new(); lock_hashtable.size = LOCK_INITIAL_HASHTABLE_SIZE; lock_hashtable.entries = 0; @@ -434,7 +434,7 @@ void lock_hashtable_cleanup(void) /* lock the hashtable */ - mutex_lock(&(lock_hashtable.mutex)); + Mutex_lock(lock_hashtable.mutex); /* search the hashtable for cleared references */ @@ -470,7 +470,7 @@ void lock_hashtable_cleanup(void) /* unlock the hashtable */ - mutex_unlock(&(lock_hashtable.mutex)); + Mutex_unlock(lock_hashtable.mutex); } #endif @@ -506,7 +506,7 @@ static lock_record_t *lock_hashtable_get(threadobject *t, java_handle_t *o) /* lock the hashtable */ - mutex_lock(&(lock_hashtable.mutex)); + Mutex_lock(lock_hashtable.mutex); /* lookup the lock record in the hashtable */ @@ -550,7 +550,7 @@ static lock_record_t *lock_hashtable_get(threadobject *t, java_handle_t *o) /* unlock the hashtable */ - mutex_unlock(&(lock_hashtable.mutex)); + Mutex_unlock(lock_hashtable.mutex); /* return the new lock record */ @@ -578,7 +578,7 @@ static void lock_hashtable_remove(threadobject *t, java_handle_t *o) /* lock the hashtable */ - mutex_lock(&(lock_hashtable.mutex)); + Mutex_lock(lock_hashtable.mutex); /* get lock record */ @@ -617,7 +617,7 @@ static void lock_hashtable_remove(threadobject *t, java_handle_t *o) /* unlock the hashtable */ - mutex_unlock(&(lock_hashtable.mutex)); + Mutex_unlock(lock_hashtable.mutex); /* free the lock record */ @@ -745,7 +745,7 @@ static inline void lock_lockword_set(threadobject *t, java_handle_t *o, uintptr_ static inline void lock_record_enter(threadobject *t, lock_record_t *lr) { - mutex_lock(&(lr->mutex)); + Mutex_lock(lr->mutex); lr->owner = t; } @@ -767,7 +767,7 @@ static inline void lock_record_enter(threadobject *t, lock_record_t *lr) static inline void lock_record_exit(threadobject *t, lock_record_t *lr) { lr->owner = NULL; - mutex_unlock(&(lr->mutex)); + Mutex_unlock(lr->mutex); } @@ -848,7 +848,7 @@ static void sable_flc_waiting(ptrint lockword, threadobject *t, java_handle_t *o /* failure, TODO: add statistics */ return; - mutex_lock(&t_other->flc_lock); + Mutex_lock(t_other->flc_lock); old_flc = t_other->flc_bit; t_other->flc_bit = true; @@ -874,7 +874,7 @@ static void sable_flc_waiting(ptrint lockword, threadobject *t, java_handle_t *o /* Wait until another thread sees the flc bit and notifies us of unlocking. */ - pthread_cond_wait(&t->flc_cond, &t_other->flc_lock); + Condition_wait(t->flc_cond, t_other->flc_lock); /* Traverse FLC list looking if we're still there */ current = t_other->flc_list; @@ -895,14 +895,14 @@ static void sable_flc_waiting(ptrint lockword, threadobject *t, java_handle_t *o else t_other->flc_bit = old_flc; - mutex_unlock(&t_other->flc_lock); + Mutex_unlock(t_other->flc_lock); } static void notify_flc_waiters(threadobject *t, java_handle_t *o) { threadobject *current; - mutex_lock(&t->flc_lock); + Mutex_lock(t->flc_lock); current = t->flc_list; while (current) @@ -925,14 +925,14 @@ static void notify_flc_waiters(threadobject *t, java_handle_t *o) } } /* Wake the waiting thread */ - pthread_cond_broadcast(¤t->flc_cond); + Condition_broadcast(current->flc_cond); current = current->flc_next; } t->flc_list = NULL; t->flc_bit = false; - mutex_unlock(&t->flc_lock); + Mutex_unlock(t->flc_lock); } /* lock_monitor_enter ********************************************************** @@ -1148,7 +1148,7 @@ bool lock_monitor_exit(java_handle_t *o) /* unlock this lock record */ lr->owner = NULL; - mutex_unlock(&(lr->mutex)); + Mutex_unlock(lr->mutex); return true; } @@ -1416,12 +1416,12 @@ static void lock_record_notify(threadobject *t, lock_record_t *lr, bool one) /* Enter the wait-mutex. */ - mutex_lock(&(waitingthread->waitmutex)); + Mutex_lock(waitingthread->waitmutex); DEBUGLOCKS(("[lock_record_notify: lr=%p, t=%p, waitingthread=%p, one=%d]", lr, t, waitingthread, one)); - pthread_cond_signal(&(waitingthread->waitcond)); + Condition_signal(waitingthread->waitcond); /* Mark the thread as signaled. */ @@ -1429,7 +1429,7 @@ static void lock_record_notify(threadobject *t, lock_record_t *lr, bool one) /* Leave the wait-mutex. */ - mutex_unlock(&(waitingthread->waitmutex)); + Mutex_unlock(waitingthread->waitmutex); /* if we should only wake one, we are done */ diff --git a/src/threads/posix/lock.h b/src/threads/posix/lock.h index 3b49f9946..ddadd3f81 100644 --- a/src/threads/posix/lock.h +++ b/src/threads/posix/lock.h @@ -38,7 +38,7 @@ extern "C" { #include "native/llni.h" -#include "threads/mutex.h" +#include "threads/mutex.hpp" #include "toolbox/list.h" @@ -75,7 +75,7 @@ struct lock_record_t { java_object_t *object; /* object for which this lock is */ struct threadobject *owner; /* current owner of this monitor */ s4 count; /* recursive lock count */ - mutex_t mutex; /* mutex for synchronizing */ + Mutex* mutex; /* mutex for synchronizing */ list_t *waiters; /* list of threads waiting */ lock_record_t *hashlink; /* next record in hash chain */ }; @@ -88,7 +88,7 @@ struct lock_record_t { *******************************************************************************/ struct lock_hashtable_t { - mutex_t mutex; /* mutex for synch. access to the table */ + Mutex* mutex; /* mutex for synch. access to the table */ u4 size; /* number of slots */ u4 entries; /* current number of entries */ lock_record_t **ptr; /* the table of slots, uses ext. chain. */ diff --git a/src/threads/posix/mutex-posix.h b/src/threads/posix/mutex-posix.h deleted file mode 100644 index b178c51d2..000000000 --- a/src/threads/posix/mutex-posix.h +++ /dev/null @@ -1,150 +0,0 @@ -/* src/threads/posix/mutex-posix.h - POSIX mutual exclusion functions - - Copyright (C) 2008 - CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO - - This file is part of CACAO. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - This program 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 - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. - -*/ - - -#ifndef _MUTEX_POSIX_H -#define _MUTEX_POSIX_H - -#include "config.h" - -#include - -#include "vm/vm.h" - - -/* POSIX mutex object *********************************************************/ - -typedef pthread_mutex_t mutex_t; - - -/* static mutex initializer ***************************************************/ - -#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER - - -/* inline functions ***********************************************************/ - -/* mutex_init ****************************************************************** - - Initializes the given mutex object and checks for errors. - - ARGUMENTS: - mutex ... POSIX mutex object - -*******************************************************************************/ - -inline static void mutex_init(mutex_t *mutex) -{ - int result; - - result = pthread_mutex_init(mutex, NULL); - - if (result != 0) - vm_abort_errnum(result, "mutex_init: pthread_mutex_init failed"); -} - - -/* mutex_lock ****************************************************************** - - Locks the given mutex object and checks for errors. If the mutex is - already locked by another thread, the calling thread is suspended until - the mutex is unlocked. - - If the mutex is already locked by the calling thread, the same applies, - thus effectively causing the calling thread to deadlock. (This is because - we use "fast" pthread mutexes without error checking.) - - ARGUMENTS: - mutex ... POSIX mutex object - -*******************************************************************************/ - -inline static void mutex_lock(mutex_t *mutex) -{ - int result; - - result = pthread_mutex_lock(mutex); - - if (result != 0) - vm_abort_errnum(result, "mutex_lock: pthread_mutex_lock failed"); -} - - -/* mutex_unlock **************************************************************** - - Unlocks the given mutex object and checks for errors. The mutex is - assumed to be locked and owned by the calling thread. - - ARGUMENTS: - mutex ... POSIX mutex object - -*******************************************************************************/ - -inline static void mutex_unlock(mutex_t *mutex) -{ - int result; - - result = pthread_mutex_unlock(mutex); - - if (result != 0) - vm_abort_errnum(result, "mutex_unlock: pthread_mutex_unlock failed"); -} - - -/* mutex_destroy *************************************************************** - - Destroys the given mutex object and checks for errors. - - ARGUMENTS: - mutex ... POSIX mutex object - -*******************************************************************************/ - -inline static void mutex_destroy(mutex_t *mutex) -{ - int result; - - result = pthread_mutex_destroy(mutex); - - if (result != 0) - vm_abort_errnum(result, "mutex_destroy: pthread_mutex_destroy failed"); -} - - -#endif /* _MUTEX_POSIX_H */ - - -/* - * These are local overrides for various environment variables in Emacs. - * Please do not remove this and leave it at the end of the file, where - * Emacs will automagically detect them. - * --------------------------------------------------------------------- - * Local variables: - * mode: c - * indent-tabs-mode: t - * c-basic-offset: 4 - * tab-width: 4 - * End: - * vim:noexpandtab:sw=4:ts=4: - */ diff --git a/src/threads/posix/mutex-posix.hpp b/src/threads/posix/mutex-posix.hpp new file mode 100644 index 000000000..5bf985624 --- /dev/null +++ b/src/threads/posix/mutex-posix.hpp @@ -0,0 +1,154 @@ +/* src/threads/posix/mutex-posix.hpp - POSIX mutual exclusion functions + + Copyright (C) 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO + + This file is part of CACAO. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + +*/ + + +#ifndef _MUTEX_POSIX_HPP +#define _MUTEX_POSIX_HPP + +#include "config.h" + +#include + +#include "vm/vm.h" + +#ifdef __cplusplus + +/** + * POSIX implementation of a mutex. + */ +class Mutex { +private: + // POSIX mutex structure. + pthread_mutex_t _mutex; + + // Condition class needs to access _mutex for wait() and + // timedwait(). + friend class Condition; + +public: + Mutex(); + ~Mutex(); + + void lock(); + void unlock(); +}; + + +/* static mutex initializer ***************************************************/ + +#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + + +/** + * Initializes the given mutex object and checks for errors. + */ +inline Mutex::Mutex() +{ + int result; + + result = pthread_mutex_init(&_mutex, NULL); + + if (result != 0) + vm_abort_errnum(result, "Mutex::Mutex(): pthread_mutex_init failed"); +} + + +/** + * Destroys the given mutex object and checks for errors. + */ +inline Mutex::~Mutex() +{ + int result; + + result = pthread_mutex_destroy(&_mutex); + + if (result != 0) + vm_abort_errnum(result, "Mutex::~Mutex(): pthread_mutex_destroy failed"); +} + + +/** + * Locks the given mutex object and checks for errors. If the mutex is + * already locked by another thread, the calling thread is suspended until + * the mutex is unlocked. + * + * If the mutex is already locked by the calling thread, the same applies, + * thus effectively causing the calling thread to deadlock. (This is because + * we use "fast" pthread mutexes without error checking.) + */ +inline void Mutex::lock() +{ + int result; + + result = pthread_mutex_lock(&_mutex); + + if (result != 0) + vm_abort_errnum(result, "Mutex::lock(): pthread_mutex_lock failed"); +} + + +/** + * Unlocks the given mutex object and checks for errors. The mutex is + * assumed to be locked and owned by the calling thread. + */ +inline void Mutex::unlock() +{ + int result; + + result = pthread_mutex_unlock(&_mutex); + + if (result != 0) + vm_abort_errnum(result, "Mutex::unlock: pthread_mutex_unlock failed"); +} + +#else + +// This structure must have the same layout as the class above. +typedef struct Mutex { + pthread_mutex_t _mutex; +} Mutex; + +Mutex* Mutex_new(); +void Mutex_delete(Mutex* mutex); +void Mutex_lock(Mutex* mutex); +void Mutex_unlock(Mutex* mutex); + +#endif + +#endif /* _MUTEX_POSIX_HPP */ + + +/* + * These are local overrides for various environment variables in Emacs. + * Please do not remove this and leave it at the end of the file, where + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c++ + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + * vim:noexpandtab:sw=4:ts=4: + */ diff --git a/src/threads/posix/thread-posix.c b/src/threads/posix/thread-posix.c index 8a19e1e7c..c4dee8543 100644 --- a/src/threads/posix/thread-posix.c +++ b/src/threads/posix/thread-posix.c @@ -73,8 +73,9 @@ # include "native/include/java_lang_VMThread.h" #endif +#include "threads/condition.hpp" #include "threads/lock-common.h" -#include "threads/mutex.h" +#include "threads/mutex.hpp" #include "threads/threadlist.h" #include "threads/thread.h" @@ -134,7 +135,7 @@ static int sem_init(sem_t *sem, int pshared, int value) sem->value = value; - mutex_init(&sem->mutex); + sem->mutex = Mutex_new(); if (pthread_cond_init(&sem->cond, NULL) < 0) return -1; @@ -144,31 +145,32 @@ static int sem_init(sem_t *sem, int pshared, int value) static int sem_post(sem_t *sem) { - mutex_lock(&sem->mutex); + Mutex_lock(sem->mutex); sem->value++; if (pthread_cond_signal(&sem->cond) < 0) { - mutex_unlock(&sem->mutex); + Mutex_unlock(sem->mutex); return -1; } - mutex_unlock(&sem->mutex); + Mutex_unlock(sem->mutex); return 0; } static int sem_wait(sem_t *sem) { - mutex_lock(&sem->mutex); + Mutex_lock(sem->mutex); while (sem->value == 0) { +#error We cannot call pthread_cond_wait on a Mutex-class pointer. pthread_cond_wait(&sem->cond, &sem->mutex); } sem->value--; - mutex_unlock(&sem->mutex); + Mutex_unlock(sem->mutex); return 0; } @@ -178,7 +180,7 @@ static int sem_destroy(sem_t *sem) if (pthread_cond_destroy(&sem->cond) < 0) return -1; - mutex_destroy(&sem->mutex); + Mutex_destroy(sem->mutex); return 0; } @@ -220,16 +222,16 @@ pthread_key_t thread_current_key; #endif /* global mutex for stop-the-world */ -static mutex_t stopworldlock; +static Mutex* stopworldlock; #if defined(ENABLE_GC_CACAO) /* global mutex for the GC */ -static mutex_t mutex_gc; +static Mutex* mutex_gc; #endif /* global mutex and condition for joining threads on exit */ -static mutex_t mutex_join; -static pthread_cond_t cond_join; +static Mutex* mutex_join; +static Condition* cond_join; #if defined(ENABLE_GC_CACAO) /* semaphore used for acknowleding thread suspension */ @@ -341,7 +343,7 @@ void threads_stopworld(void) s4 count, i; #endif - mutex_lock(&stopworldlock); + Mutex_lock(stopworldlock); /* lock the threads lists */ @@ -459,7 +461,7 @@ void threads_startworld(void) threadlist_unlock(); - mutex_unlock(&stopworldlock); + Mutex_unlock(stopworldlock); } #endif @@ -475,27 +477,16 @@ void threads_startworld(void) void threads_impl_thread_init(threadobject *t) { - int result; - /* initialize the mutex and the condition */ - mutex_init(&t->flc_lock); - - result = pthread_cond_init(&t->flc_cond, NULL); - if (result != 0) - vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed"); - - mutex_init(&(t->waitmutex)); + t->flc_lock = Mutex_new(); + t->flc_cond = Condition_new(); - result = pthread_cond_init(&(t->waitcond), NULL); - if (result != 0) - vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed"); - - mutex_init(&(t->suspendmutex)); + t->waitmutex = Mutex_new(); + t->waitcond = Condition_new(); - result = pthread_cond_init(&(t->suspendcond), NULL); - if (result != 0) - vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed"); + t->suspendmutex = Mutex_new(); + t->suspendcond = Condition_new(); } /* threads_impl_thread_clear *************************************************** @@ -604,21 +595,21 @@ void threads_impl_thread_free(threadobject *t) /* Destroy the mutex and the condition. */ - mutex_destroy(&(t->flc_lock)); + Mutex_delete(t->flc_lock); result = pthread_cond_destroy(&(t->flc_cond)); if (result != 0) vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed"); - mutex_destroy(&(t->waitmutex)); + Mutex_delete(t->waitmutex); result = pthread_cond_destroy(&(t->waitcond)); if (result != 0) vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed"); - mutex_destroy(&(t->suspendmutex)); + Mutex_delete(t->suspendmutex); result = pthread_cond_destroy(&(t->suspendcond)); @@ -641,21 +632,18 @@ void threads_impl_preinit(void) { int result; - mutex_init(&stopworldlock); + stopworldlock = Mutex_new(); /* initialize exit mutex and condition (on exit we join all threads) */ - mutex_init(&mutex_join); - - result = pthread_cond_init(&cond_join, NULL); - if (result != 0) - vm_abort_errnum(result, "threads_impl_preinit: pthread_cond_init failed"); + mutex_join = Mutex_new(); + cond_join = Condition_new(); #if defined(ENABLE_GC_CACAO) /* initialize the GC mutex & suspend semaphore */ - mutex_init(&mutex_gc); + mutex_gc = Mutex_new(); threads_sem_init(&suspend_ack, 0, 0); #endif @@ -676,7 +664,7 @@ void threads_impl_preinit(void) #if defined(ENABLE_GC_CACAO) void threads_mutex_gc_lock(void) { - mutex_lock(&mutex_gc); + Mutex_lock(mutex_gc); } #endif @@ -690,7 +678,7 @@ void threads_mutex_gc_lock(void) #if defined(ENABLE_GC_CACAO) void threads_mutex_gc_unlock(void) { - mutex_unlock(&mutex_gc); + Mutex_unlock(mutex_gc); } #endif @@ -702,7 +690,7 @@ void threads_mutex_gc_unlock(void) void threads_mutex_join_lock(void) { - mutex_lock(&mutex_join); + Mutex_lock(mutex_join); } @@ -714,7 +702,7 @@ void threads_mutex_join_lock(void) void threads_mutex_join_unlock(void) { - mutex_unlock(&mutex_join); + Mutex_unlock(mutex_join); } @@ -1206,7 +1194,7 @@ bool thread_detach_current_thread(void) /* Signal that this thread has finished and leave the mutex. */ - pthread_cond_signal(&cond_join); + Condition_signal(cond_join); threads_mutex_join_unlock(); return true; @@ -1226,10 +1214,10 @@ bool thread_detach_current_thread(void) bool threads_suspend_thread(threadobject *thread, s4 reason) { /* acquire the suspendmutex */ - mutex_lock(&(thread->suspendmutex)); + Mutex_lock(thread->suspendmutex); if (thread->suspended) { - mutex_unlock(&(thread->suspendmutex)); + Mutex_unlock(thread->suspendmutex); return false; } @@ -1295,7 +1283,7 @@ void threads_suspend_ack(u1* pc, u1* sp) DEBUGTHREADS("suspending", thread); /* release the suspension mutex and wait till we are resumed */ - pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex)); + Condition_wait(thread->suspendcond, thread->suspendmutex); DEBUGTHREADS("resuming", thread); @@ -1307,7 +1295,7 @@ void threads_suspend_ack(u1* pc, u1* sp) /* TODO: free dump memory */ /* release the suspendmutex */ - mutex_unlock(&(thread->suspendmutex)); + Mutex_unlock(thread->suspendmutex); } #endif @@ -1322,10 +1310,10 @@ void threads_suspend_ack(u1* pc, u1* sp) bool threads_resume_thread(threadobject *thread) { /* acquire the suspendmutex */ - mutex_lock(&(thread->suspendmutex)); + Mutex_lock(thread->suspendmutex); if (!thread->suspended) { - mutex_unlock(&(thread->suspendmutex)); + Mutex_unlock(thread->suspendmutex); return false; } @@ -1333,10 +1321,10 @@ bool threads_resume_thread(threadobject *thread) /* tell everyone that the thread should resume */ assert(thread != THREADOBJECT); - pthread_cond_broadcast(&(thread->suspendcond)); + Condition_broadcast(thread->suspendcond); /* release the suspendmutex */ - mutex_unlock(&(thread->suspendmutex)); + Mutex_unlock(thread->suspendmutex); return true; } @@ -1370,7 +1358,7 @@ void threads_join_all_threads(void) non-daemon thread. */ while (threadlist_get_non_daemons() > 1) - pthread_cond_wait(&cond_join, &mutex_join); + Condition_wait(cond_join, mutex_join); /* leave join mutex */ @@ -1450,7 +1438,7 @@ static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTi { /* acquire the waitmutex */ - mutex_lock(&t->waitmutex); + Mutex_lock(t->waitmutex); /* wait on waitcond */ @@ -1461,8 +1449,7 @@ static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTi { thread_set_state_timed_waiting(t); - pthread_cond_timedwait(&t->waitcond, &t->waitmutex, - wakeupTime); + Condition_timedwait(t->waitcond, t->waitmutex, wakeupTime); thread_set_state_runnable(t); } @@ -1472,7 +1459,7 @@ static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTi while (!t->interrupted && !t->signaled) { thread_set_state_waiting(t); - pthread_cond_wait(&t->waitcond, &t->waitmutex); + Condition_wait(t->waitcond, t->waitmutex); thread_set_state_runnable(t); } @@ -1480,7 +1467,7 @@ static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTi /* release the waitmutex */ - mutex_unlock(&t->waitmutex); + Mutex_unlock(t->waitmutex); } @@ -1566,7 +1553,7 @@ void threads_thread_interrupt(threadobject *thread) /* Signal the thread a "waitcond" and tell it that it has been interrupted. */ - mutex_lock(&thread->waitmutex); + Mutex_lock(thread->waitmutex); DEBUGTHREADS("interrupted", thread); @@ -1574,11 +1561,11 @@ void threads_thread_interrupt(threadobject *thread) pthread_kill(thread->tid, sig); - pthread_cond_signal(&thread->waitcond); + Condition_signal(thread->waitcond); thread->interrupted = true; - mutex_unlock(&thread->waitmutex); + Mutex_unlock(thread->waitmutex); } diff --git a/src/threads/posix/thread-posix.h b/src/threads/posix/thread-posix.h index 45d05eca4..5c107f863 100644 --- a/src/threads/posix/thread-posix.h +++ b/src/threads/posix/thread-posix.h @@ -42,7 +42,8 @@ typedef struct threadobject threadobject; #include "native/localref.h" -#include "threads/mutex.h" +#include "threads/condition.hpp" +#include "threads/mutex.hpp" #include "threads/posix/lock.h" @@ -126,15 +127,15 @@ struct threadobject { struct threadobject *flc_list; /* FLC list head for this thread */ struct threadobject *flc_next; /* next pointer for FLC list */ java_handle_t *flc_object; - mutex_t flc_lock; /* controlling access to these fields */ - pthread_cond_t flc_cond; + Mutex* flc_lock; /* controlling access to these fields */ + Condition* flc_cond; /* these are used for the wait/notify implementation */ - mutex_t waitmutex; - pthread_cond_t waitcond; + Mutex* waitmutex; + Condition* waitcond; - mutex_t suspendmutex; /* lock before suspending this thread */ - pthread_cond_t suspendcond; /* notify to resume this thread */ + Mutex* suspendmutex; /* lock before suspending this thread */ + Condition* suspendcond; /* notify to resume this thread */ bool interrupted; bool signaled; diff --git a/src/threads/removeme.cpp b/src/threads/removeme.cpp new file mode 100644 index 000000000..60878ce5a --- /dev/null +++ b/src/threads/removeme.cpp @@ -0,0 +1,61 @@ +/* src/threads/removeme.cpp + + Copyright (C) 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO + + This file is part of CACAO. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + +*/ + +// XXX Remove me as soon as all using files have been converted to C++! + +#include "config.h" + +#include "threads/condition.hpp" +#include "threads/mutex.hpp" + +extern "C" { + +Mutex* Mutex_new() { return new Mutex(); } +void Mutex_delete(Mutex* mutex) { delete mutex; } +void Mutex_lock(Mutex* mutex) { mutex->lock(); } +void Mutex_unlock(Mutex* mutex) { mutex->unlock(); } + +Condition* Condition_new() { return new Condition(); } +void Condition_delete(Condition* cond) { delete cond; } +void Condition_broadcast(Condition* cond) { cond->broadcast(); } +void Condition_signal(Condition* cond) { cond->signal(); } +void Condition_timedwait(Condition* cond, Mutex* mutex, const struct timespec* abstime) { cond->timedwait(mutex, abstime); } +void Condition_wait(Condition* cond, Mutex* mutex) { cond->wait(mutex); } + +} + + +/* + * These are local overrides for various environment variables in Emacs. + * Please do not remove this and leave it at the end of the file, where + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c++ + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + * vim:noexpandtab:sw=4:ts=4: + */ diff --git a/src/threads/thread.h b/src/threads/thread.h index b1f4eef7e..6d4e02e31 100644 --- a/src/threads/thread.h +++ b/src/threads/thread.h @@ -34,6 +34,8 @@ extern "C" { #include "vmcore/system.h" +#include "threads/mutex.hpp" + #if defined(ENABLE_THREADS) # include "threads/posix/thread-posix.h" #else @@ -216,9 +218,9 @@ inline static bool thread_is_interrupted(threadobject *t) a blocking system call is interrupted. The mutex ensures that it will see the correct value for the interrupted flag. */ - mutex_lock(&t->waitmutex); + Mutex_lock(t->waitmutex); interrupted = t->interrupted; - mutex_unlock(&t->waitmutex); + Mutex_unlock(t->waitmutex); return interrupted; } @@ -235,13 +237,13 @@ inline static bool thread_is_interrupted(threadobject *t) inline static void thread_set_interrupted(threadobject *t, bool interrupted) { - mutex_lock(&t->waitmutex); + Mutex_lock(t->waitmutex); /* Set interrupted flag. */ t->interrupted = interrupted; - mutex_unlock(&t->waitmutex); + Mutex_unlock(t->waitmutex); } diff --git a/src/threads/threadlist.c b/src/threads/threadlist.c index 8b7d92e3e..29f192afd 100644 --- a/src/threads/threadlist.c +++ b/src/threads/threadlist.c @@ -29,7 +29,7 @@ #include "mm/memory.h" -#include "threads/mutex.h" +#include "threads/mutex.hpp" #include "threads/threadlist.h" #include "threads/thread.h" @@ -40,7 +40,7 @@ /* global variables ***********************************************************/ -static mutex_t threadlist_mutex; /* global mutex for the thread list */ +static Mutex* threadlist_mutex; /* global mutex for the thread list */ static list_t *list_thread; /* global threads list */ static list_t *list_thread_free; /* global free threads list */ @@ -65,7 +65,7 @@ void threadlist_init(void) /* Initialize the thread list mutex. */ - mutex_init(&threadlist_mutex); + threadlist_mutex = Mutex_new(); /* Initialize the thread lists. */ @@ -88,7 +88,7 @@ void threadlist_init(void) void threadlist_lock(void) { - mutex_lock(&threadlist_mutex); + Mutex_lock(threadlist_mutex); } @@ -100,7 +100,7 @@ void threadlist_lock(void) void threadlist_unlock(void) { - mutex_unlock(&threadlist_mutex); + Mutex_unlock(threadlist_mutex); } diff --git a/src/vm/vm.c b/src/vm/vm.c index 1dabfee6f..6c192e277 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -59,7 +59,6 @@ #include "native/vm/nativevm.h" #include "threads/lock-common.h" -#include "threads/mutex.h" #include "threads/threadlist.h" #include "threads/thread.h" @@ -1927,11 +1926,12 @@ void vm_shutdown(s4 status) } #if defined(ENABLE_JVMTI) +# error This should be a JVMTI function. /* terminate cacaodbgserver */ if (dbgcom!=NULL) { - mutex_lock(&dbgcomlock); + Mutex_lock(&dbgcomlock); dbgcom->running=1; - mutex_unlock(&dbgcomlock); + Mutex_unlock(&dbgcomlock); jvmti_cacaodbgserver_quit(); } #endif