Philipp Tomsich
Christian Thalinger
- $Id: cacaoh.c 4530 2006-02-21 09:11:53Z twisti $
+ $Id: cacaoh.c 4908 2006-05-12 16:49:50Z edwin $
*/
#if defined(NATIVE_THREADS)
threads_preinit();
#endif
- initLocks();
+ lock_init();
#endif
/* initialize the string hashtable stuff: lock (must be done
Christian Thalinger
Edwin Steiner
- $Id: headers.c 4879 2006-05-05 17:34:49Z edwin $
+ $Id: headers.c 4908 2006-05-12 16:49:50Z edwin $
*/
/* machine dependent stuff ****************************************************/
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-threadcritnode asm_criticalsections;
+critical_section_node_t asm_criticalsections;
void thread_restartcriticalsection(ucontext_t *uc) {}
#endif
Changes: Christian Thalinger
Edwin Steiner
- $Id: memory.c 4798 2006-04-20 19:18:43Z edwin $
+ $Id: memory.c 4908 2006-05-12 16:49:50Z edwin $
*/
codememlock = NEW(java_objectheader);
# if defined(NATIVE_THREADS)
- initObjectLock(codememlock);
+ lock_init_object_lock(codememlock);
# endif
#endif /* defined(USE_THREADS) */
Samuel Vinson
- $Id: jvmti.c 4892 2006-05-06 18:29:55Z motse $
+ $Id: jvmti.c 4908 2006-05-12 16:49:50Z edwin $
*/
{
int i,j,size=20;
java_objectheader **om;
- lockRecordPool* lrp;
+ lock_record_pool_t* lrp;
log_text("GetOwnedMonitorInfo called - todo: fix object mapping");
om=MNEW(java_objectheader*,size);
- pthread_mutex_lock(&pool_lock);
- lrp=global_pool;
+ pthread_mutex_lock(&lock_global_pool_lock);
+ lrp=lock_global_pool;
while (lrp != NULL) {
for (j=0; j<lrp->header.size; j++) {
- if((lrp->lr[j].ownerThread==(threadobject*)thread)&&
+ if((lrp->lr[j].owner==(threadobject*)thread)&&
(!lrp->lr[j].waiting)) {
if (i>=size) {
MREALLOC(om,java_objectheader*,size,size*2);
lrp=lrp->header.next;
}
- pthread_mutex_unlock(&pool_lock);
+ pthread_mutex_unlock(&lock_global_pool_lock);
*owned_monitors_ptr = heap_allocate(sizeof(java_objectheader*)*i,true,NULL);
memcpy(*owned_monitors_ptr,om,i*sizeof(java_objectheader*));
jobject * monitor_ptr)
{
int j;
- lockRecordPool* lrp;
+ lock_record_pool_t* lrp;
java_objectheader* monitor;
CHECK_PHASE_START
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- pthread_mutex_lock(&pool_lock);
+ pthread_mutex_lock(&lock_global_pool_lock);
- lrp=global_pool;
+ lrp=lock_global_pool;
while ((lrp != NULL)&&(monitor==NULL)) {
for (j=0; j<lrp->header.size; j++) {
- if((lrp->lr[j].ownerThread==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
+ if((lrp->lr[j].owner==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
monitor=lrp->lr[j].o;
break;
}
lrp=lrp->header.next;
}
- pthread_mutex_unlock(&pool_lock);
+ pthread_mutex_unlock(&lock_global_pool_lock);
if (monitor!=NULL) {
*monitor_ptr = heap_allocate(sizeof(java_objectheader*),true,NULL);
return JVMTI_ERROR_INVALID_MONITOR;
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- if (!threadHoldsLock((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name))
+ if (!lock_does_thread_hold_lock((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name))
return JVMTI_ERROR_NOT_MONITOR_OWNER;
- monitorExit((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name);
+ lock_monitor_exit((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name);
/* GC will clean monitor up */
#else
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
/* assure current thread owns this monitor */
- if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
+ if (!lock_does_thread_hold_lock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
return JVMTI_ERROR_NOT_MONITOR_OWNER;
builtin_monitorexit((java_objectheader*)monitor->name);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
/* assure current thread owns this monitor */
- if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
+ if (!lock_does_thread_hold_lock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
return JVMTI_ERROR_NOT_MONITOR_OWNER;
- wait_cond_for_object(&monitor->name->header, millis,0);
+ lock_wait_for_object(&monitor->name->header, millis,0);
if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
return JVMTI_ERROR_INTERRUPT;
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
/* assure current thread owns this monitor */
- if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
+ if (!lock_does_thread_hold_lock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
return JVMTI_ERROR_NOT_MONITOR_OWNER;
- signal_cond_for_object((java_objectheader*)&monitor->name);
+ lock_notify_object((java_objectheader*)&monitor->name);
#else
log_text ("RawMonitorNotify not supported");
#endif
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
/* assure current thread owns this monitor */
- if (!threadHoldsLock((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name))
+ if (!lock_does_thread_hold_lock((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name))
return JVMTI_ERROR_NOT_MONITOR_OWNER;
- broadcast_cond_for_object((java_objectheader*)&monitor->name);
+ lock_notify_all_object((java_objectheader*)&monitor->name);
#else
log_text ("RawMonitorNotifyAll not supported");
#endif
Changes:
- $Id: gennativetable.c 4879 2006-05-05 17:34:49Z edwin $
+ $Id: gennativetable.c 4908 2006-05-12 16:49:50Z edwin $
*/
#if defined(NATIVE_THREADS)
threads_preinit();
#endif
- initLocks();
+ lock_init();
#endif
/* initialize the string hashtable stuff: lock (must be done
Changes: Joseph Wenninger
Christian Thalinger
- $Id: VMObject.c 4550 2006-03-01 17:00:33Z twisti $
+ $Id: VMObject.c 4908 2006-05-12 16:49:50Z edwin $
*/
MCOPY(new, this, u1, size);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- initObjectLock((java_objectheader *) new);
+ lock_init_object_lock((java_objectheader *) new);
#endif
return new;
MCOPY(new, this, u1, c->instancesize);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- initObjectLock((java_objectheader *) new);
+ lock_init_object_lock((java_objectheader *) new);
#endif
return new;
JNIEXPORT void JNICALL Java_java_lang_VMObject_notify(JNIEnv *env, jclass clazz, java_lang_Object *this)
{
#if defined(USE_THREADS)
- signal_cond_for_object(&this->header);
+ lock_notify_object(&this->header);
#endif
}
JNIEXPORT void JNICALL Java_java_lang_VMObject_notifyAll(JNIEnv *env, jclass clazz, java_lang_Object *this)
{
#if defined(USE_THREADS)
- broadcast_cond_for_object(&this->header);
+ lock_notify_all_object(&this->header);
#endif
}
JNIEXPORT void JNICALL Java_java_lang_VMObject_wait(JNIEnv *env, jclass clazz, java_lang_Object *o, s8 ms, s4 ns)
{
#if defined(USE_THREADS)
- wait_cond_for_object(&o->header, ms, ns);
+ lock_wait_for_object(&o->header, ms, ns);
#endif
}
Changes: Joseph Wenninger
Christian Thalinger
- $Id: VMThread.c 4550 2006-03-01 17:00:33Z twisti $
+ $Id: VMThread.c 4908 2006-05-12 16:49:50Z edwin $
*/
JNIEXPORT s4 JNICALL Java_java_lang_VMThread_holdsLock(JNIEnv *env, jclass clazz, java_lang_Object* o)
{
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- return threadHoldsLock((threadobject*) THREADOBJECT,
+ return lock_does_thread_hold_lock((threadobject*) THREADOBJECT,
(java_objectheader *) o);
#else
/* I don't know how to find out [stefan] */
* Init the tables.
*/
void
-initLocks (void)
+lock_init (void)
{
int i;
* Wait for the condition of an object to be signalled
*/
void
-wait_cond_for_object (java_objectheader *obj, s8 time, s4 par3)
+lock_wait_for_object (java_objectheader *obj, s8 time, s4 par3)
{
iCv *condition;
mutexHashEntry *mutexEntry;
* Signal the condition of an object
*/
void
-signal_cond_for_object (java_objectheader *obj)
+lock_notify_object (java_objectheader *obj)
{
iCv *condition;
* Broadcast the condition of an object.
*/
void
-broadcast_cond_for_object (java_objectheader *obj)
+lock_notify_all_object (java_objectheader *obj)
{
intsDisable();
- internal_broadcast_cond_for_object(obj);
+ internal_lock_notify_all_object(obj);
intsRestore();
}
* Internal: Broadcast the condition of an object.
*/
void
-internal_broadcast_cond_for_object (java_objectheader *obj)
+internal_lock_notify_all_object (java_objectheader *obj)
{
iCv *condition;
iCv condition;
} object_mutex;
-extern void initLocks (void);
+extern void lock_init (void);
mutexHashEntry* conditionLockedMutexForObject (java_objectheader *object);
* use these functions only outside critical sections (intsEnable/intsRestore).
*/
-void signal_cond_for_object (java_objectheader *obj);
-void broadcast_cond_for_object (java_objectheader *obj);
-void wait_cond_for_object (java_objectheader *obj, s8 time, s4);
+void lock_notify_object (java_objectheader *obj);
+void lock_notify_all_object (java_objectheader *obj);
+void lock_wait_for_object (java_objectheader *obj, s8 time, s4);
void lock_mutex_for_object (java_objectheader *obj);
void unlock_mutex_for_object (java_objectheader *obj);
void internal_lock_mutex_for_object (java_objectheader *obj);
void internal_unlock_mutex_for_object (java_objectheader *obj);
-void internal_broadcast_cond_for_object (java_objectheader *obj);
+void internal_lock_notify_all_object (java_objectheader *obj);
#endif /* __locks_h */
signal(SIGPIPE, SIG_IGN);
- initLocks();
+ lock_init();
for (i = 0; i < MAXTHREADS; ++i) {
contexts[i]=0;
/* Notify on the object just in case anyone is waiting */
internal_lock_mutex_for_object(&tid->header);
- internal_broadcast_cond_for_object(&tid->header);
+ internal_lock_notify_all_object(&tid->header);
internal_unlock_mutex_for_object(&tid->header);
/* Remove thread from live list to it can be garbaged */
##
## Authors: Christian Thalinger
##
-## Changes:
+## Changes: Edwin Steiner
##
-## $Id: Makefile.am 4563 2006-03-06 13:03:05Z twisti $
+## $Id: Makefile.am 4908 2006-05-12 16:49:50Z edwin $
## Process this file with automake to produce Makefile.in
noinst_LTLIBRARIES = libthreads.la
libthreads_la_SOURCES = \
+ critical.c \
+ critical.h \
+ lock.c \
+ lock.h \
threads.c \
threads.h
--- /dev/null
+/* src/threads/native/critical.c - restartable critical sections
+
+ Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
+
+ 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.
+
+ Contact: cacao@cacaojvm.org
+
+ Authors: Stefan Ring
+ Edwin Steiner
+
+ Changes: Christian Thalinger
+
+ $Id: threads.c 4903 2006-05-11 12:48:43Z edwin $
+
+*/
+
+#include "config.h"
+#include "vm/types.h"
+
+#include <stddef.h>
+
+#include "threads/native/critical.h"
+#include "vm/jit/asmpart.h"
+#include "toolbox/avl.h"
+
+/* the AVL tree containing the critical sections */
+
+static avl_tree *criticaltree;
+
+/* prototypes *****************************************************************/
+
+static s4 critical_compare(const void *pa, const void *pb);
+static void critical_register_asm_critical_sections(void);
+
+
+/* critical_init ***************************************************************
+
+ Init global data structures.
+
+*******************************************************************************/
+
+void critical_init(void)
+{
+ criticaltree = avl_create(&critical_compare);
+
+ critical_register_asm_critical_sections();
+}
+
+/* critical_compare ************************************************************
+
+ Comparison function for AVL tree of critical section.
+
+ IN:
+ pa...............first node
+ pb...............second node
+
+ RETURN VALUE:
+ -1, 0, or +1
+
+*******************************************************************************/
+
+static s4 critical_compare(const void *pa, const void *pb)
+{
+ const critical_section_node_t *na = pa;
+ const critical_section_node_t *nb = pb;
+
+ if (na->mcodebegin < nb->mcodebegin)
+ return -1;
+ if (na->mcodebegin > nb->mcodebegin)
+ return 1;
+ return 0;
+}
+
+
+/* critical_find ***************************************************************
+
+ Find the critical region the given pc is in.
+
+ IN:
+ mcodeptr.........PC
+
+ OUT:
+ pointer to critical region node, or
+ NULL if critical region was not found.
+
+*******************************************************************************/
+
+static const critical_section_node_t *critical_find(u1 *mcodeptr)
+{
+ avl_node *n;
+ const critical_section_node_t *m;
+
+ n = criticaltree->root;
+ m = NULL;
+
+ if (!n)
+ return NULL;
+
+ for (;;) {
+ const critical_section_node_t *d = n->data;
+
+ if (mcodeptr == d->mcodebegin)
+ return d;
+
+ if (mcodeptr < d->mcodebegin) {
+ if (n->childs[0]) {
+ n = n->childs[0];
+ }
+ else {
+ return m;
+ }
+ }
+ else {
+ if (n->childs[1]) {
+ m = n->data;
+ n = n->childs[1];
+ }
+ else {
+ return n->data;
+ }
+ }
+ }
+}
+
+
+/* critical_register_critical_section ******************************************
+
+ Register a critical section.
+
+ IN:
+ n................node for the critical section
+
+*******************************************************************************/
+
+void critical_register_critical_section(critical_section_node_t *n)
+{
+ avl_insert(criticaltree, n);
+}
+
+
+/* critical_find_restart_point *************************************************
+
+ Find a restart point for the given PC, in case it is in a critical section.
+
+ IN:
+ mcodeptr.........PC
+
+ OUT:
+ PC of the restart point, or
+ NULL if the given mcodeptr is not in a critical section
+
+*******************************************************************************/
+
+u1 *critical_find_restart_point(u1 *mcodeptr)
+{
+ const critical_section_node_t *n = critical_find(mcodeptr);
+
+ /* XXX should we check >= n->mcodebegin */
+ return (n && mcodeptr < n->mcodeend && mcodeptr > n->mcodebegin) ? n->mcoderestart : NULL;
+}
+
+
+/* critical_register_asm_critical_sections *************************************
+
+ Register critical sections defined in the array asm_criticalsections.
+
+*******************************************************************************/
+
+static void critical_register_asm_critical_sections(void)
+{
+ /* XXX TWISTI: this is just a quick hack */
+#if defined(ENABLE_JIT)
+ critical_section_node_t *n = &asm_criticalsections;
+
+ while (n->mcodebegin)
+ critical_register_critical_section(n++);
+#endif
+}
+
+
+/*
+ * 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:
+ */
--- /dev/null
+/* src/threads/native/critical.h - restartable critical sections
+
+ Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
+
+ 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.
+
+ Contact: cacao@cacaojvm.org
+
+ Authors: Stefan Ring
+ Edwin Steiner
+
+ Changes: Christian Thalinger
+
+ $Id: threads.h 4866 2006-05-01 21:40:38Z edwin $
+
+*/
+
+
+#ifndef _CRITICAL_H
+#define _CRITICAL_H
+
+#include "config.h"
+
+#include <ucontext.h>
+
+/* This must not be changed, it is used in asm_criticalsections! */
+
+typedef struct {
+ u1 *mcodebegin;
+ u1 *mcodeend;
+ u1 *mcoderestart;
+} critical_section_node_t;
+
+void critical_init(void);
+
+void critical_register_critical_section(critical_section_node_t *);
+
+u1 *critical_find_restart_point(u1*);
+
+/* this is a machine dependent functions (src/vm/jit/$(ARCH_DIR)/md.c) */
+void thread_restartcriticalsection(ucontext_t *);
+
+#endif /* _CRITICAL_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:
+ */
--- /dev/null
+/* src/threads/native/lock.c - lock implementation
+
+ Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
+
+ 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.
+
+ Contact: cacao@cacaojvm.org
+
+ Authors: Stefan Ring
+
+ Changes: Christian Thalinger
+ Edwin Steiner
+
+ $Id: threads.c 4903 2006-05-11 12:48:43Z edwin $
+
+*/
+
+
+#include "config.h"
+
+/* XXX cleanup these includes */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <time.h>
+#include <errno.h>
+
+#include <pthread.h>
+#include <semaphore.h>
+
+#include "vm/types.h"
+
+#include "arch.h"
+
+#ifndef USE_MD_THREAD_STUFF
+#include "machine-instr.h"
+#else
+#include "threads/native/generic-primitives.h"
+#endif
+
+#include "mm/boehm.h"
+#include "mm/memory.h"
+#include "native/native.h"
+#include "native/include/java_lang_Object.h"
+#include "native/include/java_lang_Throwable.h"
+#include "native/include/java_lang_Thread.h"
+#include "native/include/java_lang_ThreadGroup.h"
+#include "native/include/java_lang_VMThread.h"
+#include "threads/native/threads.h"
+#include "toolbox/avl.h"
+#include "toolbox/logging.h"
+#include "vm/builtin.h"
+#include "vm/exceptions.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/stringlocal.h"
+#include "vm/vm.h"
+#include "vm/jit/asmpart.h"
+
+#if !defined(__DARWIN__)
+#if defined(__LINUX__)
+#define GC_LINUX_THREADS
+#elif defined(__MIPS__)
+#define GC_IRIX_THREADS
+#endif
+#include "boehm-gc/include/gc.h"
+#endif
+
+#ifdef USE_MD_THREAD_STUFF
+pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+
+/******************************************************************************/
+/* MACROS */
+/******************************************************************************/
+
+#define INITIALLOCKRECORDS 8
+
+#define GRAB_LR(lr,t) \
+ if (lr->owner != t) { \
+ lr = lr->incharge; \
+ }
+
+#define CHECK_MONITORSTATE(lr,t,mo,a) \
+ if (lr->o != mo || lr->owner != t) { \
+ *exceptionptr = new_illegalmonitorstateexception(); \
+ a; \
+ }
+
+
+/******************************************************************************/
+/* GLOBAL VARIABLES */
+/******************************************************************************/
+
+/* unlocked dummy record - avoids NULL checks */
+static lock_record_t *dummyLR;
+
+pthread_mutex_t lock_global_pool_lock;
+lock_record_pool_t *lock_global_pool;
+
+
+/* lock_init *******************************************************************
+
+ Initialize global data for locking.
+
+*******************************************************************************/
+
+void lock_init(void)
+{
+ pthread_mutex_init(&lock_global_pool_lock, NULL);
+
+ /* Every newly created object's monitorPtr points here so we save
+ a check against NULL */
+
+ dummyLR = NEW(lock_record_t);
+ dummyLR->o = NULL;
+ dummyLR->owner = NULL;
+ dummyLR->waiting = NULL;
+ dummyLR->incharge = dummyLR;
+}
+
+
+/* lock_record_init ************************************************************
+
+ Initialize a lock record.
+
+ IN:
+ r............the lock record to initialize
+ t............will become the owner
+
+*******************************************************************************/
+
+static void lock_record_init(lock_record_t *r, threadobject *t)
+{
+ r->lockCount = 1;
+ r->owner = t;
+ r->queuers = 0;
+ r->o = NULL;
+ r->waiter = NULL;
+ r->incharge = (lock_record_t *) &dummyLR;
+ r->waiting = NULL;
+ threads_sem_init(&r->queueSem, 0, 0);
+ pthread_mutex_init(&r->resolveLock, NULL);
+ pthread_cond_init(&r->resolveWait, NULL);
+}
+
+
+/* lock_init_thread_lock_record_pool *******************************************
+
+ Initialize the lock record pool(s) for a thread.
+
+ IN:
+ thread.......the thread
+
+*******************************************************************************/
+
+void lock_init_thread_lock_record_pool(threadobject *thread)
+{
+ thread->ee.firstLR = NULL;
+ thread->ee.lrpool = NULL;
+ thread->ee.numlr = 0;
+}
+
+
+/* lock_record_alloc_new_pool **************************************************
+
+ Get a new lock record pool from the memory allocator.
+
+ IN:
+ thread.......the thread that will own the lock records
+ size.........number of lock records in the pool to allocate
+
+ RETURN VALUE:
+ the new lock record pool, with initialized lock records
+
+*******************************************************************************/
+
+static lock_record_pool_t *lock_record_alloc_new_pool(threadobject *thread, int size)
+{
+ lock_record_pool_t *p = mem_alloc(sizeof(lock_record_pool_header_t)
+ + sizeof(lock_record_t) * size);
+ int i;
+
+ p->header.size = size;
+ for (i=0; i<size; i++) {
+ lock_record_init(&p->lr[i], thread);
+ p->lr[i].nextFree = &p->lr[i+1];
+ }
+ p->lr[i-1].nextFree = NULL;
+ return p;
+}
+
+
+/* lock_record_alloc_pool ******************************************************
+
+ Allocate a lock record pool. The pool is either taken from the global free
+ list or requested from the memory allocator.
+
+ IN:
+ thread.......the thread that will own the lock records
+ size.........number of lock records in the pool to allocate
+
+ RETURN VALUE:
+ the new lock record pool, with initialized lock records
+
+*******************************************************************************/
+
+static lock_record_pool_t *lock_record_alloc_pool(threadobject *t, int size)
+{
+ pthread_mutex_lock(&lock_global_pool_lock);
+ if (lock_global_pool) {
+ int i;
+ lock_record_pool_t *pool = lock_global_pool;
+ lock_global_pool = pool->header.next;
+ pthread_mutex_unlock(&lock_global_pool_lock);
+
+ for (i=0; i < pool->header.size; i++) {
+ pool->lr[i].owner = t;
+ pool->lr[i].nextFree = &pool->lr[i+1];
+ }
+ pool->lr[i-1].nextFree = NULL;
+
+ return pool;
+ }
+ pthread_mutex_unlock(&lock_global_pool_lock);
+
+ return lock_record_alloc_new_pool(t, size);
+}
+
+
+/* lock_record_free_pools ******************************************************
+
+ Free the lock record pools in the given linked list.
+
+ IN:
+ pool.........list header
+
+*******************************************************************************/
+
+void lock_record_free_pools(lock_record_pool_t *pool)
+{
+ lock_record_pool_header_t *last;
+ pthread_mutex_lock(&lock_global_pool_lock);
+ last = &pool->header;
+ while (last->next)
+ last = &last->next->header;
+ last->next = lock_global_pool;
+ lock_global_pool = pool;
+ pthread_mutex_unlock(&lock_global_pool_lock);
+}
+
+
+/* lock_record_alloc ***********************************************************
+
+ Allocate a lock record which is owned by the given thread.
+
+ IN:
+ t............the thread
+
+*******************************************************************************/
+
+static lock_record_t *lock_record_alloc(threadobject *t)
+{
+ lock_record_t *r;
+
+ assert(t);
+ r = t->ee.firstLR;
+
+ if (!r) {
+ int poolsize = t->ee.numlr ? t->ee.numlr * 2 : INITIALLOCKRECORDS;
+ lock_record_pool_t *pool = lock_record_alloc_pool(t, poolsize);
+ pool->header.next = t->ee.lrpool;
+ t->ee.lrpool = pool;
+ r = &pool->lr[0];
+ t->ee.numlr += pool->header.size;
+ }
+
+ t->ee.firstLR = r->nextFree;
+#ifndef NDEBUG
+ r->nextFree = NULL; /* in order to find invalid uses of nextFree */
+#endif
+ return r;
+}
+
+
+/* lock_record_recycle *********************************************************
+
+ Recycle the given lock record. It will be inserted in the appropriate
+ free list.
+
+ IN:
+ t............the owner
+ r............lock record to recycle
+
+*******************************************************************************/
+
+static inline void lock_record_recycle(threadobject *t, lock_record_t *r)
+{
+ assert(t);
+ assert(r);
+ assert(r->owner == t);
+ assert(r->nextFree == NULL);
+
+ r->nextFree = t->ee.firstLR;
+ t->ee.firstLR = r;
+}
+
+
+/* lock_init_object_lock *******************************************************
+
+ Initialize the monitor pointer of the given object. The monitor gets
+ initialized to an unlocked state.
+
+*******************************************************************************/
+
+void lock_init_object_lock(java_objectheader *o)
+{
+ assert(o);
+
+ o->monitorPtr = dummyLR;
+}
+
+
+/* lock_get_initial_lock_word **************************************************
+
+ Returns the global dummy monitor lock record. The pointer is
+ required in the code generator to set up a virtual
+ java_objectheader for code patch locking.
+
+*******************************************************************************/
+
+lock_record_t *lock_get_initial_lock_word(void)
+{
+ return dummyLR;
+}
+
+
+/* lock_queue_on_lock_record ***************************************************
+
+ Suspend the current thread and queue it on the given lock record.
+
+*******************************************************************************/
+
+static void lock_queue_on_lock_record(lock_record_t *lr, java_objectheader *o)
+{
+ atomic_add(&lr->queuers, 1);
+ MEMORY_BARRIER_AFTER_ATOMIC();
+
+ if (lr->o == o)
+ threads_sem_wait(&lr->queueSem);
+
+ atomic_add(&lr->queuers, -1);
+}
+
+
+/* lock_record_release *********************************************************
+
+ Release the lock held by the given lock record. Threads queueing on the
+ semaphore of the record will be woken up.
+
+*******************************************************************************/
+
+static void lock_record_release(lock_record_t *lr)
+{
+ int q;
+ lr->o = NULL;
+ MEMORY_BARRIER();
+ q = lr->queuers;
+ while (q--)
+ threads_sem_post(&lr->queueSem);
+}
+
+
+static inline void lock_handle_waiter(lock_record_t *newlr,
+ lock_record_t *curlr,
+ java_objectheader *o)
+{
+ /* if the current lock record is used for waiting on the object */
+ /* `o`, then record it as a waiter in the new lock record */
+
+ if (curlr->waiting == o)
+ newlr->waiter = curlr;
+}
+
+
+/* lock_monitor_enter ****************************************************************
+
+ Acquire the monitor of the given object. If the current thread already
+ owns the monitor, the lock counter is simply increased.
+
+ This function blocks until it can acquire the monitor.
+
+ IN:
+ t............the current thread
+ o............the object of which to enter the monitor
+
+ RETURN VALUE:
+ the new lock record of the object when it has been entered
+
+*******************************************************************************/
+
+lock_record_t *lock_monitor_enter(threadobject *t, java_objectheader *o)
+{
+ for (;;) {
+ lock_record_t *lr = o->monitorPtr;
+ if (lr->o != o) {
+ /* the lock record does not lock this object */
+ lock_record_t *nlr;
+ lock_record_t *mlr;
+
+ /* allocate a new lock record for this object */
+ mlr = lock_record_alloc(t);
+ mlr->o = o;
+
+ /* check if it is the same record the object refered to earlier */
+ if (mlr == lr) {
+ MEMORY_BARRIER();
+ nlr = o->monitorPtr;
+ if (nlr == lr) {
+ /* the object still refers to the same lock record */
+ /* got it! */
+ lock_handle_waiter(mlr, lr, o);
+ return mlr;
+ }
+ }
+ else {
+ /* no, it's another lock record */
+ /* if we don't own the old record, set incharge XXX */
+ if (lr->owner != t)
+ mlr->incharge = lr;
+
+ /* if the object still refers to lr, replace it by the new mlr */
+ MEMORY_BARRIER_BEFORE_ATOMIC();
+ nlr = (lock_record_t *) compare_and_swap((long*) &o->monitorPtr, (long) lr, (long) mlr);
+ }
+
+ if (nlr == lr) {
+ /* we swapped the new record in successfully */
+ if (mlr == lr || lr->o != o) {
+ /* the old lock record is the same as the new one, or */
+ /* it locks another object. */
+ /* got it! */
+ lock_handle_waiter(mlr, lr, o);
+ return mlr;
+ }
+ /* lr locks the object, we have to wait */
+ while (lr->o == o)
+ lock_queue_on_lock_record(lr, o);
+
+ /* got it! */
+ lock_handle_waiter(mlr, lr, o);
+ return mlr;
+ }
+
+ /* forget this mlr lock record, wait on nlr and try again */
+ lock_record_release(mlr);
+ lock_record_recycle(t, mlr);
+ lock_queue_on_lock_record(nlr, o);
+ }
+ else {
+ /* the lock record is for the object we want */
+
+ if (lr->owner == t) {
+ /* we own it already, just recurse */
+ lr->lockCount++;
+ return lr;
+ }
+
+ /* it's locked. we wait and then try again */
+ lock_queue_on_lock_record(lr, o);
+ }
+ }
+}
+
+
+/* lock_wake_waiters ********************************************************
+
+ For each lock record in the given waiter list, post the queueSem
+ once for each queuer of the lock record.
+
+ IN:
+ lr...........the head of the waiter list
+
+*******************************************************************************/
+
+static void lock_wake_waiters(lock_record_t *lr)
+{
+ lock_record_t *tmplr;
+ s4 q;
+
+ /* move it to a local variable (Stefan commented this especially.
+ * Might be important somehow...) */
+
+ tmplr = lr;
+
+ do {
+ q = tmplr->queuers;
+
+ while (q--)
+ threads_sem_post(&tmplr->queueSem);
+
+ tmplr = tmplr->waiter;
+ } while (tmplr != NULL && tmplr != lr); /* this breaks cycles to lr */
+}
+
+
+/* lock_monitor_exit *****************************************************************
+
+ Decrement the counter of a (currently owned) monitor. If the counter
+ reaches zero, release the monitor.
+
+ If the current thread is not the owner of the monitor, an
+ IllegalMonitorState exception is thrown.
+
+ IN:
+ t............the current thread
+ o............the object of which to exit the monitor
+
+ RETURN VALUE:
+ true.........everything ok,
+ false........an exception has been thrown
+
+*******************************************************************************/
+
+bool lock_monitor_exit(threadobject *t, java_objectheader *o)
+{
+ lock_record_t *lr;
+
+ lr = o->monitorPtr;
+ GRAB_LR(lr, t);
+ CHECK_MONITORSTATE(lr, t, o, return false);
+
+ /* { the current thread `t` owns the lock record `lr` on object `o` } */
+
+ if (lr->lockCount > 1) {
+ /* we had locked this one recursively. just decrement, it will */
+ /* still be locked. */
+ lr->lockCount--;
+ return true;
+ }
+
+ /* we are going to unlock and recycle this lock record */
+
+ if (lr->waiter) {
+ lock_record_t *wlr = lr->waiter;
+ if (o->monitorPtr != lr ||
+ (void*) compare_and_swap((long*) &o->monitorPtr, (long) lr, (long) wlr) != lr)
+ {
+ lock_record_t *nlr = o->monitorPtr;
+ assert(nlr->waiter == NULL);
+ nlr->waiter = wlr; /* XXX is it ok to overwrite the nlr->waiter field like that? */
+ STORE_ORDER_BARRIER();
+ }
+ else {
+ lock_wake_waiters(wlr);
+ }
+ lr->waiter = NULL;
+ }
+
+ /* unlock and throw away this lock record */
+ lock_record_release(lr);
+ lock_record_recycle(t, lr);
+ return true;
+}
+
+
+/* lock_record_remove_waiter *******************************************************
+
+ Remove a waiter lock record from the waiter list of the given lock record
+
+ IN:
+ lr...........the lock record holding the waiter list
+ toremove.....the record to remove from the list
+
+*******************************************************************************/
+
+static void lock_record_remove_waiter(lock_record_t *lr,
+ lock_record_t *toremove)
+{
+ do {
+ if (lr->waiter == toremove) {
+ lr->waiter = toremove->waiter;
+ break;
+ }
+ lr = lr->waiter;
+ } while (lr); /* XXX need to break cycle? */
+}
+
+
+/* lock_monitor_wait *****************************************************************
+
+ Wait on an object for a given (maximum) amount of time.
+
+ IN:
+ t............the current thread
+ o............the object
+ millis.......milliseconds of timeout
+ nanos........nanoseconds of timeout
+
+ PRE-CONDITION:
+ The current thread must be the owner of the object's monitor.
+
+*******************************************************************************/
+
+void lock_monitor_wait(threadobject *t, java_objectheader *o, s8 millis, s4 nanos)
+{
+ bool wasinterrupted;
+ lock_record_t *newlr;
+ lock_record_t *lr;
+
+ lr = o->monitorPtr;
+ GRAB_LR(lr, t);
+ CHECK_MONITORSTATE(lr, t, o, return);
+
+ /* { the thread t owns the lock record lr on the object o } */
+
+ /* wake threads waiting on this record XXX why? */
+
+ if (lr->waiter)
+ lock_wake_waiters(lr->waiter);
+
+ /* mark the lock record as "waiting on object o" */
+
+ lr->waiting = o;
+ STORE_ORDER_BARRIER();
+
+ /* unlock this record */
+
+ lock_record_release(lr);
+
+ /* wait until notified/interrupted/timed out */
+
+ wasinterrupted = threads_wait_with_timeout_relative(t, millis, nanos);
+
+ /* re-enter the monitor */
+
+ newlr = lock_monitor_enter(t, o);
+
+ /* we are no longer waiting */
+
+ lock_record_remove_waiter(newlr, lr);
+ newlr->lockCount = lr->lockCount;
+
+ /* recylce the old lock record */
+
+ lr->lockCount = 1;
+ lr->waiting = NULL;
+ lr->waiter = NULL;
+ lock_record_recycle(t, lr);
+
+ /* if we have been interrupted, throw the appropriate exception */
+
+ if (wasinterrupted)
+ *exceptionptr = new_exception(string_java_lang_InterruptedException);
+}
+
+
+/* lock_monitor_notify **************************************************************
+
+ Notify one thread or all threads waiting on the given object.
+
+ IN:
+ t............the current thread
+ o............the object
+ one..........if true, only notify one thread
+
+ PRE-CONDITION:
+ The current thread must be the owner of the object's monitor.
+
+*******************************************************************************/
+
+static void lock_monitor_notify(threadobject *t, java_objectheader *o, bool one)
+{
+ lock_record_t *lr;
+ lock_record_t *wlr;
+ threadobject *wthread;
+
+ lr = o->monitorPtr;
+ GRAB_LR(lr, t);
+ CHECK_MONITORSTATE(lr, t, o, return);
+
+ /* { the thread t owns the lock record lr on the object o } */
+
+ /* for each waiter: */
+
+ for (wlr = lr->waiter; wlr; wlr = wlr->waiter) {
+
+ /* signal the waiting thread */
+
+ wthread = wlr->owner;
+ pthread_mutex_lock(&wthread->waitLock);
+ if (wthread->isSleeping)
+ pthread_cond_signal(&wthread->waitCond);
+ wthread->signaled = true;
+ pthread_mutex_unlock(&wthread->waitLock);
+
+ /* if we should only wake one, we are done */
+
+ if (one)
+ break;
+ }
+}
+
+
+/* lock_does_thread_hold_lock **************************************************
+
+ Return true if the given thread owns the monitor of the given object.
+
+ IN:
+ t............the thread
+ o............the object
+
+ RETURN VALUE:
+ true, if the thread is locking the object
+
+*******************************************************************************/
+
+bool lock_does_thread_hold_lock(threadobject *t, java_objectheader *o)
+{
+ lock_record_t *lr;
+
+ lr = o->monitorPtr;
+ GRAB_LR(lr, t);
+
+ return (lr->o == o) && (lr->owner == t);
+}
+
+
+/* lock_wait_for_object ********************************************************
+
+ Wait for the given object.
+
+ IN:
+ o............the object
+ millis.......milliseconds to wait
+ nanos........nanoseconds to wait
+
+*******************************************************************************/
+
+void lock_wait_for_object(java_objectheader *o, s8 millis, s4 nanos)
+{
+ threadobject *t = (threadobject*) THREADOBJECT;
+ lock_monitor_wait(t, o, millis, nanos);
+}
+
+
+/* lock_notify_object **********************************************************
+
+ Notify one thread waiting on the given object.
+
+ IN:
+ o............the object
+
+*******************************************************************************/
+
+void lock_notify_object(java_objectheader *o)
+{
+ threadobject *t = (threadobject*) THREADOBJECT;
+ lock_monitor_notify(t, o, true);
+}
+
+
+/* lock_notify_all_object ******************************************************
+
+ Notify all threads waiting on the given object.
+
+ IN:
+ o............the object
+
+*******************************************************************************/
+
+void lock_notify_all_object(java_objectheader *o)
+{
+ threadobject *t = (threadobject*) THREADOBJECT;
+ lock_monitor_notify(t, o, false);
+}
+
+/*
+ * 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:
+ */
--- /dev/null
+/* src/threads/native/lock.h - lock implementation
+
+ Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
+
+ 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.
+
+ Contact: cacao@cacaojvm.org
+
+ Authors: Stefan Ring
+
+ Changes: Christian Thalinger
+ Edwin Steiner
+
+ $Id: threads.h 4866 2006-05-01 21:40:38Z edwin $
+
+*/
+
+
+#ifndef _LOCK_H
+#define _LOCK_H
+
+#include "config.h"
+#include "vm/types.h"
+
+/* XXX Darwin */
+#include <semaphore.h>
+
+#include "vm/global.h"
+
+/* typedefs *******************************************************************/
+
+typedef struct lock_execution_env_t lock_execution_env_t;
+typedef struct lock_record_t lock_record_t;
+typedef struct lock_record_pool_header_t lock_record_pool_header_t;
+typedef struct lock_record_pool_t lock_record_pool_t;
+
+
+/* lock_execution_env_t ********************************************************
+
+ Execution environment. Contains the lock record freelist and pools.
+
+*******************************************************************************/
+
+struct lock_execution_env_t {
+ lock_record_t *firstLR;
+ lock_record_pool_t *lrpool;
+ int numlr;
+};
+
+
+/* lock_record_t ***************************************************************
+
+ This is the really interesting stuff.
+ See handbook for a detailed description.
+
+*******************************************************************************/
+
+struct lock_record_t {
+ struct threadobject *owner;
+ java_objectheader *o;
+ s4 lockCount;
+ lock_record_t *nextFree;
+ s4 queuers;
+ lock_record_t *waiter;
+ lock_record_t *incharge;
+ java_objectheader *waiting;
+ sem_t queueSem;
+ pthread_mutex_t resolveLock;
+ pthread_cond_t resolveWait;
+};
+
+
+/* XXXXXXXXXXXXXXXXX ***********************************************************
+
+*******************************************************************************/
+
+struct lock_record_pool_header_t {
+ lock_record_pool_t *next;
+ int size;
+};
+
+
+/* XXXXXXXXXXXXXXXXX ***********************************************************
+
+*******************************************************************************/
+
+struct lock_record_pool_t {
+ lock_record_pool_header_t header;
+ lock_record_t lr[1];
+};
+
+void lock_init(void);
+
+lock_record_t *lock_get_initial_lock_word(void);
+
+lock_record_t *lock_monitor_enter(struct threadobject *, java_objectheader *);
+bool lock_monitor_exit(struct threadobject *, java_objectheader *);
+
+bool lock_does_thread_hold_lock(struct threadobject *t, java_objectheader *o);
+
+void lock_wait_for_object(java_objectheader *o, s8 millis, s4 nanos);
+void lock_notify_object(java_objectheader *o);
+void lock_notify_all_object(java_objectheader *o);
+
+void lock_init_object_lock(java_objectheader *);
+lock_record_t *lock_get_initial_lock_word(void);
+
+void lock_init_thread_lock_record_pool(struct threadobject *thread);
+void lock_record_free_pools(lock_record_pool_t *pool);
+
+#endif /* _LOCK_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:
+ */
Changes: Christian Thalinger
Edwin Steiner
- $Id: threads.c 4903 2006-05-11 12:48:43Z edwin $
+ $Id: threads.c 4908 2006-05-12 16:49:50Z edwin $
*/
#include "config.h"
+/* XXX cleanup these includes */
+
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "arch.h"
-#ifndef USE_MD_THREAD_STUFF
+#if !defined(USE_MD_THREAD_STUFF)
#include "machine-instr.h"
#else
#include "threads/native/generic-primitives.h"
#include "boehm-gc/include/gc.h"
#endif
-#ifdef USE_MD_THREAD_STUFF
+
+/* prototypes *****************************************************************/
+
+static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
+
+/******************************************************************************/
+/* GLOBAL VARIABLES */
+/******************************************************************************/
+
+/* the main thread */
+threadobject *mainthreadobj;
+
+#ifndef HAVE___THREAD
+pthread_key_t tkey_threadinfo;
+#else
+__thread threadobject *threadobj;
+#endif
+
+static pthread_mutex_rec_t compiler_mutex;
+
+static pthread_mutex_t threadlistlock;
+
+static pthread_mutex_t stopworldlock;
+static volatile int stopworldwhere;
+
+static sem_t suspend_ack;
+#if defined(__MIPS__)
+static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
+#endif
+
+static pthread_attr_t threadattr;
+
+#if defined(USE_MD_THREAD_STUFF)
pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
#endif
+
/******************************************************************************/
/* Recursive Mutex Implementation for Darwin */
/******************************************************************************/
-#ifdef MUTEXSIM
+#if defined(MUTEXSIM)
/* We need this for older MacOSX (10.1.x) */
-typedef struct {
- pthread_mutex_t mutex;
- pthread_t owner;
- int count;
-} pthread_mutex_rec_t;
-
-static void pthread_mutex_init_rec(pthread_mutex_rec_t *m)
+void pthread_mutex_init_rec(pthread_mutex_rec_t *m)
{
pthread_mutex_init(&m->mutex, NULL);
m->count = 0;
}
-static void pthread_mutex_destroy_rec(pthread_mutex_rec_t *m)
+void pthread_mutex_destroy_rec(pthread_mutex_rec_t *m)
{
pthread_mutex_destroy(&m->mutex);
}
-static void pthread_mutex_lock_rec(pthread_mutex_rec_t *m)
+void pthread_mutex_lock_rec(pthread_mutex_rec_t *m)
{
for (;;) {
if (!m->count)
}
}
-static void pthread_mutex_unlock_rec(pthread_mutex_rec_t *m)
+void pthread_mutex_unlock_rec(pthread_mutex_rec_t *m)
{
if (!--m->count)
pthread_mutex_unlock(&m->mutex);
}
-#else /* MUTEXSIM */
-
-#define pthread_mutex_lock_rec pthread_mutex_lock
-#define pthread_mutex_unlock_rec pthread_mutex_unlock
-#define pthread_mutex_rec_t pthread_mutex_t
+#endif /* defined(MUTEXSIM) */
-#endif /* MUTEXSIM */
/* threads_sem_init ************************************************************
abort();
}
+
/* threads_sem_wait ************************************************************
Wait for a semaphore, non-interruptible.
abort();
}
+
/* threads_sem_post ************************************************************
Increase the count of a semaphore. Checks for errors.
abort();
}
+
/* threads_set_thread_priority *************************************************
Set the priority of the given thread.
}
-static avl_tree *criticaltree;
-threadobject *mainthreadobj;
+/* compiler_lock ***************************************************************
-#ifndef HAVE___THREAD
-pthread_key_t tkey_threadinfo;
-#else
-__thread threadobject *threadobj;
-#endif
+ Enter the compiler lock.
-static pthread_mutex_rec_t compiler_mutex;
+******************************************************************************/
void compiler_lock()
{
pthread_mutex_lock_rec(&compiler_mutex);
}
-void compiler_unlock()
-{
- pthread_mutex_unlock_rec(&compiler_mutex);
-}
-static s4 criticalcompare(const void *pa, const void *pb)
-{
- const threadcritnode *na = pa;
- const threadcritnode *nb = pb;
-
- if (na->mcodebegin < nb->mcodebegin)
- return -1;
- if (na->mcodebegin > nb->mcodebegin)
- return 1;
- return 0;
-}
-
-
-static const threadcritnode *findcritical(u1 *mcodeptr)
-{
- avl_node *n;
- const threadcritnode *m;
-
- n = criticaltree->root;
- m = NULL;
-
- if (!n)
- return NULL;
+/* compiler_unlock *************************************************************
- for (;;) {
- const threadcritnode *d = n->data;
-
- if (mcodeptr == d->mcodebegin)
- return d;
-
- if (mcodeptr < d->mcodebegin) {
- if (n->childs[0]) {
- n = n->childs[0];
- }
- else {
- return m;
- }
- }
- else {
- if (n->childs[1]) {
- m = n->data;
- n = n->childs[1];
- }
- else {
- return n->data;
- }
- }
- }
-}
+ Release the compiler lock.
+******************************************************************************/
-void thread_registercritical(threadcritnode *n)
+void compiler_unlock()
{
- avl_insert(criticaltree, n);
+ pthread_mutex_unlock_rec(&compiler_mutex);
}
-u1 *thread_checkcritical(u1 *mcodeptr)
-{
- const threadcritnode *n = findcritical(mcodeptr);
- return (n && mcodeptr < n->mcodeend && mcodeptr > n->mcodebegin) ? n->mcoderestart : NULL;
-}
-static void thread_addstaticcritical()
-{
- /* XXX TWISTI: this is just a quick hack */
-#if defined(ENABLE_JIT)
- threadcritnode *n = &asm_criticalsections;
+/* lock_stopworld **************************************************************
- while (n->mcodebegin)
- thread_registercritical(n++);
-#endif
-}
+ Enter the stopworld lock, specifying why the world shall be stopped.
-static pthread_mutex_t threadlistlock;
-
-static pthread_mutex_t stopworldlock;
-volatile int stopworldwhere;
+ IN:
+ where........ 1 from within GC
+ 2 class numbering
-static sem_t suspend_ack;
-#if defined(__MIPS__)
-static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
-#endif
+******************************************************************************/
-/*
- * where - 1 from within GC
- 2 class numbering
- */
void lock_stopworld(int where)
{
pthread_mutex_lock(&stopworldlock);
stopworldwhere = where;
}
+
+/* unlock_stopworld ************************************************************
+
+ Release the stopworld lock.
+
+******************************************************************************/
+
void unlock_stopworld()
{
stopworldwhere = 0;
}
#endif
+
+/* setthreadobject *************************************************************
+
+ Set the current thread object.
+
+ IN:
+ thread.......the thread object to set
+
+*******************************************************************************/
+
#if !defined(ENABLE_JVMTI)
static void setthreadobject(threadobject *thread)
#else
return THREADOBJECT;
}
-/* unlocked dummy record - avoids NULL checks */
-static monitorLockRecord *dummyLR;
-
-static void initPools();
-
/* thread_preinit **************************************************************
pthread_key_create(&tkey_threadinfo, NULL);
#endif
setthreadobject(mainthreadobj);
- initPools();
-
- /* Every newly created object's monitorPtr points here so we save
- a check against NULL */
-
- dummyLR = NEW(monitorLockRecord);
- dummyLR->o = NULL;
- dummyLR->ownerThread = NULL;
- dummyLR->waiting = NULL;
- dummyLR->incharge = dummyLR;
/* we need a working dummyLR before initializing the critical
section tree */
- criticaltree = avl_create(&criticalcompare);
+ lock_init();
+
+ critical_init();
- thread_addstaticcritical();
threads_sem_init(&suspend_ack, 0, 0);
}
-static pthread_attr_t threadattr;
-
-static void freeLockRecordPools(lockRecordPool *);
-
-
/* threads_init ****************************************************************
Initializes the threads required by the JVM: main, finalizer.
tempthread = mainthreadobj;
- freeLockRecordPools(mainthreadobj->ee.lrpool);
+ lock_record_free_pools(mainthreadobj->ee.lrpool);
/* This is kinda tricky, we grow the java.lang.Thread object so we
can keep the execution environment there. No Thread object must
setthreadobject(mainthreadobj);
- initLocks();
+ lock_init_thread_lock_record_pool(mainthreadobj);
mainthreadobj->info.next = mainthreadobj;
mainthreadobj->info.prev = mainthreadobj;
}
+/* initThread ******************************************************************
+
+ Initialize implementation fields of a java.lang.VMThread.
+
+ IN:
+ t............the java.lang.VMThread
+
+******************************************************************************/
+
void initThread(java_lang_VMThread *t)
{
threadobject *thread = (threadobject*) t;
thread->isSleeping = false;
}
-static void initThreadLocks(threadobject *);
-
/* startupinfo *****************************************************************
/* init data structures of this thread */
- initThreadLocks(thread);
+ lock_init_thread_lock_record_pool(thread);
/* tell threads_startup_thread that we registered ourselves */
/* CAUTION: *startup becomes invalid with this! */
/* Allow lock record pools to be used by other threads. They
cannot be deleted so we'd better not waste them. */
- freeLockRecordPools(thread->ee.lrpool);
+ lock_record_free_pools(thread->ee.lrpool);
/* remove thread from thread list, do this inside a lock */
}
+/* findNonDaemon ***************************************************************
+
+ Helper function used by joinAllThreads for finding non-daemon threads
+ that are still running.
+
+*******************************************************************************/
+
/* At the end of the program, we wait for all running non-daemon threads to die
*/
return NULL;
}
+
+/* joinAllThreads **************************************************************
+
+ Join all non-daemon threads.
+
+*******************************************************************************/
+
void joinAllThreads()
{
threadobject *thread;
pthread_mutex_unlock(&threadlistlock);
}
-static void initLockRecord(monitorLockRecord *r, threadobject *t)
-{
- r->lockCount = 1;
- r->ownerThread = t;
- r->queuers = 0;
- r->o = NULL;
- r->waiter = NULL;
- r->incharge = (monitorLockRecord *) &dummyLR;
- r->waiting = NULL;
- threads_sem_init(&r->queueSem, 0, 0);
- pthread_mutex_init(&r->resolveLock, NULL);
- pthread_cond_init(&r->resolveWait, NULL);
-}
-
-void initLocks()
-{
- initThreadLocks(mainthreadobj);
-}
-
-static void initThreadLocks(threadobject *thread)
-{
- thread->ee.firstLR = NULL;
- thread->ee.lrpool = NULL;
- thread->ee.numlr = 0;
-}
-
-static lockRecordPool *allocNewLockRecordPool(threadobject *thread, int size)
-{
- lockRecordPool *p = mem_alloc(sizeof(lockRecordPoolHeader) + sizeof(monitorLockRecord) * size);
- int i;
-
- p->header.size = size;
- for (i=0; i<size; i++) {
- initLockRecord(&p->lr[i], thread);
- p->lr[i].nextFree = &p->lr[i+1];
- }
- p->lr[i-1].nextFree = NULL;
- return p;
-}
-
-#define INITIALLOCKRECORDS 8
-
-pthread_mutex_t pool_lock;
-lockRecordPool *global_pool;
-
-static void initPools()
-{
- pthread_mutex_init(&pool_lock, NULL);
-}
-
-static lockRecordPool *allocLockRecordPool(threadobject *t, int size)
-{
- pthread_mutex_lock(&pool_lock);
- if (global_pool) {
- int i;
- lockRecordPool *pool = global_pool;
- global_pool = pool->header.next;
- pthread_mutex_unlock(&pool_lock);
-
- for (i=0; i < pool->header.size; i++) {
- pool->lr[i].ownerThread = t;
- pool->lr[i].nextFree = &pool->lr[i+1];
- }
- pool->lr[i-1].nextFree = NULL;
-
- return pool;
- }
- pthread_mutex_unlock(&pool_lock);
-
- return allocNewLockRecordPool(t, size);
-}
-
-static void freeLockRecordPools(lockRecordPool *pool)
-{
- lockRecordPoolHeader *last;
- pthread_mutex_lock(&pool_lock);
- last = &pool->header;
- while (last->next)
- last = &last->next->header;
- last->next = global_pool;
- global_pool = pool;
- pthread_mutex_unlock(&pool_lock);
-}
-
-static monitorLockRecord *allocLockRecordSimple(threadobject *t)
-{
- monitorLockRecord *r;
-
- assert(t);
- r = t->ee.firstLR;
-
- if (!r) {
- int poolsize = t->ee.numlr ? t->ee.numlr * 2 : INITIALLOCKRECORDS;
- lockRecordPool *pool = allocLockRecordPool(t, poolsize);
- pool->header.next = t->ee.lrpool;
- t->ee.lrpool = pool;
- r = &pool->lr[0];
- t->ee.numlr += pool->header.size;
- }
-
- t->ee.firstLR = r->nextFree;
-#ifndef NDEBUG
- r->nextFree = NULL; /* in order to find invalid uses of nextFree */
-#endif
- return r;
-}
-
-static inline void recycleLockRecord(threadobject *t, monitorLockRecord *r)
-{
- assert(t);
- assert(r);
- assert(r->ownerThread == t);
- assert(r->nextFree == NULL);
-
- r->nextFree = t->ee.firstLR;
- t->ee.firstLR = r;
-}
-
-/* initObjectLock **************************************************************
-
- Initialize the monitor pointer of the given object. The monitor gets
- initialized to an unlocked state.
-
-*******************************************************************************/
-
-void initObjectLock(java_objectheader *o)
-{
- assert(o);
-
- o->monitorPtr = dummyLR;
-}
-
-
-/* get_dummyLR *****************************************************************
-
- Returns the global dummy monitor lock record. The pointer is
- required in the code generator to set up a virtual
- java_objectheader for code patch locking.
-
-*******************************************************************************/
-
-monitorLockRecord *get_dummyLR(void)
-{
- return dummyLR;
-}
-
-
-static void queueOnLockRecord(monitorLockRecord *lr, java_objectheader *o)
-{
- atomic_add(&lr->queuers, 1);
- MEMORY_BARRIER_AFTER_ATOMIC();
-
- if (lr->o == o)
- threads_sem_wait(&lr->queueSem);
-
- atomic_add(&lr->queuers, -1);
-}
-
-static void freeLockRecord(monitorLockRecord *lr)
-{
- int q;
- lr->o = NULL;
- MEMORY_BARRIER();
- q = lr->queuers;
- while (q--)
- threads_sem_post(&lr->queueSem);
-}
-
-static inline void handleWaiter(monitorLockRecord *newlr,
- monitorLockRecord *curlr,
- java_objectheader *o)
-{
- /* if the current lock record is used for waiting on the object */
- /* `o`, then record it as a waiter in the new lock record */
-
- if (curlr->waiting == o)
- newlr->waiter = curlr;
-}
-
-/* monitorEnter ****************************************************************
-
- Acquire the monitor of the given object. If the current thread already
- owns the monitor, the lock counter is simply increased.
-
- This function blocks until it can acquire the monitor.
-
- IN:
- t............the current thread
- o............the object of which to enter the monitor
-
- RETURN VALUE:
- the new lock record of the object when it has been entered
-
-*******************************************************************************/
-
-monitorLockRecord *monitorEnter(threadobject *t, java_objectheader *o)
-{
- for (;;) {
- monitorLockRecord *lr = o->monitorPtr;
- if (lr->o != o) {
- /* the lock record does not lock this object */
- monitorLockRecord *nlr;
- monitorLockRecord *mlr;
-
- /* allocate a new lock record for this object */
- mlr = allocLockRecordSimple(t);
- mlr->o = o;
-
- /* check if it is the same record the object refered to earlier */
- if (mlr == lr) {
- MEMORY_BARRIER();
- nlr = o->monitorPtr;
- if (nlr == lr) {
- /* the object still refers to the same lock record */
- /* got it! */
- handleWaiter(mlr, lr, o);
- return mlr;
- }
- }
- else {
- /* no, it's another lock record */
- /* if we don't own the old record, set incharge XXX */
- if (lr->ownerThread != t)
- mlr->incharge = lr;
-
- /* if the object still refers to lr, replace it by the new mlr */
- MEMORY_BARRIER_BEFORE_ATOMIC();
- nlr = (monitorLockRecord *) compare_and_swap((long*) &o->monitorPtr, (long) lr, (long) mlr);
- }
-
- if (nlr == lr) {
- /* we swapped the new record in successfully */
- if (mlr == lr || lr->o != o) {
- /* the old lock record is the same as the new one, or */
- /* it locks another object. */
- /* got it! */
- handleWaiter(mlr, lr, o);
- return mlr;
- }
- /* lr locks the object, we have to wait */
- while (lr->o == o)
- queueOnLockRecord(lr, o);
-
- /* got it! */
- handleWaiter(mlr, lr, o);
- return mlr;
- }
-
- /* forget this mlr lock record, wait on nlr and try again */
- freeLockRecord(mlr);
- recycleLockRecord(t, mlr);
- queueOnLockRecord(nlr, o);
- }
- else {
- /* the lock record is for the object we want */
-
- if (lr->ownerThread == t) {
- /* we own it already, just recurse */
- lr->lockCount++;
- return lr;
- }
-
- /* it's locked. we wait and then try again */
- queueOnLockRecord(lr, o);
- }
- }
-}
-
-/* threads_wake_waiters ********************************************************
-
- For each lock record in the given waiter list, post the queueSem
- once for each queuer of the lock record.
-
- IN:
- lr...........the head of the waiter list
-
-*******************************************************************************/
-
-static void threads_wake_waiters(monitorLockRecord *lr)
-{
- monitorLockRecord *tmplr;
- s4 q;
-
- /* move it to a local variable (Stefan commented this especially.
- * Might be important somehow...) */
-
- tmplr = lr;
-
- do {
- q = tmplr->queuers;
-
- while (q--)
- threads_sem_post(&tmplr->queueSem);
-
- tmplr = tmplr->waiter;
- } while (tmplr != NULL && tmplr != lr); /* this breaks cycles to lr */
-}
-
-#define GRAB_LR(lr,t) \
- if (lr->ownerThread != t) { \
- lr = lr->incharge; \
- }
-
-#define CHECK_MONITORSTATE(lr,t,mo,a) \
- if (lr->o != mo || lr->ownerThread != t) { \
- *exceptionptr = new_illegalmonitorstateexception(); \
- a; \
- }
-
-/* monitorExit *****************************************************************
-
- Decrement the counter of a (currently owned) monitor. If the counter
- reaches zero, release the monitor.
-
- If the current thread is not the owner of the monitor, an
- IllegalMonitorState exception is thrown.
-
- IN:
- t............the current thread
- o............the object of which to exit the monitor
-
- RETURN VALUE:
- true.........everything ok,
- false........an exception has been thrown
-
-*******************************************************************************/
-
-bool monitorExit(threadobject *t, java_objectheader *o)
-{
- monitorLockRecord *lr;
-
- lr = o->monitorPtr;
- GRAB_LR(lr, t);
- CHECK_MONITORSTATE(lr, t, o, return false);
-
- /* { the current thread `t` owns the lock record `lr` on object `o` } */
-
- if (lr->lockCount > 1) {
- /* we had locked this one recursively. just decrement, it will */
- /* still be locked. */
- lr->lockCount--;
- return true;
- }
-
- /* we are going to unlock and recycle this lock record */
-
- if (lr->waiter) {
- monitorLockRecord *wlr = lr->waiter;
- if (o->monitorPtr != lr ||
- (void*) compare_and_swap((long*) &o->monitorPtr, (long) lr, (long) wlr) != lr)
- {
- monitorLockRecord *nlr = o->monitorPtr;
- assert(nlr->waiter == NULL);
- nlr->waiter = wlr; /* XXX is it ok to overwrite the nlr->waiter field like that? */
- STORE_ORDER_BARRIER();
- }
- else {
- threads_wake_waiters(wlr);
- }
- lr->waiter = NULL;
- }
-
- /* unlock and throw away this lock record */
- freeLockRecord(lr);
- recycleLockRecord(t, lr);
- return true;
-}
-
-/* threads_remove_waiter *******************************************************
-
- Remove a waiter lock record from the waiter list of the given lock record
-
- IN:
- lr...........the lock record holding the waiter list
- toremove.....the record to remove from the list
-
-*******************************************************************************/
-
-static void threads_remove_waiter(monitorLockRecord *lr,
- monitorLockRecord *toremove)
-{
- do {
- if (lr->waiter == toremove) {
- lr->waiter = toremove->waiter;
- break;
- }
- lr = lr->waiter;
- } while (lr); /* XXX need to break cycle? */
-}
/* threads_timespec_earlier ****************************************************
(tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
}
+
/* threads_current_time_is_earlier_than ****************************************
Check if the current time is earlier than the given timespec.
/* threads_wait_with_timeout ***************************************************
- Wait for the given maximum amount of time on a monitor until either
+ Wait until the given point in time on a monitor until either
we are notified, we are interrupted, or the time is up.
IN:
}
-static void calcAbsoluteTime(struct timespec *tm, s8 millis, s4 nanos)
-{
- if (millis || nanos) {
- struct timeval tv;
- long nsec;
- gettimeofday(&tv, NULL);
- tv.tv_sec += millis / 1000;
- millis %= 1000;
- nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
- tm->tv_sec = tv.tv_sec + nsec / 1000000000;
- tm->tv_nsec = nsec % 1000000000;
- }
- else {
- tm->tv_sec = 0;
- tm->tv_nsec = 0;
- }
-}
-
-/* monitorWait *****************************************************************
+/* threads_wait_with_timeout_relative ******************************************
- Wait on an object for a given (maximum) amount of time.
+ Wait for the given maximum amount of time on a monitor until either
+ we are notified, we are interrupted, or the time is up.
IN:
t............the current thread
- o............the object
- millis.......milliseconds of timeout
- nanos........nanoseconds of timeout
+ millis.......milliseconds to wait
+ nanos........nanoseconds to wait
+
+ RETURN VALUE:
+ true.........if the wait has been interrupted,
+ false........if the wait was ended by notification or timeout
- PRE-CONDITION:
- The current thread must be the owner of the object's monitor.
-
*******************************************************************************/
-void monitorWait(threadobject *t, java_objectheader *o, s8 millis, s4 nanos)
+bool threads_wait_with_timeout_relative(threadobject *t,
+ s8 millis,
+ s4 nanos)
{
- bool wasinterrupted;
struct timespec wakeupTime;
- monitorLockRecord *newlr;
- monitorLockRecord *lr;
-
- lr = o->monitorPtr;
- GRAB_LR(lr, t);
- CHECK_MONITORSTATE(lr, t, o, return);
-
- /* { the thread t owns the lock record lr on the object o } */
/* calculate the the (latest) wakeup time */
- calcAbsoluteTime(&wakeupTime, millis, nanos);
-
- /* wake threads waiting on this record XXX why? */
-
- if (lr->waiter)
- threads_wake_waiters(lr->waiter);
-
- /* mark the lock record as "waiting on object o" */
-
- lr->waiting = o;
- STORE_ORDER_BARRIER();
-
- /* unlock this record */
-
- freeLockRecord(lr);
-
- /* wait until notified/interrupted/timed out */
-
- wasinterrupted = threads_wait_with_timeout(t, &wakeupTime);
+ threads_calc_absolute_time(&wakeupTime, millis, nanos);
- /* re-enter the monitor */
+ /* wait */
- newlr = monitorEnter(t, o);
-
- /* we are no longer waiting */
-
- threads_remove_waiter(newlr, lr);
- newlr->lockCount = lr->lockCount;
-
- /* recylce the old lock record */
-
- lr->lockCount = 1;
- lr->waiting = NULL;
- lr->waiter = NULL;
- recycleLockRecord(t, lr);
-
- /* if we have been interrupted, throw the appropriate exception */
-
- if (wasinterrupted)
- *exceptionptr = new_exception(string_java_lang_InterruptedException);
+ return threads_wait_with_timeout(t, &wakeupTime);
}
-/* notifyOneOrAll **************************************************************
- Notify one thread or all threads waiting on the given object.
+/* threads_calc_absolute_time **************************************************
+
+ Calculate the absolute point in time a given number of ms and ns from now.
IN:
- t............the current thread
- o............the object
- one..........if true, only notify one thread
+ millis............milliseconds from now
+ nanos.............nanoseconds from now
+
+ OUT:
+ *tm...............receives the timespec of the absolute point in time
- PRE-CONDITION:
- The current thread must be the owner of the object's monitor.
-
*******************************************************************************/
-static void notifyOneOrAll(threadobject *t, java_objectheader *o, bool one)
+static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
{
- monitorLockRecord *lr;
- monitorLockRecord *wlr;
- threadobject *wthread;
-
- lr = o->monitorPtr;
- GRAB_LR(lr, t);
- CHECK_MONITORSTATE(lr, t, o, return);
-
- /* { the thread t owns the lock record lr on the object o } */
-
- /* for each waiter: */
-
- for (wlr = lr->waiter; wlr; wlr = wlr->waiter) {
-
- /* signal the waiting thread */
-
- wthread = wlr->ownerThread;
- pthread_mutex_lock(&wthread->waitLock);
- if (wthread->isSleeping)
- pthread_cond_signal(&wthread->waitCond);
- wthread->signaled = true;
- pthread_mutex_unlock(&wthread->waitLock);
-
- /* if we should only wake one, we are done */
-
- if (one)
- break;
+ if (millis || nanos) {
+ struct timeval tv;
+ long nsec;
+ gettimeofday(&tv, NULL);
+ tv.tv_sec += millis / 1000;
+ millis %= 1000;
+ nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
+ tm->tv_sec = tv.tv_sec + nsec / 1000000000;
+ tm->tv_nsec = nsec % 1000000000;
+ }
+ else {
+ tm->tv_sec = 0;
+ tm->tv_nsec = 0;
}
}
-/* threadHoldsLock *************************************************************
-
- Return true if the given thread owns the monitor of the given object.
-
- IN:
- t............the thread
- o............the object
-
- RETURN VALUE:
- true, if the thread is locking the object
-
-*******************************************************************************/
-
-bool threadHoldsLock(threadobject *t, java_objectheader *o)
-{
- monitorLockRecord *lr;
-
- lr = o->monitorPtr;
- GRAB_LR(lr, t);
-
- return (lr->o == o) && (lr->ownerThread == t);
-}
/* interruptThread *************************************************************
pthread_mutex_unlock(&t->waitLock);
}
+
/* interruptedThread ***********************************************************
Check if the current thread has been interrupted and reset the
return intr;
}
+
/* isInterruptedThread *********************************************************
Check if the given thread has been interrupted
return t->interrupted;
}
+
/* thread_sleep ****************************************************************
Sleep the current thread for the specified amount of time.
t = (threadobject *) THREADOBJECT;
- calcAbsoluteTime(&wakeupTime, millis, nanos);
+ threads_calc_absolute_time(&wakeupTime, millis, nanos);
wasinterrupted = threads_wait_with_timeout(t, &wakeupTime);
*exceptionptr = new_exception(string_java_lang_InterruptedException);
}
+
+/* yieldThread *****************************************************************
+
+ Yield to the scheduler.
+
+*******************************************************************************/
+
void yieldThread()
{
sched_yield();
}
-void setPriorityThread(thread *t, s4 priority)
-{
- nativethread *info = &((threadobject*) t->vmThread)->info;
- threads_set_thread_priority(info->tid, priority);
-}
-void wait_cond_for_object(java_objectheader *o, s8 millis, s4 nanos)
-{
- threadobject *t = (threadobject*) THREADOBJECT;
- monitorWait(t, o, millis, nanos);
-}
+/* setPriorityThread ***********************************************************
-void signal_cond_for_object(java_objectheader *o)
-{
- threadobject *t = (threadobject*) THREADOBJECT;
- notifyOneOrAll(t, o, true);
-}
+ Set the priority for the given java.lang.Thread.
+
+ IN:
+ t............the java.lang.Thread
+ priority.....the priority
-void broadcast_cond_for_object(java_objectheader *o)
+*******************************************************************************/
+
+void setPriorityThread(thread *t, s4 priority)
{
- threadobject *t = (threadobject*) THREADOBJECT;
- notifyOneOrAll(t, o, false);
+ nativethread *info = &((threadobject*) t->vmThread)->info;
+ threads_set_thread_priority(info->tid, priority);
}
Changes: Christian Thalinger
Edwin Steiner
- $Id: threads.h 4866 2006-05-01 21:40:38Z edwin $
+ $Id: threads.h 4908 2006-05-12 16:49:50Z edwin $
*/
#include "native/include/java_lang_VMThread.h"
#include "vm/global.h"
+#include "threads/native/lock.h"
+
#if defined(__DARWIN__)
#include <mach/mach.h>
/* typedefs *******************************************************************/
-typedef struct ExecEnvironment ExecEnvironment;
typedef struct nativethread nativethread;
typedef struct threadobject threadobject;
-typedef struct monitorLockRecord monitorLockRecord;
-typedef struct lockRecordPoolHeader lockRecordPoolHeader;
-typedef struct lockRecordPool lockRecordPool;
typedef java_lang_Thread thread;
-
-/* ExecEnvironment *************************************************************
-
- Monitor lock implementation
-
-*******************************************************************************/
-
-struct ExecEnvironment {
- monitorLockRecord *firstLR;
- lockRecordPool *lrpool;
- int numlr;
-};
-
-
struct nativethread {
threadobject *next;
threadobject *prev;
struct threadobject {
java_lang_VMThread o;
nativethread info; /* some general pthreads stuff */
- ExecEnvironment ee; /* contains our lock record pool */
+ lock_execution_env_t ee; /* contains our lock record pool */
/* these are used for the wait/notify implementation */
pthread_mutex_t waitLock;
dumpinfo dumpinfo; /* dump memory info structure */
};
-/* monitorLockRecord ***********************************************************
-
- This is the really interesting stuff.
- See handbook for a detailed description.
-
-*******************************************************************************/
-
-struct monitorLockRecord {
- threadobject *ownerThread;
- java_objectheader *o;
- s4 lockCount;
- monitorLockRecord *nextFree;
- s4 queuers;
- monitorLockRecord *waiter;
- monitorLockRecord *incharge;
- java_objectheader *waiting;
- sem_t queueSem;
- pthread_mutex_t resolveLock;
- pthread_cond_t resolveWait;
-};
-
-
-struct lockRecordPoolHeader {
- lockRecordPool *next;
- int size;
-};
-
-struct lockRecordPool {
- lockRecordPoolHeader header;
- monitorLockRecord lr[1];
-};
-
void threads_sem_init(sem_t *sem, bool shared, int value);
void threads_sem_wait(sem_t *sem);
void threads_sem_post(sem_t *sem);
-monitorLockRecord *monitorEnter(threadobject *, java_objectheader *);
-bool monitorExit(threadobject *, java_objectheader *);
-
-bool threadHoldsLock(threadobject *t, java_objectheader *o);
-
-void wait_cond_for_object(java_objectheader *o, s8 millis, s4 nanos);
-void signal_cond_for_object(java_objectheader *o);
-void broadcast_cond_for_object(java_objectheader *o);
-
void *thread_getself(void);
void threads_preinit(void);
bool threads_init(u1 *stackbottom);
-void initObjectLock(java_objectheader *);
-monitorLockRecord *get_dummyLR(void);
-void initLocks();
+void lock_init();
void initThread(java_lang_VMThread *);
/* start a thread */
void thread_sleep(s8 millis, s4 nanos);
void yieldThread();
+bool threads_wait_with_timeout_relative(threadobject *t, s8 millis, s4 nanos);
+
void setPriorityThread(thread *t, s4 priority);
void interruptThread(java_lang_VMThread *);
void setthreadobject(threadobject *thread);
#endif
-
-/* This must not be changed, it is used in asm_criticalsections */
-typedef struct {
- u1 *mcodebegin;
- u1 *mcodeend;
- u1 *mcoderestart;
-} threadcritnode;
-
-void thread_registercritical(threadcritnode *);
-u1 *thread_checkcritical(u1*);
-
-extern volatile int stopworldwhere;
extern threadobject *mainthreadobj;
-extern pthread_mutex_t pool_lock;
-extern lockRecordPool *global_pool;
-
-
void cast_stopworld();
void cast_startworld();
/* dumps all threads */
void threads_dump(void);
-/* this is a machine dependent functions (src/vm/jit/$(ARCH_DIR)/md.c) */
-void thread_restartcriticalsection(ucontext_t *);
+
+/******************************************************************************/
+/* Recursive Mutex Implementation for Darwin */
+/******************************************************************************/
+
+#if defined(MUTEXSIM)
+
+/* We need this for older MacOSX (10.1.x) */
+
+typedef struct {
+ pthread_mutex_t mutex;
+ pthread_t owner;
+ int count;
+} pthread_mutex_rec_t;
+
+void pthread_mutex_init_rec(pthread_mutex_rec_t *m);
+void pthread_mutex_destroy_rec(pthread_mutex_rec_t *m);
+void pthread_mutex_lock_rec(pthread_mutex_rec_t *m);
+void pthread_mutex_unlock_rec(pthread_mutex_rec_t *m);
+
+#else /* !defined(MUTEXSIM) */
+
+#define pthread_mutex_lock_rec pthread_mutex_lock
+#define pthread_mutex_unlock_rec pthread_mutex_unlock
+#define pthread_mutex_rec_t pthread_mutex_t
+
+#endif /* defined(MUTEXSIM) */
#endif /* _THREADS_H */
Changes:
- $Id: avl.c 4357 2006-01-22 23:33:38Z twisti $
+ $Id: avl.c 4908 2006-05-12 16:49:50Z edwin $
*/
t->lock = NEW(java_objectheader);
# if defined(NATIVE_THREADS)
- initObjectLock(t->lock);
+ lock_init_object_lock(t->lock);
# endif
#endif
calls instead of machine instructions, using the C calling
convention.
- $Id: builtin.c 4884 2006-05-05 19:13:41Z edwin $
+ $Id: builtin.c 4908 2006-05-12 16:49:50Z edwin $
*/
o->vftbl = c->vftbl;
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- initObjectLock(o);
+ lock_init_object_lock(o);
#endif
CYCLES_STATS_GET(cycles_end);
a->objheader.vftbl = arrayclass->vftbl;
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- initObjectLock(&a->objheader);
+ lock_init_object_lock(&a->objheader);
#endif
a->size = size;
CYCLES_STATS_GET(cycles_start);
CYCLES_STATS_GET(cycles_overhead);
- monitorEnter((threadobject *) THREADOBJECT, o);
+ lock_monitor_enter((threadobject *) THREADOBJECT, o);
CYCLES_STATS_GET(cycles_end);
CYCLES_STATS_COUNT(builtin_monitorenter, cycles_end - cycles_overhead);
#else /* defined(NATIVE_THREADS) */
CYCLES_STATS_GET(cycles_start);
- monitorExit((threadobject *) THREADOBJECT, o);
+ lock_monitor_exit((threadobject *) THREADOBJECT, o);
CYCLES_STATS_GET(cycles_end);
CYCLES_STATS_COUNT(builtin_monitorexit, cycles_end - cycles_start);
Christian Thalinger
Edwin Steiner
- $Id: class.c 4879 2006-05-05 17:34:49Z edwin $
+ $Id: class.c 4908 2006-05-12 16:49:50Z edwin $
*/
class_set_packagename(c);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- initObjectLock(&c->object.header);
+ lock_init_object_lock(&c->object.header);
#endif
return c;
Changes: Christian Thalinger
- $Id: classcache.c 4889 2006-05-06 00:16:11Z edwin $
+ $Id: classcache.c 4908 2006-05-12 16:49:50Z edwin $
*/
lock_hashtable_classcache = NEW(java_objectheader);
# if defined(NATIVE_THREADS)
- initObjectLock(lock_hashtable_classcache);
+ lock_init_object_lock(lock_hashtable_classcache);
# endif
#endif
Changes:
- $Id: finalizer.c 4874 2006-05-05 14:36:18Z edwin $
+ $Id: finalizer.c 4908 2006-05-12 16:49:50Z edwin $
*/
lock_finalizer_thread = NEW(java_objectheader);
# if defined(NATIVE_THREADS)
- initObjectLock(lock_finalizer_thread);
+ lock_init_object_lock(lock_finalizer_thread);
# endif
#endif
/* wait forever (0, 0) on that object till we are signaled */
- wait_cond_for_object(lock_finalizer_thread, 0, 0);
+ lock_wait_for_object(lock_finalizer_thread, 0, 0);
/* leave the lock */
/* signal the finalizer thread */
- signal_cond_for_object(lock_finalizer_thread);
+ lock_notify_object(lock_finalizer_thread);
/* leave the lock */
Joseph Wenninger
Christian Thalinger
- $Id: global.h 4854 2006-04-27 23:03:37Z twisti $
+ $Id: global.h 4908 2006-05-12 16:49:50Z edwin $
*/
struct java_objectheader { /* header for all objects */
struct _vftbl *vftbl; /* pointer to virtual function table */
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- struct monitorLockRecord *monitorPtr;
+ struct lock_record_t *monitorPtr;
#endif
};
Andreas Krall
Christian Thalinger
- $Id: hashtable.c 4900 2006-05-11 09:18:28Z twisti $
+ $Id: hashtable.c 4908 2006-05-12 16:49:50Z edwin $
*/
hash->header = NEW(java_objectheader);
- initObjectLock(hash->header);
+ lock_init_object_lock(hash->header);
# endif
#endif
Christian Ullrich
Edwin Steiner
- $Id: codegen.c 4899 2006-05-10 16:14:28Z twisti $
+ $Id: codegen.c 4908 2006-05-12 16:49:50Z edwin $
*/
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
/* create a virtual java_objectheader */
- (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
+ (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
disp = dseg_addaddress(cd, NULL); /* vftbl */
M_LDA(REG_ITMP3, REG_PV, disp);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
/* create a virtual java_objectheader */
- (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
+ (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
disp = dseg_addaddress(cd, NULL); /* vftbl */
M_LDA(REG_ITMP3, REG_PV, disp);
Changes:
- $Id: md-os.c 4357 2006-01-22 23:33:38Z twisti $
+ $Id: md-os.c 4908 2006-05-12 16:49:50Z edwin $
*/
_mc = &_uc->uc_mcontext;
- critical = thread_checkcritical((void *) _mc->mc_regs[R_PC]);
+ critical = critical_find_restart_point((void *) _mc->mc_regs[R_PC]);
if (critical)
_mc->mc_regs[R_PC] = (ptrint) critical;
Changes:
- $Id: md-os.c 4357 2006-01-22 23:33:38Z twisti $
+ $Id: md-os.c 4908 2006-05-12 16:49:50Z edwin $
*/
_mc = &_uc->uc_mcontext;
- critical = thread_checkcritical((void *) _mc->sc_pc);
+ critical = critical_find_restart_point((void *) _mc->sc_pc);
if (critical)
_mc->sc_pc = (ptrint) critical;
Changes: Christian Thalinger
Edwin Steiner
- $Id: asmpart.h 4792 2006-04-19 01:05:18Z edwin $
+ $Id: asmpart.h 4908 2006-05-12 16:49:50Z edwin $
*/
#if defined(USE_THREADS)
# if defined(NATIVE_THREADS)
# include "threads/native/threads.h"
+# include "threads/native/critical.h"
# else
# include "threads/green/threads.h"
# endif
void *asm_switchstackandcall(void *stack, void *func, void **stacktopsave, void * p);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-extern threadcritnode asm_criticalsections;
+extern critical_section_node_t asm_criticalsections;
#endif
/* code_get_sync_slot_count ****************************************************
Return the number of stack slots used for storing the synchronized object
- (and the return value around monitorExit calls) by the given code.
+ (and the return value around lock_monitor_exit calls) by the given code.
IN:
code.............the codeinfo of the code in question
memory. All functions writing values into the data area return the offset
relative the begin of the code area (start of procedure).
- $Id: codegen-common.c 4898 2006-05-10 15:51:46Z twisti $
+ $Id: codegen-common.c 4908 2006-05-12 16:49:50Z edwin $
*/
mcodelen = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- extralen = sizeof(threadcritnode) * cd->threadcritcount;
+ extralen = sizeof(critical_section_node_t) * cd->threadcritcount;
#else
extralen = 0;
#endif
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
{
- threadcritnode *n = (threadcritnode *) ((ptrint) code->mcode + alignedlen);
+ critical_section_node_t *n = (critical_section_node_t *) ((ptrint) code->mcode + alignedlen);
s4 i;
- threadcritnodetemp *nt = cd->threadcrit;
+ codegen_critical_section_t *nt = cd->threadcrit;
for (i = 0; i < cd->threadcritcount; i++) {
n->mcodebegin = (u1 *) (ptrint) code->mcode + nt->mcodebegin;
n->mcodeend = (u1 *) (ptrint) code->mcode + nt->mcodeend;
n->mcoderestart = (u1 *) (ptrint) code->mcode + nt->mcoderestart;
- thread_registercritical(n);
+ critical_register_critical_section(n);
n++;
nt = nt->next;
}
{
cd->threadcritcurrent.next = cd->threadcrit;
cd->threadcritcurrent.mcodeend = offset;
- cd->threadcrit = DNEW(threadcritnodetemp);
+ cd->threadcrit = DNEW(codegen_critical_section_t);
*(cd->threadcrit) = cd->threadcritcurrent;
cd->threadcritcount++;
}
Changes: Christian Ullrich
Edwin Steiner
- $Id: codegen-common.h 4898 2006-05-10 15:51:46Z twisti $
+ $Id: codegen-common.h 4908 2006-05-12 16:49:50Z edwin $
*/
/* forward typedefs ***********************************************************/
typedef struct codegendata codegendata;
-typedef struct threadcritnodetemp threadcritnodetemp;
+typedef struct codegen_critical_section_t codegen_critical_section_t;
#include "config.h"
/************************* critical sections *********************************/
-struct threadcritnodetemp {
- threadcritnodetemp *next;
+struct codegen_critical_section_t {
+ codegen_critical_section_t *next;
s4 mcodebegin;
s4 mcodeend;
s4 mcoderestart;
s4 exceptiontablelength; /* exceptiontable length */
exceptiontable *exceptiontable; /* the exceptiontable */
- threadcritnodetemp *threadcrit; /* List of critical code regions */
- threadcritnodetemp threadcritcurrent;
+ codegen_critical_section_t *threadcrit; /* List of critical code regions */
+ codegen_critical_section_t threadcritcurrent;
s4 threadcritcount; /* Number of critical regions */
s4 maxstack;
Christian Ullrich
Edwin Steiner
- $Id: codegen.c 4863 2006-04-30 16:17:44Z edwin $
+ $Id: codegen.c 4908 2006-05-12 16:49:50Z edwin $
*/
/* move pointer to java_objectheader onto stack */
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
+ (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
off = dseg_addaddress(cd, NULL); /* vftbl */
M_MOV_IMM(0, REG_ITMP3);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
/* create a virtual java_objectheader */
- (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
+ (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
disp = dseg_addaddress(cd, NULL); /* vftbl */
M_MOV_IMM(0, REG_ITMP3);
Changes:
- $Id: md-os.c 4357 2006-01-22 23:33:38Z twisti $
+ $Id: md-os.c 4908 2006-05-12 16:49:50Z edwin $
*/
{
void *critical;
- critical = thread_checkcritical((void *) uc->uc_mcontext.mc_eip);
+ critical = critical_find_restart_point((void *) uc->uc_mcontext.mc_eip);
if (critical)
uc->uc_mcontext.mc_eip = (ptrint) critical;
Changes:
- $Id: md-os.c 4357 2006-01-22 23:33:38Z twisti $
+ $Id: md-os.c 4908 2006-05-12 16:49:50Z edwin $
*/
{
void *critical;
- critical = thread_checkcritical((void *) uc->uc_mcontext.gregs[REG_EIP]);
+ critical = critical_find_restart_point((void *) uc->uc_mcontext.gregs[REG_EIP]);
if (critical)
uc->uc_mcontext.gregs[REG_EIP] = (ptrint) critical;
Changes:
- $Id: dynamic-super.c 4746 2006-04-11 05:10:55Z edwin $
+ $Id: dynamic-super.c 4908 2006-05-12 16:49:50Z edwin $
*/
lock_hashtable_superreuse = NEW(java_objectheader);
# if defined(NATIVE_THREADS)
- initObjectLock(lock_hashtable_patchersupers);
- initObjectLock(lock_hashtable_superreuse);
+ lock_init_object_lock(lock_hashtable_patchersupers);
+ lock_init_object_lock(lock_hashtable_superreuse);
# endif
#endif
}
This module generates MIPS machine code for a sequence of
intermediate code commands (ICMDs).
- $Id: codegen.c 4905 2006-05-11 13:43:55Z twisti $
+ $Id: codegen.c 4908 2006-05-12 16:49:50Z edwin $
*/
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
/* create a virtual java_objectheader */
- (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
+ (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
disp = dseg_addaddress(cd, NULL); /* vftbl */
M_LDA(REG_ITMP3, REG_PV, disp);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
/* order reversed because of data segment layout */
- (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
+ (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
disp = dseg_addaddress(cd, NULL); /* vftbl */
M_LDA(REG_ITMP3, REG_PV, disp);
Changes: Christian Thalinger
- $Id: md-os.c 4357 2006-01-22 23:33:38Z twisti $
+ $Id: md-os.c 4908 2006-05-12 16:49:50Z edwin $
*/
{
void *critical;
- critical = thread_checkcritical((void*) uc->uc_mcontext.gregs[CTX_EPC]);
+ critical = critical_find_restart_point((void*) uc->uc_mcontext.gregs[CTX_EPC]);
if (critical)
uc->uc_mcontext.gregs[CTX_EPC] = (ptrint) critical;
Changes: Christian Thalinger
- $Id: md-os.c 4357 2006-01-22 23:33:38Z twisti $
+ $Id: md-os.c 4908 2006-05-12 16:49:50Z edwin $
*/
_mc = &_uc->uc_mcontext;
- critical = thread_checkcritical((void *) (ptrint) _mc->pc);
+ critical = critical_find_restart_point((void *) (ptrint) _mc->pc);
if (critical)
_mc->pc = (ptrint) critical;
Christian Ullrich
Edwin Steiner
- $Id: codegen.c 4898 2006-05-10 15:51:46Z twisti $
+ $Id: codegen.c 4908 2006-05-12 16:49:50Z edwin $
*/
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
/* order reversed because of data segment layout */
- (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
+ (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
disp = dseg_addaddress(cd, NULL); /* vftbl */
M_LDA(REG_ITMP3, REG_PV, disp);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
/* order reversed because of data segment layout */
- (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
+ (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
disp = dseg_addaddress(cd, NULL); /* vftbl */
M_LDA(REG_ITMP3, REG_PV, disp);
/* wait 1 ms */
- wait_cond_for_object(lock_profile_thread, 0, 100);
+ lock_wait_for_object(lock_profile_thread, 0, 100);
/* leave the lock */
Christian Thalinger
Christian Ullrich
- $Id: stack.c 4879 2006-05-05 17:34:49Z edwin $
+ $Id: stack.c 4908 2006-05-12 16:49:50Z edwin $
*/
lock_stack_show_icmd = NEW(java_objectheader);
# if defined(NATIVE_THREADS)
- initObjectLock(lock_stack_show_icmd);
+ lock_init_object_lock(lock_stack_show_icmd);
# endif
#endif
Changes: Christian Ullrich
Edwin Steiner
- $Id: codegen.c 4863 2006-04-30 16:17:44Z edwin $
+ $Id: codegen.c 4908 2006-05-12 16:49:50Z edwin $
*/
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
/* create a virtual java_objectheader */
- (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
+ (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
a = dseg_addaddress(cd, NULL); /* vftbl */
emit_lea_membase_reg(cd, RIP, -(((ptrint) cd->mcodeptr + 7) - (ptrint) cd->mcodebase) + a, REG_ITMP3);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
/* create a virtual java_objectheader */
- (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
+ (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
disp = dseg_addaddress(cd, NULL); /* vftbl */
emit_lea_membase_reg(cd, RIP, -(((ptrint) cd->mcodeptr + 7) - (ptrint) cd->mcodebase) + disp, REG_ITMP3);
Changes: Edwin Steiner
- $Id: md.c 4805 2006-04-21 10:54:24Z twisti $
+ $Id: md.c 4908 2006-05-12 16:49:50Z edwin $
*/
{
void *critical;
- critical = thread_checkcritical((void *) uc->uc_mcontext.gregs[REG_RIP]);
+ critical = critical_find_restart_point((void *) uc->uc_mcontext.gregs[REG_RIP]);
if (critical)
uc->uc_mcontext.gregs[REG_RIP] = (ptrint) critical;
Edwin Steiner
Christian Thalinger
- $Id: loader.c 4881 2006-05-05 18:14:27Z edwin $
+ $Id: loader.c 4908 2006-05-12 16:49:50Z edwin $
*/
for (lce = list_first(list_classpath_entries); lce != NULL;
lce = list_next(list_classpath_entries, lce))
if (lce->type == CLASSPATH_ARCHIVE)
- initObjectLock((java_objectheader *) lce);
+ lock_init_object_lock((java_objectheader *) lce);
#endif
/* load some important classes */
#if defined(USE_THREADS)
if (stackbottom != 0)
- initLocks();
+ lock_init(); /* XXX this should probably be done only for green threads */
#endif
return true;
c = cb->class;
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- initObjectLock(&m->header);
+ lock_init_object_lock(&m->header);
#endif
#if defined(ENABLE_STATISTICS)
MSET(clone, 0, methodinfo, 1);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- initObjectLock(&clone->header);
+ lock_init_object_lock(&clone->header);
#endif
/* ATTENTION: if you delete the ACC_NATIVE below, set
Changes: Christian Thalinger
Edwin Steiner
- $Id: string.c 4900 2006-05-11 09:18:28Z twisti $
+ $Id: string.c 4908 2006-05-12 16:49:50Z edwin $
*/
lock_hashtable_string = NEW(java_objectheader);
# if defined(NATIVE_THREADS)
- initObjectLock(lock_hashtable_string);
+ lock_init_object_lock(lock_hashtable_string);
# endif
#endif
js = NEW(java_lang_String);
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- initObjectLock(&js->header);
+ lock_init_object_lock(&js->header);
#endif
js->header.vftbl = class_java_lang_String->vftbl;
#if defined(NATIVE_THREADS)
threads_preinit();
#endif
- initLocks();
+ lock_init();
#endif
/* initialize the string hashtable stuff: lock (must be done