new native threads
authorstefan <none@none>
Sun, 1 Aug 2004 22:01:00 +0000 (22:01 +0000)
committerstefan <none@none>
Sun, 1 Aug 2004 22:01:00 +0000 (22:01 +0000)
14 files changed:
global.h
jit/alpha/machine-instr.h
jit/i386/machine-instr.h
nat/Thread.c
nat/VMObject.c
src/native/vm/VMObject.c
src/native/vm/VMThread.c
src/threads/native/threads.c
src/threads/native/threads.h
src/vm/global.h
src/vm/jit/alpha/machine-instr.h
src/vm/jit/i386/machine-instr.h
threads/nativethread.c
threads/nativethread.h

index 7e079e9e365a017fb840dda44feb917dd3af1405..538bf874f50f3215045bfddf47271a9d6abbfb2b 100644 (file)
--- a/global.h
+++ b/global.h
@@ -31,7 +31,7 @@
             Philipp Tomsich
                        Edwin Steiner
 
-   $Id: global.h 1326 2004-07-21 13:22:33Z twisti $
+   $Id: global.h 1377 2004-08-01 22:01:00Z stefan $
 
 */
 
@@ -47,6 +47,7 @@
 
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
 #include <pthread.h>
+#include <semaphore.h>
 #endif
 
 #define STATISTICS          /* if enabled collects program statistics         */
@@ -381,7 +382,7 @@ typedef struct {            /* NameAndType (Field or Method)                  */
 struct java_objectheader {              /* header for all objects             */
        vftbl_t *vftbl;                     /* pointer to virtual function table  */
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       long monitorBits;
+       void *monitorPtr;
 #endif
 };
 
index 9b30f45d238e7fbfb44f4c19aee4b1cbda120eb7..158ada12da52bf94e9c9286362a3234d56b4f16d 100644 (file)
@@ -1,58 +1,49 @@
 #ifndef _MACHINE_INSTR_H
 #define _MACHINE_INSTR_H
 
-static inline long
+static inline void
 __attribute__ ((unused))
-atomic_swap (volatile long *p, long val)
+atomic_add (volatile int *mem, int val)
 {
-  long ret, t1;
+    int temp;
 
   __asm__ __volatile__ (
-    "/* Inline atomic swap */\n"
-       "1:\t"
-       "ldq_l  %2,%4\n\t"
-       "mov    %3,%0\n\t"
-       "stq_c  %0,%1\n\t"
-       "beq    %0,2f\n\t"
-    ".subsection 1\n"
-    "2:\t"
-    "br 1b\n"
-    ".previous\n\t"
-    "3:\t"
+    "1:\t"
+    "ldl_l  %1,%3\n\t"
+    "addl   %1,%2,%1\n\t"
+    "stl_c  %1,%0\n\t"
+    "beq    %1,1b\n\t"
     "mb\n\t"
-    "/* End atomic swap */"
-       : "=&r"(t1), "=m"(*p), "=&r"(ret)
-       : "r"(val), "m"(*p));
-
-  return ret;
+    : "=m"(*mem), "=&r"(temp)
+    : "r"(val), "m"(*mem));
 }
 
 static inline long
 __attribute__ ((unused))
 compare_and_swap (volatile long *p, long oldval, long newval)
 {
-  long ret;
+  long ret, temp;
 
   __asm__ __volatile__ (
-    "/* Inline compare & swap */\n"
     "1:\t"
-    "ldq_l  %0,%4\n\t"
-    "cmpeq  %0,%2,%0\n\t"
-    "beq    %0,3f\n\t"
-    "mov    %3,%0\n\t"
-    "stq_c  %0,%1\n\t"
-    "beq    %0,2f\n\t"
-    ".subsection 1\n"
+    "ldq_l  %0,%5\n\t"
+    "cmpeq  %0,%3,%2\n\t"
+    "beq    %2,2f\n\t"
+    "mov    %4,%2\n\t"
+    "stq_c  %2,%1\n\t"
+    "beq    %2,1b\n\t"
     "2:\t"
-    "br 1b\n"
-    ".previous\n\t"
-    "3:\t"
     "mb\n\t"
-    "/* End compare & swap */"
-       : "=&r"(ret), "=m"(*p)
-       : "r"(oldval), "r"(newval), "m"(*p));
+    : "=&r"(ret), "=m"(*p), "=&r"(temp)
+    : "r"(oldval), "r"(newval), "m"(*p));
 
   return ret;
 }
 
+#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("wmb" : : : "memory");
+#define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("mb" : : : "memory");
+#define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
+#define MEMORY_BARRIER() __asm__ __volatile__ ( \
+               "mb" : : : "memory" );
+
 #endif
index 47a0a21b1625f2413ea971e34aa0e734c081a537..edbbb27d518e0016076ef36588ebf59c520ed4be 100644 (file)
@@ -1,26 +1,31 @@
 #ifndef _MACHINE_INSTR_H
 #define _MACHINE_INSTR_H
 
-static inline long
+static inline void
 __attribute__ ((unused))
-atomic_swap (volatile long *mem, long val)
+atomic_add (volatile int *mem, int val)
 {
-  __asm__ __volatile__ ("xchgl %2,%0"
-            : "=r" (val) : "0" (val), "m" (*mem));
-  return val;
+  __asm__ __volatile__ ("lock; addl %1,%0"
+                                               : "=m" (*mem) 
+                                               : "ir" (val), "m" (*mem));
 }
 
-static inline char
+static inline long
 __attribute__ ((unused))
-compare_and_swap (volatile long int *p, long int oldval, long int newval)
+compare_and_swap (volatile long *p, long oldval, long newval)
 {
-  char ret;
-  long int readval;
+  long ret;
 
-  __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
-                        : "=q" (ret), "=m" (*p), "=a" (readval)
-                        : "r" (newval), "m" (*p), "2" (oldval));
+  __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
+                        : "=a" (ret), "=m" (*p)
+                        : "r" (newval), "m" (*p), "0" (oldval));
   return ret;
 }
 
+#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
+#define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
+#define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
+#define MEMORY_BARRIER() __asm__ __volatile__ ( \
+               "lock; add $0, 0(%%esp)" : : : "memory" );
+
 #endif
index bc0c9d66b91a34cad630d5dd4633069606ceec4d..42b9955b326f127d009614154f5a4c8ec87f5887 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Joseph Wenninger
 
-   $Id: Thread.c 1344 2004-07-21 17:12:53Z twisti $
+   $Id: Thread.c 1377 2004-08-01 22:01:00Z stefan $
 
 */
 
@@ -78,7 +78,7 @@ JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_VMThread_currentThread(JNIEnv
 #if !defined(NATIVE_THREADS)
        t = (java_lang_Thread *) currentThread;
 #else
-       t = THREADOBJECT;
+       t = ((threadobject*) THREADOBJECT)->o.thread;
 #endif
   
        if (!t->group) {
@@ -92,7 +92,7 @@ JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_VMThread_currentThread(JNIEnv
                        log_text("unable to create ThreadGroup");
        }
 
-       return (java_lang_Thread *) t;
+       return t;
 #else
        return 0;       
 #endif
@@ -106,7 +106,11 @@ JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_VMThread_currentThread(JNIEnv
  */
 JNIEXPORT void JNICALL Java_java_lang_VMThread_interrupt(JNIEnv *env, java_lang_VMThread *this)
 {
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       interruptThread(this);
+#else
        log_text("Java_java_lang_VMThread_interrupt0 called");
+#endif
 }
 
 
@@ -121,7 +125,12 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMThread_isAlive(JNIEnv *env, java_lang_VMTh
                log_text("java_lang_VMThread_isAlive called");
 
 #if defined(USE_THREADS)
+#if !defined(NATIVE_THREADS)
        return aliveThread((thread *) this->thread);
+#else
+       /* This method is implemented in classpath. */
+       panic("aliveThread");
+#endif
 #endif
 }
 
@@ -134,8 +143,12 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMThread_isAlive(JNIEnv *env, java_lang_VMTh
  */
 JNIEXPORT s4 JNICALL Java_java_lang_VMThread_isInterrupted(JNIEnv *env, java_lang_VMThread *this)
 {
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       return isInterruptedThread(this);
+#else
        log_text("Java_java_lang_VMThread_isInterrupted  called");
        return 0;
+#endif
 }
 
 
@@ -176,7 +189,7 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeSetPriority(JNIEnv *env, ja
     if (runverbose) 
                log_text("java_lang_VMThread_setPriority0 called");
 
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
+#if defined(USE_THREADS)
        setPriorityThread((thread *) this->thread, par1);
 #endif
 }
@@ -189,22 +202,6 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeSetPriority(JNIEnv *env, ja
  */
 JNIEXPORT void JNICALL Java_java_lang_VMThread_sleep(JNIEnv *env, jclass clazz, s8 millis, s4 nanos)
 {
-       if (millis < 0) {
-               *exceptionptr =
-                       new_exception_message(string_java_lang_IllegalArgumentException,
-                                                                 "timeout value is negative");
-
-               return;
-       }
-
-       if (nanos < 0 || nanos > 999999) {
-               *exceptionptr =
-                       new_exception_message(string_java_lang_IllegalArgumentException,
-                                                                 "nanosecond timeout value out of range");
-
-               return;
-       }
-
 #if defined(USE_THREADS)
        sleepThread(millis, nanos);
 #endif
@@ -222,13 +219,8 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_start(JNIEnv *env, java_lang_VMTh
                log_text("java_lang_VMThread_start called");
 
 #if defined(USE_THREADS)
-#if defined(__GNUC__)
-#warning perhaps it would be better to always work with the vmthread structure in the thread code (jowenn)
-#endif
-       if (this->thread->vmThread == 0)
-               this->thread->vmThread = this;
-
-       startThread((thread *) (this->thread));
+       this->thread->vmThread = this;
+       startThread((thread *) this->thread);
 #endif
 }
 
@@ -300,9 +292,12 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_yield(JNIEnv *env, jclass clazz)
  */
 JNIEXPORT s4 JNICALL Java_java_lang_VMThread_interrupted(JNIEnv *env, jclass clazz)
 {
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       return interruptedThread();
+#else
        log_text("Java_java_lang_VMThread_interrupted");
-
        return 0;
+#endif
 }
 
 
@@ -318,9 +313,8 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeInit(JNIEnv *env, java_lang
                log_text("There has been an exception, strange...");*/
 
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       initThread(this->thread);
+       initThread(this);
 #endif
-       this->thread->priority = 5;
 }
 
 
index a161f7133acc536c74f16c2ea0c65c4978148186..882086e4344fdd931c88ae0ab5b7d9fb16fdf75a 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Joseph Wenninger
 
-   $Id: VMObject.c 1344 2004-07-21 17:12:53Z twisti $
+   $Id: VMObject.c 1377 2004-08-01 22:01:00Z stefan $
 
 */
 
@@ -68,7 +68,7 @@ JNIEXPORT java_lang_Object* JNICALL Java_java_lang_VMObject_clone(JNIEnv *env, j
                new = (java_lang_Object *) heap_allocate(size, (desc->arraytype == ARRAYTYPE_OBJECT), NULL);
                memcpy(new, this, size);
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
-               new->header.monitorBits = 0;
+               initObjectLock(new);
 #endif
         
                return new;
@@ -90,7 +90,7 @@ JNIEXPORT java_lang_Object* JNICALL Java_java_lang_VMObject_clone(JNIEnv *env, j
 
     memcpy(new, this, c->instancesize);
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       new->header.monitorBits = 0;
+       initObjectLock(new);
 #endif
 
     return new;
@@ -140,7 +140,7 @@ JNIEXPORT void JNICALL Java_java_lang_VMObject_wait(JNIEnv *env, jclass clazz, j
                log_text("java_lang_VMObject_wait called");
 
 #if defined(USE_THREADS)
-       wait_cond_for_object(&this->header, time);
+       wait_cond_for_object(&this->header, time, par3);
 #endif
 }
 
index a161f7133acc536c74f16c2ea0c65c4978148186..882086e4344fdd931c88ae0ab5b7d9fb16fdf75a 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Joseph Wenninger
 
-   $Id: VMObject.c 1344 2004-07-21 17:12:53Z twisti $
+   $Id: VMObject.c 1377 2004-08-01 22:01:00Z stefan $
 
 */
 
@@ -68,7 +68,7 @@ JNIEXPORT java_lang_Object* JNICALL Java_java_lang_VMObject_clone(JNIEnv *env, j
                new = (java_lang_Object *) heap_allocate(size, (desc->arraytype == ARRAYTYPE_OBJECT), NULL);
                memcpy(new, this, size);
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
-               new->header.monitorBits = 0;
+               initObjectLock(new);
 #endif
         
                return new;
@@ -90,7 +90,7 @@ JNIEXPORT java_lang_Object* JNICALL Java_java_lang_VMObject_clone(JNIEnv *env, j
 
     memcpy(new, this, c->instancesize);
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       new->header.monitorBits = 0;
+       initObjectLock(new);
 #endif
 
     return new;
@@ -140,7 +140,7 @@ JNIEXPORT void JNICALL Java_java_lang_VMObject_wait(JNIEnv *env, jclass clazz, j
                log_text("java_lang_VMObject_wait called");
 
 #if defined(USE_THREADS)
-       wait_cond_for_object(&this->header, time);
+       wait_cond_for_object(&this->header, time, par3);
 #endif
 }
 
index ac46098995db68d69a46c0a420c549474d6329aa..5eef05962263a8843e906ea1de8fd942547eacf6 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Joseph Wenninger
 
-   $Id: VMThread.c 1344 2004-07-21 17:12:53Z twisti $
+   $Id: VMThread.c 1377 2004-08-01 22:01:00Z stefan $
 
 */
 
@@ -78,7 +78,7 @@ JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_VMThread_currentThread(JNIEnv
 #if !defined(NATIVE_THREADS)
        t = (java_lang_Thread *) currentThread;
 #else
-       t = THREADOBJECT;
+       t = ((threadobject*) THREADOBJECT)->o.thread;
 #endif
   
        if (!t->group) {
@@ -92,7 +92,7 @@ JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_VMThread_currentThread(JNIEnv
                        log_text("unable to create ThreadGroup");
        }
 
-       return (java_lang_Thread *) t;
+       return t;
 #else
        return 0;       
 #endif
@@ -106,7 +106,11 @@ JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_VMThread_currentThread(JNIEnv
  */
 JNIEXPORT void JNICALL Java_java_lang_VMThread_interrupt(JNIEnv *env, java_lang_VMThread *this)
 {
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       interruptThread(this);
+#else
        log_text("Java_java_lang_VMThread_interrupt0 called");
+#endif
 }
 
 
@@ -121,7 +125,12 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMThread_isAlive(JNIEnv *env, java_lang_VMTh
                log_text("java_lang_VMThread_isAlive called");
 
 #if defined(USE_THREADS)
+#if !defined(NATIVE_THREADS)
        return aliveThread((thread *) this->thread);
+#else
+       /* This method is implemented in classpath. */
+       panic("aliveThread");
+#endif
 #endif
 }
 
@@ -134,8 +143,12 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMThread_isAlive(JNIEnv *env, java_lang_VMTh
  */
 JNIEXPORT s4 JNICALL Java_java_lang_VMThread_isInterrupted(JNIEnv *env, java_lang_VMThread *this)
 {
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       return isInterruptedThread(this);
+#else
        log_text("Java_java_lang_VMThread_isInterrupted  called");
        return 0;
+#endif
 }
 
 
@@ -176,7 +189,7 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeSetPriority(JNIEnv *env, ja
     if (runverbose) 
                log_text("java_lang_VMThread_setPriority0 called");
 
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
+#if defined(USE_THREADS)
        setPriorityThread((thread *) this->thread, par1);
 #endif
 }
@@ -189,22 +202,6 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeSetPriority(JNIEnv *env, ja
  */
 JNIEXPORT void JNICALL Java_java_lang_VMThread_sleep(JNIEnv *env, jclass clazz, s8 millis, s4 nanos)
 {
-       if (millis < 0) {
-               *exceptionptr =
-                       new_exception_message(string_java_lang_IllegalArgumentException,
-                                                                 "timeout value is negative");
-
-               return;
-       }
-
-       if (nanos < 0 || nanos > 999999) {
-               *exceptionptr =
-                       new_exception_message(string_java_lang_IllegalArgumentException,
-                                                                 "nanosecond timeout value out of range");
-
-               return;
-       }
-
 #if defined(USE_THREADS)
        sleepThread(millis, nanos);
 #endif
@@ -222,13 +219,8 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_start(JNIEnv *env, java_lang_VMTh
                log_text("java_lang_VMThread_start called");
 
 #if defined(USE_THREADS)
-#if defined(__GNUC__)
-#warning perhaps it would be better to always work with the vmthread structure in the thread code (jowenn)
-#endif
-       if (this->thread->vmThread == 0)
-               this->thread->vmThread = this;
-
-       startThread((thread *) (this->thread));
+       this->thread->vmThread = this;
+       startThread((thread *) this->thread);
 #endif
 }
 
@@ -300,9 +292,12 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_yield(JNIEnv *env, jclass clazz)
  */
 JNIEXPORT s4 JNICALL Java_java_lang_VMThread_interrupted(JNIEnv *env, jclass clazz)
 {
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       return interruptedThread();
+#else
        log_text("Java_java_lang_VMThread_interrupted");
-
        return 0;
+#endif
 }
 
 
@@ -318,9 +313,8 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeInit(JNIEnv *env, java_lang
                log_text("There has been an exception, strange...");*/
 
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       initThread(this->thread);
+       initThread(this);
 #endif
-       this->thread->priority = 5;
 }
 
 
index e8d3b5cdb0c2474bf5dc65c1887bc4b4fb14b0ca..7a46f3f2ec02f0924657c249eb6f329c28f7d84f 100644 (file)
@@ -31,6 +31,7 @@
 #include "nat/java_lang_Throwable.h"
 #include "nat/java_lang_Thread.h"
 #include "nat/java_lang_ThreadGroup.h"
+#include "nat/java_lang_VMThread.h"
 
 #include <pthread.h>
 #include <semaphore.h>
@@ -46,6 +47,8 @@
 
 #ifdef MUTEXSIM
 
+/* We need this for older MacOSX (10.1.x) */
+
 typedef struct {
        pthread_mutex_t mutex;
        pthread_t owner;
@@ -97,6 +100,16 @@ static void pthread_mutex_unlock_rec(pthread_mutex_rec_t *m)
 
 #endif /* MUTEXSIM */
 
+static void setPriority(pthread_t tid, int priority)
+{
+       struct sched_param schedp;
+       int policy;
+
+       pthread_getschedparam(tid, &policy, &schedp);
+       schedp.sched_priority = priority;
+       pthread_setschedparam(tid, policy, &schedp);
+}
+
 #include "machine-instr.h"
 
 static struct avl_table *criticaltree;
@@ -377,6 +390,10 @@ static void setthreadobject(threadobject *thread)
 #endif
 }
 
+static monitorLockRecord *dummyLR;
+
+static void initPools();
+
 /*
  * Initialize threads.
  */
@@ -404,17 +421,27 @@ initThreadsEarly()
 
        mainthreadobj = NEW(threadobject);
        memset(mainthreadobj, 0, sizeof(threadobject));
+       mainthreadobj->info.tid = pthread_self();
 #if !defined(HAVE___THREAD)
        pthread_key_create(&tkey_threadinfo, NULL);
 #endif
        setthreadobject(mainthreadobj);
+       initPools();
 
     criticaltree = avl_create(criticalcompare, NULL, NULL);
        thread_addstaticcritical();
        sem_init(&suspend_ack, 0, 0);
+
+       /* Every newly created object's monitorPtr points here so we save a check
+        * against NULL */
+       dummyLR = mem_alloc(sizeof(monitorLockRecord));
+       dummyLR->o = NULL;
+       dummyLR->ownerThread = NULL;
+       dummyLR->waiting = false;
 }
 
 static pthread_attr_t threadattr;
+
 static void freeLockRecordPools(lockRecordPool *);
 
 void
@@ -422,10 +449,13 @@ initThreads(u1 *stackbottom)
 {
        classinfo *threadclass;
        classinfo *threadgroupclass;
+       java_lang_String *threadname;
        java_lang_Thread *mainthread;
+       java_lang_ThreadGroup *threadgroup;
        threadobject *tempthread = mainthreadobj;
+       methodinfo *method;
 
-       threadclass = class_new(utf_new_char("java/lang/Thread"));
+       threadclass = class_new(utf_new_char("java/lang/VMThread"));
        class_load(threadclass);
        class_link(threadclass);
 
@@ -433,8 +463,12 @@ initThreads(u1 *stackbottom)
                throw_exception_exit();
 
        freeLockRecordPools(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 have been created
+        * at an earlier time */
        threadclass->instancesize = sizeof(threadobject);
 
+       /* Create a VMThread */
        mainthreadobj = (threadobject *) builtin_new(threadclass);
 
        if (!mainthreadobj)
@@ -443,36 +477,80 @@ initThreads(u1 *stackbottom)
        FREE(tempthread, threadobject);
        initThread(&mainthreadobj->o);
 
-#if !defined(HAVE___THREAD)
-       pthread_setspecific(tkey_threadinfo, mainthreadobj);
-#else
-       threadobj = mainthreadobj;
-#endif
+       setthreadobject(mainthreadobj);
 
-       mainthread = &mainthreadobj->o;
        initLocks();
        mainthreadobj->info.next = mainthreadobj;
        mainthreadobj->info.prev = mainthreadobj;
 
-       mainthread->name=javastring_new(utf_new_char("main"));
+       threadname = javastring_new(utf_new_char("main"));
 
        /* Allocate and init ThreadGroup */
        threadgroupclass = class_new(utf_new_char("java/lang/ThreadGroup"));
-       mainthread->group =
+       threadgroup =
                (java_lang_ThreadGroup *) native_new_and_init(threadgroupclass);
 
-       if (!mainthread->group)
+       if (!threadgroup)
+               throw_exception_exit();
+
+       /* Create a Thread */
+       threadclass = class_new(utf_new_char("java/lang/Thread"));
+       mainthread = (java_lang_Thread*) builtin_new(threadclass);
+       mainthreadobj->o.thread = mainthread;
+
+       if (!mainthread)
+               throw_exception_exit();
+
+       /* Call Thread constructor */
+       method = class_resolveclassmethod(threadclass,
+                                                                         utf_new_char("<init>"),
+                                                                         utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
+                                                                         threadclass,
+                                                                         true);
+
+       if (!method)
+               throw_exception_exit();
+
+       asm_calljavafunction(method, mainthread, mainthreadobj, threadname, (void*) 5);
+       if (*exceptionptr)
+               throw_exception_exit();
+
+       mainthread->group = threadgroup;
+       /* XXX This is a hack because the fourth argument was omitted */
+       mainthread->daemon = false;
+
+       /* Add mainthread to ThreadGroup */
+       method = class_resolveclassmethod(threadgroupclass,
+                                                                         utf_new_char("addThread"),
+                                                                         utf_new_char("(Ljava/lang/Thread;)V"),
+                                                                         threadgroupclass,
+                                                                         true);
+
+       if (!method)
                throw_exception_exit();
 
+       asm_calljavafunction(method, threadgroup, mainthread, NULL, NULL);
+       if (*exceptionptr)
+               throw_exception_exit();
+
+       /* TODO InheritableThreadLocal */
+
+       setPriority(pthread_self(), 5);
+
        pthread_attr_init(&threadattr);
        pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
 }
 
-void initThread(java_lang_Thread *t)
+void initThread(java_lang_VMThread *t)
 {
-       nativethread *info = &((threadobject*) t)->info;
+       threadobject *thread = (threadobject*) t;
+       nativethread *info = &thread->info;
+       info->tid = pthread_self();
        pthread_mutex_init(&info->joinMutex, NULL);
        pthread_cond_init(&info->joinCond, NULL);
+
+       thread->interrupted = 0;
+       thread->waiting = NULL;
 }
 
 static void initThreadLocks(threadobject *);
@@ -509,6 +587,8 @@ static void *threadstartup(void *t)
        startup = NULL;
        sem_post(psem);
 
+       setPriority(info->tid, thread->o.thread->priority);
+
        /* Find the run()V method and call it */
        method = class_resolveclassmethod(thread->o.header.vftbl->class,
                                                                          utf_new_char("run"),
@@ -524,6 +604,8 @@ static void *threadstartup(void *t)
                throw_exception();
        }
 
+       /* 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);
 
        pthread_mutex_lock(&threadlistlock);
@@ -539,13 +621,13 @@ static void *threadstartup(void *t)
        return NULL;
 }
 
-void startThread(threadobject *t)
+void startThread(thread *t)
 {
-       nativethread *info = &t->info;
+       nativethread *info = &((threadobject*) t->vmThread)->info;
        sem_t sem;
        startupinfo startup;
 
-       startup.thread = t;
+       startup.thread = (threadobject*) t->vmThread;
        startup.psem = &sem;
 
        sem_init(&sem, 0, 0);
@@ -553,16 +635,31 @@ void startThread(threadobject *t)
        if (pthread_create(&info->tid, &threadattr, threadstartup, &startup))
                panic("pthread_create failed");
 
-       /* Wait here until thread has entered itself into the thread list */
+       /* Wait here until the thread has entered itself into the thread list */
        sem_wait(&sem);
        sem_destroy(&sem);
 }
 
+/* At the end of the program, we wait for all running non-daemon threads to die
+ */
+
+static threadobject *findNonDaemon(threadobject *thread)
+{
+       while (thread != mainthreadobj) {
+               if (!thread->o.thread->daemon)
+                       return thread;
+               thread = thread->info.prev;
+       }
+
+       return NULL;
+}
+
 void joinAllThreads()
 {
+       threadobject *thread;
        pthread_mutex_lock(&threadlistlock);
-       while (mainthreadobj->info.prev != mainthreadobj) {
-               nativethread *info = &mainthreadobj->info.prev->info;
+       while ((thread = findNonDaemon(mainthreadobj->info.prev)) != NULL) {
+               nativethread *info = &thread->info;
                pthread_mutex_lock(&info->joinMutex);
                pthread_mutex_unlock(&threadlistlock);
                if (info->tid)
@@ -573,54 +670,34 @@ void joinAllThreads()
        pthread_mutex_unlock(&threadlistlock);
 }
 
-bool aliveThread(java_lang_Thread *t)
-{
-       return ((threadobject*) t)->info.tid != 0;
-}
-
-void sleepThread(s8 millis, s4 nanos)
-{
-       struct timespec tv;
-       tv.tv_sec = millis / 1000;
-       tv.tv_nsec = millis % 1000 * 1000000 + nanos;
-       do { } while (nanosleep(&tv, &tv) == EINTR);
-}
-
-void yieldThread()
-{
-       sched_yield();
-}
-
-static void timedCondWait(pthread_cond_t *cond, pthread_mutex_t *mutex, s8 millis)
+static void initLockRecord(monitorLockRecord *r, threadobject *t)
 {
-       struct timeval now;
-       struct timespec desttime;
-       gettimeofday(&now, NULL);
-       desttime.tv_sec = millis / 1000;
-       desttime.tv_nsec = millis % 1000 * 1000000;
-       pthread_cond_timedwait(cond, mutex, &desttime);
+       r->lockCount = 1;
+       r->ownerThread = t;
+       r->queuers = 0;
+       r->o = NULL;
+       r->waiter = NULL;
+       r->incharge = NULL;
+       r->waiting = false;
+       sem_init(&r->queueSem, 0, 0);
+       pthread_mutex_init(&r->resolveLock, NULL);
+       pthread_cond_init(&r->resolveWait, NULL);
+       pthread_mutex_init(&r->waitLock, NULL);
+       pthread_cond_init(&r->waitCond, NULL);
 }
 
+/* No lock record must ever be destroyed because there may still be references
+ * to it.
 
-#define NEUTRAL 0
-#define LOCKED 1
-#define WAITERS 2
-#define BUSY 3
-
-static void initExecutionEnvironment(ExecEnvironment *ee)
-{
-       pthread_mutex_init(&ee->metaLockMutex, NULL);
-       pthread_cond_init(&ee->metaLockCond, NULL);
-       pthread_mutex_init(&ee->monitorLockMutex, NULL);
-       pthread_cond_init(&ee->monitorLockCond, NULL);
-}
-
-static void initLockRecord(monitorLockRecord *r, threadobject *t)
+static void destroyLockRecord(monitorLockRecord *r)
 {
-       r->owner = t;
-       r->lockCount = 1;
-       r->queue = NULL;
+       sem_destroy(&r->queueSem);
+       pthread_mutex_destroy(&r->resolveLock);
+       pthread_cond_destroy(&r->resolveWait);
+       pthread_mutex_destroy(&r->waitLock);
+       pthread_cond_destroy(&r->waitCond);
 }
+*/
 
 void initLocks()
 {
@@ -629,34 +706,12 @@ void initLocks()
 
 static void initThreadLocks(threadobject *thread)
 {
-       int i;
-
-       initExecutionEnvironment(&thread->ee);
-       for (i=0; i<INITIALLOCKRECORDS; i++) {
-               monitorLockRecord *r = &thread->ee.lr[i];
-               initLockRecord(r, thread);
-               r->nextFree = &thread->ee.lr[i+1];
-       }
-       thread->ee.lr[i-1].nextFree = NULL;
-       thread->ee.firstLR = &thread->ee.lr[0];
-}
-
-static inline int lockState(long r)
-{
-       return (int) r & 3;
-}
-
-static inline void *lockRecord(long r)
-{
-       return (void*) (r & ~3L);
+       thread->ee.firstLR = NULL;
+       thread->ee.lrpool = NULL;
+       thread->ee.numlr = 0;
 }
 
-static inline long makeLockBits(void *r, long l)
-{
-       return ((long) r) | l;
-}
-
-static lockRecordPool *allocLockRecordPool(threadobject *thread, int size)
+static lockRecordPool *allocNewLockRecordPool(threadobject *thread, int size)
 {
        lockRecordPool *p = mem_alloc(sizeof(lockRecordPoolHeader) + sizeof(monitorLockRecord) * size);
        int i;
@@ -670,286 +725,362 @@ static lockRecordPool *allocLockRecordPool(threadobject *thread, int size)
        return p;
 }
 
-static void freeLockRecordPools(lockRecordPool *pool)
+#define INITIALLOCKRECORDS 8
+
+static pthread_mutex_t pool_lock;
+static lockRecordPool *global_pool;
+
+static void initPools()
 {
-       while (pool) {
-               lockRecordPool *n = pool->header.next;
-               mem_free(pool, sizeof(lockRecordPoolHeader) + sizeof(monitorLockRecord) * pool->header.size);
-               pool = n;
+       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;
+               
+               return pool;
        }
+       pthread_mutex_unlock(&pool_lock);
+
+       return allocNewLockRecordPool(t, size);
 }
 
-static monitorLockRecord *allocLockRecord(threadobject *t)
+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 = t->ee.firstLR;
 
        if (!r) {
-               int poolsize = t->ee.lrpool ? t->ee.lrpool->header.size * 2 : INITIALLOCKRECORDS * 2;
+               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;
        return r;
 }
 
-static void recycleLockRecord(threadobject *t, monitorLockRecord *r)
+static inline void recycleLockRecord(threadobject *t, monitorLockRecord *r)
 {
        r->nextFree = t->ee.firstLR;
        t->ee.firstLR = r;
 }
 
-static monitorLockRecord *appendToQueue(monitorLockRecord *queue, monitorLockRecord *lr)
-{
-       monitorLockRecord *queuestart = queue;
-       if (!queue)
-               return lr;
-       while (queue->queue)
-               queue = queue->queue;
-       queue->queue = lr;
-       return queuestart;
-}
-
-static monitorLockRecord *moveMyLRToFront(threadobject *t, monitorLockRecord *lr)
+#if 0
+static monitorLockRecord *allocLockRecord(threadobject *t, monitorLockRecord *lr)
 {
-       monitorLockRecord *pred = NULL;
-       monitorLockRecord *firstLR = lr;
-       while (lr->owner != t) {
-               pred = lr;
-               lr = lr->queue;
+       monitorLockRecord *r = allocLockRecordSimple(t);
+       if (r == lr) {
+               monitorLockRecord *r2 = allocLockRecordSimple(t);
+               recycleLockRecord(t, r);
+               r = r2;
        }
-       if (!pred)
-               return lr;
-       pred->queue = lr->queue;
-       lr->queue = firstLR;
-       lr->storedBits = firstLR->storedBits;
-       return lr;
+       return r;
 }
+#endif
 
-static long getMetaLockSlow(threadobject *t, long predBits);
-static void releaseMetaLockSlow(threadobject *t, long releaseBits);
-
-static long getMetaLock(threadobject *t, java_objectheader *o)
+void initObjectLock(java_objectheader *o)
 {
-       long busyBits = makeLockBits(t, BUSY);
-       long lockBits = atomic_swap(&o->monitorBits, busyBits);
-       return lockState(lockBits) != BUSY ? lockBits : getMetaLockSlow(t, lockBits);
+       o->monitorPtr = dummyLR;
 }
 
-static long getMetaLockSlow(threadobject *t, long predBits)
+static void queueOnLockRecord(monitorLockRecord *lr, java_objectheader *o)
 {
-       long bits;
-       threadobject *pred = lockRecord(predBits);
-       pthread_mutex_lock(&pred->ee.metaLockMutex);
-       if (!pred->ee.bitsForGrab) {
-               pred->ee.succ = t;
-               do {
-                       pthread_cond_wait(&pred->ee.metaLockCond, &pred->ee.metaLockMutex);
-               } while (!t->ee.gotMetaLockSlow);
-               t->ee.gotMetaLockSlow = false;
-               bits = t->ee.metaLockBits;
-       } else {
-               bits = pred->ee.metaLockBits;
-               pred->ee.bitsForGrab = false;
-               pthread_cond_signal(&pred->ee.metaLockCond);
-       }
-       pthread_mutex_unlock(&pred->ee.metaLockMutex);
-       return bits;
+       atomic_add(&lr->queuers, 1);
+       MEMORY_BARRIER_AFTER_ATOMIC();
+       if (lr->o == o)
+               sem_wait(&lr->queueSem);
+       atomic_add(&lr->queuers, -1);
 }
 
-static void releaseMetaLock(threadobject *t, java_objectheader *o, long releaseBits)
+static void freeLockRecord(monitorLockRecord *lr)
 {
-       long busyBits = makeLockBits(t, BUSY);
-       int locked = compare_and_swap(&o->monitorBits, busyBits, releaseBits) != 0;
-       
-       if (!locked)
-               releaseMetaLockSlow(t, releaseBits);
+       int q;
+       lr->o = NULL;
+       MEMORY_BARRIER();
+       q = lr->queuers;
+       while (q--)
+               sem_post(&lr->queueSem);
 }
 
-static void releaseMetaLockSlow(threadobject *t, long releaseBits)
+static inline void handleWaiter(monitorLockRecord *mlr, monitorLockRecord *lr)
 {
-       pthread_mutex_lock(&t->ee.metaLockMutex);
-       if (t->ee.succ) {
-               assert(!t->ee.succ->ee.bitsForGrab);
-               assert(!t->ee.bitsForGrab);
-               assert(!t->ee.succ->ee.gotMetaLockSlow);
-               t->ee.succ->ee.metaLockBits = releaseBits;
-               t->ee.succ->ee.gotMetaLockSlow = true;
-               t->ee.succ = NULL;
-               pthread_cond_signal(&t->ee.metaLockCond);
-       } else {
-               t->ee.metaLockBits = releaseBits;
-               t->ee.bitsForGrab = true;
-               do {
-                       pthread_cond_wait(&t->ee.metaLockCond, &t->ee.metaLockMutex);
-               } while (t->ee.bitsForGrab);
-       }
-       pthread_mutex_unlock(&t->ee.metaLockMutex);
+       if (lr->waiting)
+               mlr->waiter = lr;
 }
 
-static void monitorEnterSlow(threadobject *t, java_objectheader *o, long r);
-
-void monitorEnter(threadobject *t, java_objectheader *o)
+monitorLockRecord *monitorEnter(threadobject *t, java_objectheader *o)
 {
-       long r = getMetaLock(t, o);
-       int state = lockState(r);
-
-       if (state == NEUTRAL) {
-               monitorLockRecord *lr = allocLockRecord(t);
-               lr->storedBits = r;
-               releaseMetaLock(t, o, makeLockBits(lr, LOCKED));
-       } else if (state == LOCKED) {
-               monitorLockRecord *ownerLR = lockRecord(r);
-               if (ownerLR->owner == t) {
-                       ownerLR->lockCount++;
-                       releaseMetaLock(t, o, r);
+       for (;;) {
+               monitorLockRecord *lr = o->monitorPtr;
+               if (lr->o != o) {
+                       monitorLockRecord *nlr, *mlr = allocLockRecordSimple(t);
+                       mlr->o = o;
+                       MEMORY_BARRIER_BEFORE_ATOMIC();
+                       nlr = (void*) compare_and_swap((long*) &o->monitorPtr, (long) lr, (long) mlr);
+                       if (nlr == lr) {
+                               if (mlr == lr || lr->o != o) {
+                                       handleWaiter(mlr, lr);
+                                       return mlr;
+                               } else {
+                                       void *incharge;
+                                       pthread_mutex_lock(&mlr->resolveLock);
+                                       incharge = mlr->incharge;
+                                       mlr->incharge = lr;
+                                       pthread_mutex_unlock(&mlr->resolveLock);
+                                       if (incharge)
+                                               pthread_cond_signal(&mlr->resolveWait);
+                               }
+                               while (lr->o == o)
+                                       queueOnLockRecord(lr, o);
+                               mlr->incharge = NULL;
+                               handleWaiter(mlr, lr);
+                               return mlr;
+                       }
+                       freeLockRecord(mlr);
+                       recycleLockRecord(t, mlr);
+                       queueOnLockRecord(nlr, o);
                } else {
-                       monitorLockRecord *lr = allocLockRecord(t);
-                       ownerLR->queue = appendToQueue(ownerLR->queue, lr);
-                       monitorEnterSlow(t, o, r);
+                       if (lr->ownerThread == t) {
+                               lr->lockCount++;
+                               return lr;
+                       }
+                       queueOnLockRecord(lr, o);
                }
-       } else if (state == WAITERS) {
-               monitorLockRecord *lr = allocLockRecord(t);
-               monitorLockRecord *firstWaiterLR = lockRecord(r);
-               lr->queue = firstWaiterLR;
-               lr->storedBits = firstWaiterLR->storedBits;
-               releaseMetaLock(t, o, makeLockBits(lr, LOCKED));
        }
 }
 
-static void monitorEnterSlow(threadobject *t, java_objectheader *o, long r)
+static monitorLockRecord *grabLockRecordInCharge(monitorLockRecord *lr)
 {
-       monitorLockRecord *lr;
-       while (lockState(r) == LOCKED) {
-               pthread_mutex_lock(&t->ee.monitorLockMutex);
-               releaseMetaLock(t, o, r);
-               pthread_cond_wait(&t->ee.monitorLockCond, &t->ee.monitorLockMutex);
-               pthread_mutex_unlock(&t->ee.monitorLockMutex);
-               r = getMetaLock(t, o);
+       pthread_mutex_lock(&lr->resolveLock);
+       if (!lr->incharge) {
+               lr->incharge = lr;
+               pthread_cond_wait(&lr->resolveWait, &lr->resolveLock);
        }
-       assert(lockState(r) == WAITERS);
-       lr = moveMyLRToFront(t, lockRecord(r));
-       releaseMetaLock(t, o, makeLockBits(lr, LOCKED));
+       pthread_mutex_unlock(&lr->resolveLock);
+       return lr->incharge;
 }
 
-static void monitorExitSlow(threadobject *t, java_objectheader *o, monitorLockRecord *lr);
-
-void monitorExit(threadobject *t, java_objectheader *o)
+static void wakeWaiters(monitorLockRecord *lr)
 {
-       long r = getMetaLock(t, o);
-       monitorLockRecord *ownerLR = lockRecord(r);
-       int state = lockState(r);
-
-       if (state == LOCKED && ownerLR->owner == t) {
-               assert(ownerLR->lockCount >= 1);
-               if (ownerLR->lockCount == 1) {
-                       if (ownerLR->queue == NULL) {
-                               assert(lockState(ownerLR->storedBits) == NEUTRAL);
-                               releaseMetaLock(t, o, ownerLR->storedBits);
-                       } else {
-                               ownerLR->queue->storedBits = ownerLR->storedBits;
-                               monitorExitSlow(t, o, ownerLR->queue);
-                               ownerLR->queue = NULL;
-                       }
-                       recycleLockRecord(t, ownerLR);
-               } else {
-                       ownerLR->lockCount--;
-                       releaseMetaLock(t, o, r);
-               }
+       do {
+               int q = lr->queuers;
+               while (q--)
+                       sem_post(&lr->queueSem);
+               lr = lr->waiter;
+       } while (lr);
+}
 
-       } else {
-               releaseMetaLock(t, o, r);
+#define GRAB_LR(lr,t) \
+    if (lr->ownerThread != t) { \
+               lr = grabLockRecordInCharge(lr); \
+               assert(lr->ownerThread == t); \
+       }
 
-               /* throw an exception */
+#define CHECK_MONITORSTATE(lr,mo,a) \
+    if (lr->o != mo) { \
+               *exceptionptr = new_exception(string_java_lang_IllegalMonitorStateException); \
+               a; \
+       }
 
-               *exceptionptr =
-                       new_exception(string_java_lang_IllegalMonitorStateException);
+bool monitorExit(threadobject *t, java_objectheader *o)
+{
+       monitorLockRecord *lr = o->monitorPtr;
+       GRAB_LR(lr, t);
+       CHECK_MONITORSTATE(lr, o, return false);
+       if (lr->lockCount > 1) {
+               lr->lockCount--;
+               return true;
+       }
+       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;
+                       nlr->waiter = wlr;
+                       STORE_ORDER_BARRIER();
+               } else
+                       wakeWaiters(wlr);
+               lr->waiter = NULL;
        }
+       freeLockRecord(lr);
+       recycleLockRecord(t, lr);
+       return true;
 }
 
-static threadobject *wakeupEE(monitorLockRecord *lr)
+static void removeFromWaiters(monitorLockRecord *lr, monitorLockRecord *wlr)
 {
-       while (lr->queue && lr->queue->owner->ee.isWaitingForNotify)
-               lr = lr->queue;
-       return lr->owner;
+       do {
+               if (lr->waiter == wlr) {
+                       lr->waiter = wlr->waiter;
+                       break;
+               }
+               lr = lr->waiter;
+       } while (lr);
+}
+
+bool waitWithTimeout(threadobject *t, monitorLockRecord *lr, struct timespec *wakeupTime)
+{
+       bool wasinterrupted;
+
+       pthread_mutex_lock(&lr->waitLock);
+       t->waiting = lr;
+       if (wakeupTime->tv_sec || wakeupTime->tv_nsec)
+               pthread_cond_timedwait(&lr->waitCond, &lr->waitLock, wakeupTime);
+       else
+               pthread_cond_wait(&lr->waitCond, &lr->waitLock);
+       wasinterrupted = t->waiting == NULL;
+       t->waiting = NULL;
+       pthread_mutex_unlock(&lr->waitLock);
+       return wasinterrupted;
 }
 
-static void monitorExitSlow(threadobject *t, java_objectheader *o, monitorLockRecord *lr)
+static void calcAbsoluteTime(struct timespec *tm, s8 millis, s4 nanos)
 {
-       threadobject *wakeEE = wakeupEE(lr);
-       if (wakeEE) {
-               pthread_mutex_lock(&wakeEE->ee.monitorLockMutex);
-               releaseMetaLock(t, o, makeLockBits(lr, WAITERS));
-               pthread_cond_signal(&wakeEE->ee.monitorLockCond);
-               pthread_mutex_unlock(&wakeEE->ee.monitorLockMutex);
+       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 {
-               releaseMetaLock(t, o, makeLockBits(lr, WAITERS));
+               tm->tv_sec = 0;
+               tm->tv_nsec = 0;
        }
 }
 
-void monitorWait(threadobject *t, java_objectheader *o, s8 millis)
+void monitorWait(threadobject *t, java_objectheader *o, s8 millis, s4 nanos)
 {
-       long r = getMetaLock(t, o);
-       monitorLockRecord *ownerLR = lockRecord(r);
-       int state = lockState(r);
-
-       if (state == LOCKED && ownerLR->owner == t) {
-               pthread_mutex_lock(&t->ee.monitorLockMutex);
-               t->ee.isWaitingForNotify = true;
-               monitorExitSlow(t, o, ownerLR);
-               if (millis == -1)
-                       pthread_cond_wait(&t->ee.monitorLockCond, &t->ee.monitorLockMutex);
-               else
-                       timedCondWait(&t->ee.monitorLockCond, &t->ee.monitorLockMutex, millis);
-               t->ee.isWaitingForNotify = false;
-               pthread_mutex_unlock(&t->ee.monitorLockMutex);
-               r = getMetaLock(t, o);
-               monitorEnterSlow(t, o, r);
+       bool wasinterrupted;
+       struct timespec wakeupTime;
+       monitorLockRecord *mlr, *lr = o->monitorPtr;
+       GRAB_LR(lr, t);
+       CHECK_MONITORSTATE(lr, o, return);
 
-       } else {
-               releaseMetaLock(t, o, r);
+       calcAbsoluteTime(&wakeupTime, millis, nanos);
+       
+       if (lr->waiter)
+               wakeWaiters(lr->waiter);
+       lr->waiting = true;
+       STORE_ORDER_BARRIER();
+       freeLockRecord(lr);
+       wasinterrupted = waitWithTimeout(t, lr, &wakeupTime);
+       mlr = monitorEnter(t, o);
+       removeFromWaiters(mlr, lr);
+       mlr->lockCount = lr->lockCount;
+       lr->lockCount = 1;
+       lr->waiting = false;
+       lr->waiter = NULL;
+       recycleLockRecord(t, lr);
+
+       if (wasinterrupted)
+               *exceptionptr = new_exception(string_java_lang_InterruptedException);
+}
 
-               /* throw an exception */
+static void notifyOneOrAll(threadobject *t, java_objectheader *o, bool one)
+{
+       monitorLockRecord *lr = o->monitorPtr;
+       GRAB_LR(lr, t);
+       CHECK_MONITORSTATE(lr, o, return);
+       do {
+               monitorLockRecord *wlr = lr->waiter;
+               if (!wlr)
+                       break;
+               pthread_cond_signal(&wlr->waitCond);
+               lr = wlr;
+       } while (!one);
+}
 
-               *exceptionptr =
-                       new_exception(string_java_lang_IllegalMonitorStateException);
+void interruptThread(java_lang_VMThread *thread)
+{
+       threadobject *t = (threadobject*) thread;
+
+       monitorLockRecord *lr = t->waiting;
+       if (lr) {
+               pthread_mutex_lock(&lr->waitLock);
+               if (t->waiting == lr) {
+                       t->waiting = NULL;
+                       pthread_cond_signal(&lr->waitCond);
+               }
+               pthread_mutex_unlock(&lr->waitLock);
+               return;
        }
+       
+       t->interrupted = 1;
 }
 
-static void notifyOneOrAll(threadobject *t, java_objectheader *o, bool one)
+bool interruptedThread()
 {
-       long r = getMetaLock(t, o);
-       monitorLockRecord *ownerLR = lockRecord(r);
-       int state = lockState(r);
-
-       if (state == LOCKED && ownerLR->owner == t) {
-               monitorLockRecord *q = ownerLR->queue;
-               while (q) {
-                       if (q->owner->ee.isWaitingForNotify) {
-                               q->owner->ee.isWaitingForNotify = false;
-                               if (one)
-                                       break;
-                       }
-                       q = q->queue;
-               }
-               releaseMetaLock(t, o, r);
+       threadobject *t = (threadobject*) THREADOBJECT;
+       long intr = t->interrupted;
+       t->interrupted = 0;
+       return intr;
+}
 
-       } else {
-               releaseMetaLock(t, o, r);
+bool isInterruptedThread(java_lang_VMThread *thread)
+{
+       threadobject *t = (threadobject*) thread;
+       return t->interrupted;
+}
+
+void sleepThread(s8 millis, s4 nanos)
+{
+       bool wasinterrupted;
+       threadobject *t = (threadobject*) THREADOBJECT;
+       monitorLockRecord *lr;
+       struct timespec wakeupTime;
+       calcAbsoluteTime(&wakeupTime, millis, nanos);
 
-               /* throw an exception */
+       lr = allocLockRecordSimple(t);
+       wasinterrupted = waitWithTimeout(t, lr, &wakeupTime);
+       recycleLockRecord(t, lr);
 
-               *exceptionptr =
-                       new_exception(string_java_lang_IllegalMonitorStateException);
-       }
+       if (wasinterrupted)
+               *exceptionptr = new_exception(string_java_lang_InterruptedException);
+}
+
+void yieldThread()
+{
+       sched_yield();
+}
+
+void setPriorityThread(thread *t, s4 priority)
+{
+       nativethread *info = &((threadobject*) t->vmThread)->info;
+       setPriority(info->tid, priority);
 }
 
-void wait_cond_for_object(java_objectheader *o, s8 time)
+void wait_cond_for_object(java_objectheader *o, s8 time, s4 nanos)
 {
        threadobject *t = (threadobject*) THREADOBJECT;
-       monitorWait(t, o, time);
+       monitorWait(t, o, time, nanos);
 }
 
 void signal_cond_for_object(java_objectheader *o)
index 2214f6a4f2bd1c97a8afc0f066d9b220f1d7d047..32a14ab22d486f49884d68998e127e4f3a138b73 100644 (file)
@@ -5,6 +5,7 @@
 #include "nat/java_lang_Object.h"
 #include "nat/java_lang_Throwable.h"
 #include "nat/java_lang_Thread.h"
+#include "nat/java_lang_VMThread.h"
 
 #if defined(__DARWIN__)
 #include <mach/mach.h>
 
 struct _threadobject;
 
-typedef struct monitorLockRecord {
-       struct _threadobject *owner;
+typedef struct _monitorLockRecord {
+       struct _threadobject *ownerThread;
+       java_objectheader *o;
        int lockCount;
-       long storedBits;
-       struct monitorLockRecord *queue;
-       struct monitorLockRecord *nextFree;
+       struct _monitorLockRecord *nextFree;
+       int queuers;
+       struct _monitorLockRecord *waiter, *incharge;
+       bool waiting;
+       sem_t queueSem;
+       pthread_mutex_t resolveLock, waitLock;
+       pthread_cond_t resolveWait, waitCond;
 } monitorLockRecord;
 
 struct _lockRecordPool;
@@ -35,23 +41,11 @@ typedef struct _lockRecordPool {
        monitorLockRecord lr[1];
 } lockRecordPool;
 
-#define INITIALLOCKRECORDS 8
-
 /* Monitor lock implementation */
 typedef struct {
-       pthread_mutex_t metaLockMutex;
-       pthread_cond_t metaLockCond;
-       bool gotMetaLockSlow;
-       bool bitsForGrab;
-       long metaLockBits;
-       struct _threadobject *succ;
-       pthread_mutex_t monitorLockMutex;
-       pthread_cond_t monitorLockCond;
-       bool isWaitingForNotify;
-
        monitorLockRecord *firstLR;
-       monitorLockRecord lr[INITIALLOCKRECORDS];
        lockRecordPool *lrpool;
+       int numlr;
 } ExecEnvironment;
 
 typedef struct {
@@ -67,36 +61,45 @@ typedef struct {
        pthread_cond_t joinCond;
 } nativethread;
 
+typedef java_lang_Thread thread;
+
 typedef struct _threadobject {
-       java_lang_Thread o;
+       java_lang_VMThread o;
        nativethread info;
        ExecEnvironment ee;
-} threadobject, thread;
 
-void monitorEnter(threadobject *, java_objectheader *);
-void monitorExit(threadobject *, java_objectheader *);
+       long interrupted;
+       monitorLockRecord *waiting;
+} threadobject;
+
+monitorLockRecord *monitorEnter(threadobject *, java_objectheader *);
+bool monitorExit(threadobject *, java_objectheader *);
 
 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);
+void wait_cond_for_object (java_objectheader *obj, s8 time, s4 nanos);
 
 void initThreadsEarly();
 void initThreads(u1 *stackbottom);
+void initObjectLock(java_objectheader *);
 void initLocks();
-void initThread(java_lang_Thread *);
+void initThread(java_lang_VMThread *);
 void joinAllThreads();
 
-bool aliveThread(java_lang_Thread *);
 void sleepThread(s8 millis, s4 nanos);
 void yieldThread();
 
+void interruptThread(java_lang_VMThread *);
+bool interruptedThread();
+bool isInterruptedThread(java_lang_VMThread *);
+
 #if !defined(HAVE___THREAD)
 extern pthread_key_t tkey_threadinfo;
-#define THREADOBJECT ((java_lang_Thread*) pthread_getspecific(tkey_threadinfo))
+#define THREADOBJECT ((java_lang_VMThread*) pthread_getspecific(tkey_threadinfo))
 #define THREADINFO (&((threadobject*) pthread_getspecific(tkey_threadinfo))->info)
 #else
 extern __thread threadobject *threadobj;
-#define THREADOBJECT ((java_lang_Thread*) threadobj)
+#define THREADOBJECT ((java_lang_VMThread*) threadobj)
 #define THREADINFO (&threadobj->info)
 #endif
 
index 7e079e9e365a017fb840dda44feb917dd3af1405..538bf874f50f3215045bfddf47271a9d6abbfb2b 100644 (file)
@@ -31,7 +31,7 @@
             Philipp Tomsich
                        Edwin Steiner
 
-   $Id: global.h 1326 2004-07-21 13:22:33Z twisti $
+   $Id: global.h 1377 2004-08-01 22:01:00Z stefan $
 
 */
 
@@ -47,6 +47,7 @@
 
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
 #include <pthread.h>
+#include <semaphore.h>
 #endif
 
 #define STATISTICS          /* if enabled collects program statistics         */
@@ -381,7 +382,7 @@ typedef struct {            /* NameAndType (Field or Method)                  */
 struct java_objectheader {              /* header for all objects             */
        vftbl_t *vftbl;                     /* pointer to virtual function table  */
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       long monitorBits;
+       void *monitorPtr;
 #endif
 };
 
index 9b30f45d238e7fbfb44f4c19aee4b1cbda120eb7..158ada12da52bf94e9c9286362a3234d56b4f16d 100644 (file)
@@ -1,58 +1,49 @@
 #ifndef _MACHINE_INSTR_H
 #define _MACHINE_INSTR_H
 
-static inline long
+static inline void
 __attribute__ ((unused))
-atomic_swap (volatile long *p, long val)
+atomic_add (volatile int *mem, int val)
 {
-  long ret, t1;
+    int temp;
 
   __asm__ __volatile__ (
-    "/* Inline atomic swap */\n"
-       "1:\t"
-       "ldq_l  %2,%4\n\t"
-       "mov    %3,%0\n\t"
-       "stq_c  %0,%1\n\t"
-       "beq    %0,2f\n\t"
-    ".subsection 1\n"
-    "2:\t"
-    "br 1b\n"
-    ".previous\n\t"
-    "3:\t"
+    "1:\t"
+    "ldl_l  %1,%3\n\t"
+    "addl   %1,%2,%1\n\t"
+    "stl_c  %1,%0\n\t"
+    "beq    %1,1b\n\t"
     "mb\n\t"
-    "/* End atomic swap */"
-       : "=&r"(t1), "=m"(*p), "=&r"(ret)
-       : "r"(val), "m"(*p));
-
-  return ret;
+    : "=m"(*mem), "=&r"(temp)
+    : "r"(val), "m"(*mem));
 }
 
 static inline long
 __attribute__ ((unused))
 compare_and_swap (volatile long *p, long oldval, long newval)
 {
-  long ret;
+  long ret, temp;
 
   __asm__ __volatile__ (
-    "/* Inline compare & swap */\n"
     "1:\t"
-    "ldq_l  %0,%4\n\t"
-    "cmpeq  %0,%2,%0\n\t"
-    "beq    %0,3f\n\t"
-    "mov    %3,%0\n\t"
-    "stq_c  %0,%1\n\t"
-    "beq    %0,2f\n\t"
-    ".subsection 1\n"
+    "ldq_l  %0,%5\n\t"
+    "cmpeq  %0,%3,%2\n\t"
+    "beq    %2,2f\n\t"
+    "mov    %4,%2\n\t"
+    "stq_c  %2,%1\n\t"
+    "beq    %2,1b\n\t"
     "2:\t"
-    "br 1b\n"
-    ".previous\n\t"
-    "3:\t"
     "mb\n\t"
-    "/* End compare & swap */"
-       : "=&r"(ret), "=m"(*p)
-       : "r"(oldval), "r"(newval), "m"(*p));
+    : "=&r"(ret), "=m"(*p), "=&r"(temp)
+    : "r"(oldval), "r"(newval), "m"(*p));
 
   return ret;
 }
 
+#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("wmb" : : : "memory");
+#define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("mb" : : : "memory");
+#define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
+#define MEMORY_BARRIER() __asm__ __volatile__ ( \
+               "mb" : : : "memory" );
+
 #endif
index 47a0a21b1625f2413ea971e34aa0e734c081a537..edbbb27d518e0016076ef36588ebf59c520ed4be 100644 (file)
@@ -1,26 +1,31 @@
 #ifndef _MACHINE_INSTR_H
 #define _MACHINE_INSTR_H
 
-static inline long
+static inline void
 __attribute__ ((unused))
-atomic_swap (volatile long *mem, long val)
+atomic_add (volatile int *mem, int val)
 {
-  __asm__ __volatile__ ("xchgl %2,%0"
-            : "=r" (val) : "0" (val), "m" (*mem));
-  return val;
+  __asm__ __volatile__ ("lock; addl %1,%0"
+                                               : "=m" (*mem) 
+                                               : "ir" (val), "m" (*mem));
 }
 
-static inline char
+static inline long
 __attribute__ ((unused))
-compare_and_swap (volatile long int *p, long int oldval, long int newval)
+compare_and_swap (volatile long *p, long oldval, long newval)
 {
-  char ret;
-  long int readval;
+  long ret;
 
-  __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
-                        : "=q" (ret), "=m" (*p), "=a" (readval)
-                        : "r" (newval), "m" (*p), "2" (oldval));
+  __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
+                        : "=a" (ret), "=m" (*p)
+                        : "r" (newval), "m" (*p), "0" (oldval));
   return ret;
 }
 
+#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
+#define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
+#define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
+#define MEMORY_BARRIER() __asm__ __volatile__ ( \
+               "lock; add $0, 0(%%esp)" : : : "memory" );
+
 #endif
index e8d3b5cdb0c2474bf5dc65c1887bc4b4fb14b0ca..7a46f3f2ec02f0924657c249eb6f329c28f7d84f 100644 (file)
@@ -31,6 +31,7 @@
 #include "nat/java_lang_Throwable.h"
 #include "nat/java_lang_Thread.h"
 #include "nat/java_lang_ThreadGroup.h"
+#include "nat/java_lang_VMThread.h"
 
 #include <pthread.h>
 #include <semaphore.h>
@@ -46,6 +47,8 @@
 
 #ifdef MUTEXSIM
 
+/* We need this for older MacOSX (10.1.x) */
+
 typedef struct {
        pthread_mutex_t mutex;
        pthread_t owner;
@@ -97,6 +100,16 @@ static void pthread_mutex_unlock_rec(pthread_mutex_rec_t *m)
 
 #endif /* MUTEXSIM */
 
+static void setPriority(pthread_t tid, int priority)
+{
+       struct sched_param schedp;
+       int policy;
+
+       pthread_getschedparam(tid, &policy, &schedp);
+       schedp.sched_priority = priority;
+       pthread_setschedparam(tid, policy, &schedp);
+}
+
 #include "machine-instr.h"
 
 static struct avl_table *criticaltree;
@@ -377,6 +390,10 @@ static void setthreadobject(threadobject *thread)
 #endif
 }
 
+static monitorLockRecord *dummyLR;
+
+static void initPools();
+
 /*
  * Initialize threads.
  */
@@ -404,17 +421,27 @@ initThreadsEarly()
 
        mainthreadobj = NEW(threadobject);
        memset(mainthreadobj, 0, sizeof(threadobject));
+       mainthreadobj->info.tid = pthread_self();
 #if !defined(HAVE___THREAD)
        pthread_key_create(&tkey_threadinfo, NULL);
 #endif
        setthreadobject(mainthreadobj);
+       initPools();
 
     criticaltree = avl_create(criticalcompare, NULL, NULL);
        thread_addstaticcritical();
        sem_init(&suspend_ack, 0, 0);
+
+       /* Every newly created object's monitorPtr points here so we save a check
+        * against NULL */
+       dummyLR = mem_alloc(sizeof(monitorLockRecord));
+       dummyLR->o = NULL;
+       dummyLR->ownerThread = NULL;
+       dummyLR->waiting = false;
 }
 
 static pthread_attr_t threadattr;
+
 static void freeLockRecordPools(lockRecordPool *);
 
 void
@@ -422,10 +449,13 @@ initThreads(u1 *stackbottom)
 {
        classinfo *threadclass;
        classinfo *threadgroupclass;
+       java_lang_String *threadname;
        java_lang_Thread *mainthread;
+       java_lang_ThreadGroup *threadgroup;
        threadobject *tempthread = mainthreadobj;
+       methodinfo *method;
 
-       threadclass = class_new(utf_new_char("java/lang/Thread"));
+       threadclass = class_new(utf_new_char("java/lang/VMThread"));
        class_load(threadclass);
        class_link(threadclass);
 
@@ -433,8 +463,12 @@ initThreads(u1 *stackbottom)
                throw_exception_exit();
 
        freeLockRecordPools(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 have been created
+        * at an earlier time */
        threadclass->instancesize = sizeof(threadobject);
 
+       /* Create a VMThread */
        mainthreadobj = (threadobject *) builtin_new(threadclass);
 
        if (!mainthreadobj)
@@ -443,36 +477,80 @@ initThreads(u1 *stackbottom)
        FREE(tempthread, threadobject);
        initThread(&mainthreadobj->o);
 
-#if !defined(HAVE___THREAD)
-       pthread_setspecific(tkey_threadinfo, mainthreadobj);
-#else
-       threadobj = mainthreadobj;
-#endif
+       setthreadobject(mainthreadobj);
 
-       mainthread = &mainthreadobj->o;
        initLocks();
        mainthreadobj->info.next = mainthreadobj;
        mainthreadobj->info.prev = mainthreadobj;
 
-       mainthread->name=javastring_new(utf_new_char("main"));
+       threadname = javastring_new(utf_new_char("main"));
 
        /* Allocate and init ThreadGroup */
        threadgroupclass = class_new(utf_new_char("java/lang/ThreadGroup"));
-       mainthread->group =
+       threadgroup =
                (java_lang_ThreadGroup *) native_new_and_init(threadgroupclass);
 
-       if (!mainthread->group)
+       if (!threadgroup)
+               throw_exception_exit();
+
+       /* Create a Thread */
+       threadclass = class_new(utf_new_char("java/lang/Thread"));
+       mainthread = (java_lang_Thread*) builtin_new(threadclass);
+       mainthreadobj->o.thread = mainthread;
+
+       if (!mainthread)
+               throw_exception_exit();
+
+       /* Call Thread constructor */
+       method = class_resolveclassmethod(threadclass,
+                                                                         utf_new_char("<init>"),
+                                                                         utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
+                                                                         threadclass,
+                                                                         true);
+
+       if (!method)
+               throw_exception_exit();
+
+       asm_calljavafunction(method, mainthread, mainthreadobj, threadname, (void*) 5);
+       if (*exceptionptr)
+               throw_exception_exit();
+
+       mainthread->group = threadgroup;
+       /* XXX This is a hack because the fourth argument was omitted */
+       mainthread->daemon = false;
+
+       /* Add mainthread to ThreadGroup */
+       method = class_resolveclassmethod(threadgroupclass,
+                                                                         utf_new_char("addThread"),
+                                                                         utf_new_char("(Ljava/lang/Thread;)V"),
+                                                                         threadgroupclass,
+                                                                         true);
+
+       if (!method)
                throw_exception_exit();
 
+       asm_calljavafunction(method, threadgroup, mainthread, NULL, NULL);
+       if (*exceptionptr)
+               throw_exception_exit();
+
+       /* TODO InheritableThreadLocal */
+
+       setPriority(pthread_self(), 5);
+
        pthread_attr_init(&threadattr);
        pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
 }
 
-void initThread(java_lang_Thread *t)
+void initThread(java_lang_VMThread *t)
 {
-       nativethread *info = &((threadobject*) t)->info;
+       threadobject *thread = (threadobject*) t;
+       nativethread *info = &thread->info;
+       info->tid = pthread_self();
        pthread_mutex_init(&info->joinMutex, NULL);
        pthread_cond_init(&info->joinCond, NULL);
+
+       thread->interrupted = 0;
+       thread->waiting = NULL;
 }
 
 static void initThreadLocks(threadobject *);
@@ -509,6 +587,8 @@ static void *threadstartup(void *t)
        startup = NULL;
        sem_post(psem);
 
+       setPriority(info->tid, thread->o.thread->priority);
+
        /* Find the run()V method and call it */
        method = class_resolveclassmethod(thread->o.header.vftbl->class,
                                                                          utf_new_char("run"),
@@ -524,6 +604,8 @@ static void *threadstartup(void *t)
                throw_exception();
        }
 
+       /* 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);
 
        pthread_mutex_lock(&threadlistlock);
@@ -539,13 +621,13 @@ static void *threadstartup(void *t)
        return NULL;
 }
 
-void startThread(threadobject *t)
+void startThread(thread *t)
 {
-       nativethread *info = &t->info;
+       nativethread *info = &((threadobject*) t->vmThread)->info;
        sem_t sem;
        startupinfo startup;
 
-       startup.thread = t;
+       startup.thread = (threadobject*) t->vmThread;
        startup.psem = &sem;
 
        sem_init(&sem, 0, 0);
@@ -553,16 +635,31 @@ void startThread(threadobject *t)
        if (pthread_create(&info->tid, &threadattr, threadstartup, &startup))
                panic("pthread_create failed");
 
-       /* Wait here until thread has entered itself into the thread list */
+       /* Wait here until the thread has entered itself into the thread list */
        sem_wait(&sem);
        sem_destroy(&sem);
 }
 
+/* At the end of the program, we wait for all running non-daemon threads to die
+ */
+
+static threadobject *findNonDaemon(threadobject *thread)
+{
+       while (thread != mainthreadobj) {
+               if (!thread->o.thread->daemon)
+                       return thread;
+               thread = thread->info.prev;
+       }
+
+       return NULL;
+}
+
 void joinAllThreads()
 {
+       threadobject *thread;
        pthread_mutex_lock(&threadlistlock);
-       while (mainthreadobj->info.prev != mainthreadobj) {
-               nativethread *info = &mainthreadobj->info.prev->info;
+       while ((thread = findNonDaemon(mainthreadobj->info.prev)) != NULL) {
+               nativethread *info = &thread->info;
                pthread_mutex_lock(&info->joinMutex);
                pthread_mutex_unlock(&threadlistlock);
                if (info->tid)
@@ -573,54 +670,34 @@ void joinAllThreads()
        pthread_mutex_unlock(&threadlistlock);
 }
 
-bool aliveThread(java_lang_Thread *t)
-{
-       return ((threadobject*) t)->info.tid != 0;
-}
-
-void sleepThread(s8 millis, s4 nanos)
-{
-       struct timespec tv;
-       tv.tv_sec = millis / 1000;
-       tv.tv_nsec = millis % 1000 * 1000000 + nanos;
-       do { } while (nanosleep(&tv, &tv) == EINTR);
-}
-
-void yieldThread()
-{
-       sched_yield();
-}
-
-static void timedCondWait(pthread_cond_t *cond, pthread_mutex_t *mutex, s8 millis)
+static void initLockRecord(monitorLockRecord *r, threadobject *t)
 {
-       struct timeval now;
-       struct timespec desttime;
-       gettimeofday(&now, NULL);
-       desttime.tv_sec = millis / 1000;
-       desttime.tv_nsec = millis % 1000 * 1000000;
-       pthread_cond_timedwait(cond, mutex, &desttime);
+       r->lockCount = 1;
+       r->ownerThread = t;
+       r->queuers = 0;
+       r->o = NULL;
+       r->waiter = NULL;
+       r->incharge = NULL;
+       r->waiting = false;
+       sem_init(&r->queueSem, 0, 0);
+       pthread_mutex_init(&r->resolveLock, NULL);
+       pthread_cond_init(&r->resolveWait, NULL);
+       pthread_mutex_init(&r->waitLock, NULL);
+       pthread_cond_init(&r->waitCond, NULL);
 }
 
+/* No lock record must ever be destroyed because there may still be references
+ * to it.
 
-#define NEUTRAL 0
-#define LOCKED 1
-#define WAITERS 2
-#define BUSY 3
-
-static void initExecutionEnvironment(ExecEnvironment *ee)
-{
-       pthread_mutex_init(&ee->metaLockMutex, NULL);
-       pthread_cond_init(&ee->metaLockCond, NULL);
-       pthread_mutex_init(&ee->monitorLockMutex, NULL);
-       pthread_cond_init(&ee->monitorLockCond, NULL);
-}
-
-static void initLockRecord(monitorLockRecord *r, threadobject *t)
+static void destroyLockRecord(monitorLockRecord *r)
 {
-       r->owner = t;
-       r->lockCount = 1;
-       r->queue = NULL;
+       sem_destroy(&r->queueSem);
+       pthread_mutex_destroy(&r->resolveLock);
+       pthread_cond_destroy(&r->resolveWait);
+       pthread_mutex_destroy(&r->waitLock);
+       pthread_cond_destroy(&r->waitCond);
 }
+*/
 
 void initLocks()
 {
@@ -629,34 +706,12 @@ void initLocks()
 
 static void initThreadLocks(threadobject *thread)
 {
-       int i;
-
-       initExecutionEnvironment(&thread->ee);
-       for (i=0; i<INITIALLOCKRECORDS; i++) {
-               monitorLockRecord *r = &thread->ee.lr[i];
-               initLockRecord(r, thread);
-               r->nextFree = &thread->ee.lr[i+1];
-       }
-       thread->ee.lr[i-1].nextFree = NULL;
-       thread->ee.firstLR = &thread->ee.lr[0];
-}
-
-static inline int lockState(long r)
-{
-       return (int) r & 3;
-}
-
-static inline void *lockRecord(long r)
-{
-       return (void*) (r & ~3L);
+       thread->ee.firstLR = NULL;
+       thread->ee.lrpool = NULL;
+       thread->ee.numlr = 0;
 }
 
-static inline long makeLockBits(void *r, long l)
-{
-       return ((long) r) | l;
-}
-
-static lockRecordPool *allocLockRecordPool(threadobject *thread, int size)
+static lockRecordPool *allocNewLockRecordPool(threadobject *thread, int size)
 {
        lockRecordPool *p = mem_alloc(sizeof(lockRecordPoolHeader) + sizeof(monitorLockRecord) * size);
        int i;
@@ -670,286 +725,362 @@ static lockRecordPool *allocLockRecordPool(threadobject *thread, int size)
        return p;
 }
 
-static void freeLockRecordPools(lockRecordPool *pool)
+#define INITIALLOCKRECORDS 8
+
+static pthread_mutex_t pool_lock;
+static lockRecordPool *global_pool;
+
+static void initPools()
 {
-       while (pool) {
-               lockRecordPool *n = pool->header.next;
-               mem_free(pool, sizeof(lockRecordPoolHeader) + sizeof(monitorLockRecord) * pool->header.size);
-               pool = n;
+       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;
+               
+               return pool;
        }
+       pthread_mutex_unlock(&pool_lock);
+
+       return allocNewLockRecordPool(t, size);
 }
 
-static monitorLockRecord *allocLockRecord(threadobject *t)
+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 = t->ee.firstLR;
 
        if (!r) {
-               int poolsize = t->ee.lrpool ? t->ee.lrpool->header.size * 2 : INITIALLOCKRECORDS * 2;
+               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;
        return r;
 }
 
-static void recycleLockRecord(threadobject *t, monitorLockRecord *r)
+static inline void recycleLockRecord(threadobject *t, monitorLockRecord *r)
 {
        r->nextFree = t->ee.firstLR;
        t->ee.firstLR = r;
 }
 
-static monitorLockRecord *appendToQueue(monitorLockRecord *queue, monitorLockRecord *lr)
-{
-       monitorLockRecord *queuestart = queue;
-       if (!queue)
-               return lr;
-       while (queue->queue)
-               queue = queue->queue;
-       queue->queue = lr;
-       return queuestart;
-}
-
-static monitorLockRecord *moveMyLRToFront(threadobject *t, monitorLockRecord *lr)
+#if 0
+static monitorLockRecord *allocLockRecord(threadobject *t, monitorLockRecord *lr)
 {
-       monitorLockRecord *pred = NULL;
-       monitorLockRecord *firstLR = lr;
-       while (lr->owner != t) {
-               pred = lr;
-               lr = lr->queue;
+       monitorLockRecord *r = allocLockRecordSimple(t);
+       if (r == lr) {
+               monitorLockRecord *r2 = allocLockRecordSimple(t);
+               recycleLockRecord(t, r);
+               r = r2;
        }
-       if (!pred)
-               return lr;
-       pred->queue = lr->queue;
-       lr->queue = firstLR;
-       lr->storedBits = firstLR->storedBits;
-       return lr;
+       return r;
 }
+#endif
 
-static long getMetaLockSlow(threadobject *t, long predBits);
-static void releaseMetaLockSlow(threadobject *t, long releaseBits);
-
-static long getMetaLock(threadobject *t, java_objectheader *o)
+void initObjectLock(java_objectheader *o)
 {
-       long busyBits = makeLockBits(t, BUSY);
-       long lockBits = atomic_swap(&o->monitorBits, busyBits);
-       return lockState(lockBits) != BUSY ? lockBits : getMetaLockSlow(t, lockBits);
+       o->monitorPtr = dummyLR;
 }
 
-static long getMetaLockSlow(threadobject *t, long predBits)
+static void queueOnLockRecord(monitorLockRecord *lr, java_objectheader *o)
 {
-       long bits;
-       threadobject *pred = lockRecord(predBits);
-       pthread_mutex_lock(&pred->ee.metaLockMutex);
-       if (!pred->ee.bitsForGrab) {
-               pred->ee.succ = t;
-               do {
-                       pthread_cond_wait(&pred->ee.metaLockCond, &pred->ee.metaLockMutex);
-               } while (!t->ee.gotMetaLockSlow);
-               t->ee.gotMetaLockSlow = false;
-               bits = t->ee.metaLockBits;
-       } else {
-               bits = pred->ee.metaLockBits;
-               pred->ee.bitsForGrab = false;
-               pthread_cond_signal(&pred->ee.metaLockCond);
-       }
-       pthread_mutex_unlock(&pred->ee.metaLockMutex);
-       return bits;
+       atomic_add(&lr->queuers, 1);
+       MEMORY_BARRIER_AFTER_ATOMIC();
+       if (lr->o == o)
+               sem_wait(&lr->queueSem);
+       atomic_add(&lr->queuers, -1);
 }
 
-static void releaseMetaLock(threadobject *t, java_objectheader *o, long releaseBits)
+static void freeLockRecord(monitorLockRecord *lr)
 {
-       long busyBits = makeLockBits(t, BUSY);
-       int locked = compare_and_swap(&o->monitorBits, busyBits, releaseBits) != 0;
-       
-       if (!locked)
-               releaseMetaLockSlow(t, releaseBits);
+       int q;
+       lr->o = NULL;
+       MEMORY_BARRIER();
+       q = lr->queuers;
+       while (q--)
+               sem_post(&lr->queueSem);
 }
 
-static void releaseMetaLockSlow(threadobject *t, long releaseBits)
+static inline void handleWaiter(monitorLockRecord *mlr, monitorLockRecord *lr)
 {
-       pthread_mutex_lock(&t->ee.metaLockMutex);
-       if (t->ee.succ) {
-               assert(!t->ee.succ->ee.bitsForGrab);
-               assert(!t->ee.bitsForGrab);
-               assert(!t->ee.succ->ee.gotMetaLockSlow);
-               t->ee.succ->ee.metaLockBits = releaseBits;
-               t->ee.succ->ee.gotMetaLockSlow = true;
-               t->ee.succ = NULL;
-               pthread_cond_signal(&t->ee.metaLockCond);
-       } else {
-               t->ee.metaLockBits = releaseBits;
-               t->ee.bitsForGrab = true;
-               do {
-                       pthread_cond_wait(&t->ee.metaLockCond, &t->ee.metaLockMutex);
-               } while (t->ee.bitsForGrab);
-       }
-       pthread_mutex_unlock(&t->ee.metaLockMutex);
+       if (lr->waiting)
+               mlr->waiter = lr;
 }
 
-static void monitorEnterSlow(threadobject *t, java_objectheader *o, long r);
-
-void monitorEnter(threadobject *t, java_objectheader *o)
+monitorLockRecord *monitorEnter(threadobject *t, java_objectheader *o)
 {
-       long r = getMetaLock(t, o);
-       int state = lockState(r);
-
-       if (state == NEUTRAL) {
-               monitorLockRecord *lr = allocLockRecord(t);
-               lr->storedBits = r;
-               releaseMetaLock(t, o, makeLockBits(lr, LOCKED));
-       } else if (state == LOCKED) {
-               monitorLockRecord *ownerLR = lockRecord(r);
-               if (ownerLR->owner == t) {
-                       ownerLR->lockCount++;
-                       releaseMetaLock(t, o, r);
+       for (;;) {
+               monitorLockRecord *lr = o->monitorPtr;
+               if (lr->o != o) {
+                       monitorLockRecord *nlr, *mlr = allocLockRecordSimple(t);
+                       mlr->o = o;
+                       MEMORY_BARRIER_BEFORE_ATOMIC();
+                       nlr = (void*) compare_and_swap((long*) &o->monitorPtr, (long) lr, (long) mlr);
+                       if (nlr == lr) {
+                               if (mlr == lr || lr->o != o) {
+                                       handleWaiter(mlr, lr);
+                                       return mlr;
+                               } else {
+                                       void *incharge;
+                                       pthread_mutex_lock(&mlr->resolveLock);
+                                       incharge = mlr->incharge;
+                                       mlr->incharge = lr;
+                                       pthread_mutex_unlock(&mlr->resolveLock);
+                                       if (incharge)
+                                               pthread_cond_signal(&mlr->resolveWait);
+                               }
+                               while (lr->o == o)
+                                       queueOnLockRecord(lr, o);
+                               mlr->incharge = NULL;
+                               handleWaiter(mlr, lr);
+                               return mlr;
+                       }
+                       freeLockRecord(mlr);
+                       recycleLockRecord(t, mlr);
+                       queueOnLockRecord(nlr, o);
                } else {
-                       monitorLockRecord *lr = allocLockRecord(t);
-                       ownerLR->queue = appendToQueue(ownerLR->queue, lr);
-                       monitorEnterSlow(t, o, r);
+                       if (lr->ownerThread == t) {
+                               lr->lockCount++;
+                               return lr;
+                       }
+                       queueOnLockRecord(lr, o);
                }
-       } else if (state == WAITERS) {
-               monitorLockRecord *lr = allocLockRecord(t);
-               monitorLockRecord *firstWaiterLR = lockRecord(r);
-               lr->queue = firstWaiterLR;
-               lr->storedBits = firstWaiterLR->storedBits;
-               releaseMetaLock(t, o, makeLockBits(lr, LOCKED));
        }
 }
 
-static void monitorEnterSlow(threadobject *t, java_objectheader *o, long r)
+static monitorLockRecord *grabLockRecordInCharge(monitorLockRecord *lr)
 {
-       monitorLockRecord *lr;
-       while (lockState(r) == LOCKED) {
-               pthread_mutex_lock(&t->ee.monitorLockMutex);
-               releaseMetaLock(t, o, r);
-               pthread_cond_wait(&t->ee.monitorLockCond, &t->ee.monitorLockMutex);
-               pthread_mutex_unlock(&t->ee.monitorLockMutex);
-               r = getMetaLock(t, o);
+       pthread_mutex_lock(&lr->resolveLock);
+       if (!lr->incharge) {
+               lr->incharge = lr;
+               pthread_cond_wait(&lr->resolveWait, &lr->resolveLock);
        }
-       assert(lockState(r) == WAITERS);
-       lr = moveMyLRToFront(t, lockRecord(r));
-       releaseMetaLock(t, o, makeLockBits(lr, LOCKED));
+       pthread_mutex_unlock(&lr->resolveLock);
+       return lr->incharge;
 }
 
-static void monitorExitSlow(threadobject *t, java_objectheader *o, monitorLockRecord *lr);
-
-void monitorExit(threadobject *t, java_objectheader *o)
+static void wakeWaiters(monitorLockRecord *lr)
 {
-       long r = getMetaLock(t, o);
-       monitorLockRecord *ownerLR = lockRecord(r);
-       int state = lockState(r);
-
-       if (state == LOCKED && ownerLR->owner == t) {
-               assert(ownerLR->lockCount >= 1);
-               if (ownerLR->lockCount == 1) {
-                       if (ownerLR->queue == NULL) {
-                               assert(lockState(ownerLR->storedBits) == NEUTRAL);
-                               releaseMetaLock(t, o, ownerLR->storedBits);
-                       } else {
-                               ownerLR->queue->storedBits = ownerLR->storedBits;
-                               monitorExitSlow(t, o, ownerLR->queue);
-                               ownerLR->queue = NULL;
-                       }
-                       recycleLockRecord(t, ownerLR);
-               } else {
-                       ownerLR->lockCount--;
-                       releaseMetaLock(t, o, r);
-               }
+       do {
+               int q = lr->queuers;
+               while (q--)
+                       sem_post(&lr->queueSem);
+               lr = lr->waiter;
+       } while (lr);
+}
 
-       } else {
-               releaseMetaLock(t, o, r);
+#define GRAB_LR(lr,t) \
+    if (lr->ownerThread != t) { \
+               lr = grabLockRecordInCharge(lr); \
+               assert(lr->ownerThread == t); \
+       }
 
-               /* throw an exception */
+#define CHECK_MONITORSTATE(lr,mo,a) \
+    if (lr->o != mo) { \
+               *exceptionptr = new_exception(string_java_lang_IllegalMonitorStateException); \
+               a; \
+       }
 
-               *exceptionptr =
-                       new_exception(string_java_lang_IllegalMonitorStateException);
+bool monitorExit(threadobject *t, java_objectheader *o)
+{
+       monitorLockRecord *lr = o->monitorPtr;
+       GRAB_LR(lr, t);
+       CHECK_MONITORSTATE(lr, o, return false);
+       if (lr->lockCount > 1) {
+               lr->lockCount--;
+               return true;
+       }
+       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;
+                       nlr->waiter = wlr;
+                       STORE_ORDER_BARRIER();
+               } else
+                       wakeWaiters(wlr);
+               lr->waiter = NULL;
        }
+       freeLockRecord(lr);
+       recycleLockRecord(t, lr);
+       return true;
 }
 
-static threadobject *wakeupEE(monitorLockRecord *lr)
+static void removeFromWaiters(monitorLockRecord *lr, monitorLockRecord *wlr)
 {
-       while (lr->queue && lr->queue->owner->ee.isWaitingForNotify)
-               lr = lr->queue;
-       return lr->owner;
+       do {
+               if (lr->waiter == wlr) {
+                       lr->waiter = wlr->waiter;
+                       break;
+               }
+               lr = lr->waiter;
+       } while (lr);
+}
+
+bool waitWithTimeout(threadobject *t, monitorLockRecord *lr, struct timespec *wakeupTime)
+{
+       bool wasinterrupted;
+
+       pthread_mutex_lock(&lr->waitLock);
+       t->waiting = lr;
+       if (wakeupTime->tv_sec || wakeupTime->tv_nsec)
+               pthread_cond_timedwait(&lr->waitCond, &lr->waitLock, wakeupTime);
+       else
+               pthread_cond_wait(&lr->waitCond, &lr->waitLock);
+       wasinterrupted = t->waiting == NULL;
+       t->waiting = NULL;
+       pthread_mutex_unlock(&lr->waitLock);
+       return wasinterrupted;
 }
 
-static void monitorExitSlow(threadobject *t, java_objectheader *o, monitorLockRecord *lr)
+static void calcAbsoluteTime(struct timespec *tm, s8 millis, s4 nanos)
 {
-       threadobject *wakeEE = wakeupEE(lr);
-       if (wakeEE) {
-               pthread_mutex_lock(&wakeEE->ee.monitorLockMutex);
-               releaseMetaLock(t, o, makeLockBits(lr, WAITERS));
-               pthread_cond_signal(&wakeEE->ee.monitorLockCond);
-               pthread_mutex_unlock(&wakeEE->ee.monitorLockMutex);
+       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 {
-               releaseMetaLock(t, o, makeLockBits(lr, WAITERS));
+               tm->tv_sec = 0;
+               tm->tv_nsec = 0;
        }
 }
 
-void monitorWait(threadobject *t, java_objectheader *o, s8 millis)
+void monitorWait(threadobject *t, java_objectheader *o, s8 millis, s4 nanos)
 {
-       long r = getMetaLock(t, o);
-       monitorLockRecord *ownerLR = lockRecord(r);
-       int state = lockState(r);
-
-       if (state == LOCKED && ownerLR->owner == t) {
-               pthread_mutex_lock(&t->ee.monitorLockMutex);
-               t->ee.isWaitingForNotify = true;
-               monitorExitSlow(t, o, ownerLR);
-               if (millis == -1)
-                       pthread_cond_wait(&t->ee.monitorLockCond, &t->ee.monitorLockMutex);
-               else
-                       timedCondWait(&t->ee.monitorLockCond, &t->ee.monitorLockMutex, millis);
-               t->ee.isWaitingForNotify = false;
-               pthread_mutex_unlock(&t->ee.monitorLockMutex);
-               r = getMetaLock(t, o);
-               monitorEnterSlow(t, o, r);
+       bool wasinterrupted;
+       struct timespec wakeupTime;
+       monitorLockRecord *mlr, *lr = o->monitorPtr;
+       GRAB_LR(lr, t);
+       CHECK_MONITORSTATE(lr, o, return);
 
-       } else {
-               releaseMetaLock(t, o, r);
+       calcAbsoluteTime(&wakeupTime, millis, nanos);
+       
+       if (lr->waiter)
+               wakeWaiters(lr->waiter);
+       lr->waiting = true;
+       STORE_ORDER_BARRIER();
+       freeLockRecord(lr);
+       wasinterrupted = waitWithTimeout(t, lr, &wakeupTime);
+       mlr = monitorEnter(t, o);
+       removeFromWaiters(mlr, lr);
+       mlr->lockCount = lr->lockCount;
+       lr->lockCount = 1;
+       lr->waiting = false;
+       lr->waiter = NULL;
+       recycleLockRecord(t, lr);
+
+       if (wasinterrupted)
+               *exceptionptr = new_exception(string_java_lang_InterruptedException);
+}
 
-               /* throw an exception */
+static void notifyOneOrAll(threadobject *t, java_objectheader *o, bool one)
+{
+       monitorLockRecord *lr = o->monitorPtr;
+       GRAB_LR(lr, t);
+       CHECK_MONITORSTATE(lr, o, return);
+       do {
+               monitorLockRecord *wlr = lr->waiter;
+               if (!wlr)
+                       break;
+               pthread_cond_signal(&wlr->waitCond);
+               lr = wlr;
+       } while (!one);
+}
 
-               *exceptionptr =
-                       new_exception(string_java_lang_IllegalMonitorStateException);
+void interruptThread(java_lang_VMThread *thread)
+{
+       threadobject *t = (threadobject*) thread;
+
+       monitorLockRecord *lr = t->waiting;
+       if (lr) {
+               pthread_mutex_lock(&lr->waitLock);
+               if (t->waiting == lr) {
+                       t->waiting = NULL;
+                       pthread_cond_signal(&lr->waitCond);
+               }
+               pthread_mutex_unlock(&lr->waitLock);
+               return;
        }
+       
+       t->interrupted = 1;
 }
 
-static void notifyOneOrAll(threadobject *t, java_objectheader *o, bool one)
+bool interruptedThread()
 {
-       long r = getMetaLock(t, o);
-       monitorLockRecord *ownerLR = lockRecord(r);
-       int state = lockState(r);
-
-       if (state == LOCKED && ownerLR->owner == t) {
-               monitorLockRecord *q = ownerLR->queue;
-               while (q) {
-                       if (q->owner->ee.isWaitingForNotify) {
-                               q->owner->ee.isWaitingForNotify = false;
-                               if (one)
-                                       break;
-                       }
-                       q = q->queue;
-               }
-               releaseMetaLock(t, o, r);
+       threadobject *t = (threadobject*) THREADOBJECT;
+       long intr = t->interrupted;
+       t->interrupted = 0;
+       return intr;
+}
 
-       } else {
-               releaseMetaLock(t, o, r);
+bool isInterruptedThread(java_lang_VMThread *thread)
+{
+       threadobject *t = (threadobject*) thread;
+       return t->interrupted;
+}
+
+void sleepThread(s8 millis, s4 nanos)
+{
+       bool wasinterrupted;
+       threadobject *t = (threadobject*) THREADOBJECT;
+       monitorLockRecord *lr;
+       struct timespec wakeupTime;
+       calcAbsoluteTime(&wakeupTime, millis, nanos);
 
-               /* throw an exception */
+       lr = allocLockRecordSimple(t);
+       wasinterrupted = waitWithTimeout(t, lr, &wakeupTime);
+       recycleLockRecord(t, lr);
 
-               *exceptionptr =
-                       new_exception(string_java_lang_IllegalMonitorStateException);
-       }
+       if (wasinterrupted)
+               *exceptionptr = new_exception(string_java_lang_InterruptedException);
+}
+
+void yieldThread()
+{
+       sched_yield();
+}
+
+void setPriorityThread(thread *t, s4 priority)
+{
+       nativethread *info = &((threadobject*) t->vmThread)->info;
+       setPriority(info->tid, priority);
 }
 
-void wait_cond_for_object(java_objectheader *o, s8 time)
+void wait_cond_for_object(java_objectheader *o, s8 time, s4 nanos)
 {
        threadobject *t = (threadobject*) THREADOBJECT;
-       monitorWait(t, o, time);
+       monitorWait(t, o, time, nanos);
 }
 
 void signal_cond_for_object(java_objectheader *o)
index 2214f6a4f2bd1c97a8afc0f066d9b220f1d7d047..32a14ab22d486f49884d68998e127e4f3a138b73 100644 (file)
@@ -5,6 +5,7 @@
 #include "nat/java_lang_Object.h"
 #include "nat/java_lang_Throwable.h"
 #include "nat/java_lang_Thread.h"
+#include "nat/java_lang_VMThread.h"
 
 #if defined(__DARWIN__)
 #include <mach/mach.h>
 
 struct _threadobject;
 
-typedef struct monitorLockRecord {
-       struct _threadobject *owner;
+typedef struct _monitorLockRecord {
+       struct _threadobject *ownerThread;
+       java_objectheader *o;
        int lockCount;
-       long storedBits;
-       struct monitorLockRecord *queue;
-       struct monitorLockRecord *nextFree;
+       struct _monitorLockRecord *nextFree;
+       int queuers;
+       struct _monitorLockRecord *waiter, *incharge;
+       bool waiting;
+       sem_t queueSem;
+       pthread_mutex_t resolveLock, waitLock;
+       pthread_cond_t resolveWait, waitCond;
 } monitorLockRecord;
 
 struct _lockRecordPool;
@@ -35,23 +41,11 @@ typedef struct _lockRecordPool {
        monitorLockRecord lr[1];
 } lockRecordPool;
 
-#define INITIALLOCKRECORDS 8
-
 /* Monitor lock implementation */
 typedef struct {
-       pthread_mutex_t metaLockMutex;
-       pthread_cond_t metaLockCond;
-       bool gotMetaLockSlow;
-       bool bitsForGrab;
-       long metaLockBits;
-       struct _threadobject *succ;
-       pthread_mutex_t monitorLockMutex;
-       pthread_cond_t monitorLockCond;
-       bool isWaitingForNotify;
-
        monitorLockRecord *firstLR;
-       monitorLockRecord lr[INITIALLOCKRECORDS];
        lockRecordPool *lrpool;
+       int numlr;
 } ExecEnvironment;
 
 typedef struct {
@@ -67,36 +61,45 @@ typedef struct {
        pthread_cond_t joinCond;
 } nativethread;
 
+typedef java_lang_Thread thread;
+
 typedef struct _threadobject {
-       java_lang_Thread o;
+       java_lang_VMThread o;
        nativethread info;
        ExecEnvironment ee;
-} threadobject, thread;
 
-void monitorEnter(threadobject *, java_objectheader *);
-void monitorExit(threadobject *, java_objectheader *);
+       long interrupted;
+       monitorLockRecord *waiting;
+} threadobject;
+
+monitorLockRecord *monitorEnter(threadobject *, java_objectheader *);
+bool monitorExit(threadobject *, java_objectheader *);
 
 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);
+void wait_cond_for_object (java_objectheader *obj, s8 time, s4 nanos);
 
 void initThreadsEarly();
 void initThreads(u1 *stackbottom);
+void initObjectLock(java_objectheader *);
 void initLocks();
-void initThread(java_lang_Thread *);
+void initThread(java_lang_VMThread *);
 void joinAllThreads();
 
-bool aliveThread(java_lang_Thread *);
 void sleepThread(s8 millis, s4 nanos);
 void yieldThread();
 
+void interruptThread(java_lang_VMThread *);
+bool interruptedThread();
+bool isInterruptedThread(java_lang_VMThread *);
+
 #if !defined(HAVE___THREAD)
 extern pthread_key_t tkey_threadinfo;
-#define THREADOBJECT ((java_lang_Thread*) pthread_getspecific(tkey_threadinfo))
+#define THREADOBJECT ((java_lang_VMThread*) pthread_getspecific(tkey_threadinfo))
 #define THREADINFO (&((threadobject*) pthread_getspecific(tkey_threadinfo))->info)
 #else
 extern __thread threadobject *threadobj;
-#define THREADOBJECT ((java_lang_Thread*) threadobj)
+#define THREADOBJECT ((java_lang_VMThread*) threadobj)
 #define THREADINFO (&threadobj->info)
 #endif