Index: vm/include/open/hythread_ext.h =================================================================== --- vm/include/open/hythread_ext.h (revision 474428) +++ vm/include/open/hythread_ext.h (working copy) @@ -311,6 +311,7 @@ #define TM_THREAD_STATE_SLEEPING JVMTI_THREAD_STATE_SLEEPING // 0x0040 Thread is sleeping -- Thread.sleep(long). #define TM_THREAD_STATE_IN_MONITOR_WAIT JVMTI_THREAD_STATE_IN_OBJECT_WAIT // 0x0100 Thread is waiting on an object monitor -- Object.wait. #define TM_THREAD_STATE_PARKED JVMTI_THREAD_STATE_PARKED // 0x0200 Thread is parked, for example: LockSupport.park, LockSupport.parkUtil and LockSupport.parkNanos. +#define TM_THREAD_STATE_UNPARKED 0x0800 // 0x0800 Thread is unparked, to track staled unparks; #define TM_THREAD_STATE_SUSPENDED JVMTI_THREAD_STATE_SUSPENDED // 0x100000 Thread suspended. java.lang.Thread.suspend() or a JVMTI suspend function (such as SuspendThread) has been called on the thread. If this bit is set, the other bits refer to the thread state before suspension. #define TM_THREAD_STATE_INTERRUPTED JVMTI_THREAD_STATE_INTERRUPTED // 0x200000 Thread has been interrupted. #define TM_THREAD_STATE_IN_NATIVE JVMTI_THREAD_STATE_IN_NATIVE // 0x400000 Thread is in native code--that is, a native method is running which has not called back into the VM or Java programming language code. Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/Thread.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/java/lang/Thread.java (revision 474428) +++ vm/vmcore/src/kernel_classes/javasrc/java/lang/Thread.java (working copy) @@ -739,11 +739,18 @@ throw new OutOfMemoryError("Failed to create new thread"); } + boolean interrupted = false; while(!this.started) { try { lock.wait(); - } catch (InterruptedException e) {/* continue waiting*/} + } catch (InterruptedException e) { + interrupted = true; + } } + + if (interrupted) { + Thread.currentThread().interrupt(); + } } } @@ -827,10 +834,12 @@ throw new NullPointerException("The argument is null!"); } synchronized (lock) { - int status = VMThreadManager.stop(this, throwable); - if (status != VMThreadManager.TM_ERROR_NONE) { - throw new InternalError( - "Thread Manager internal error " + status); + if (isAlive()) { + int status = VMThreadManager.stop(this, throwable); + if (status != VMThreadManager.TM_ERROR_NONE) { + throw new InternalError( + "Thread Manager internal error " + status); + } } } } Index: vm/thread/src/thread_native_basic.c =================================================================== --- vm/thread/src/thread_native_basic.c (revision 474428) +++ vm/thread/src/thread_native_basic.c (working copy) @@ -426,7 +426,14 @@ // Report error in case current thread is not attached if (!thread) return TM_ERROR_UNATTACHED_THREAD; - status = sem_wait_impl(thread->sleep_event, millis, nanos, interruptable); + hymutex_lock(thread->mutex); + + thread->state |= TM_THREAD_STATE_SLEEPING; + status = condvar_wait_impl(thread->condition, thread->mutex, millis, nanos, interruptable); + thread->state &= ~TM_THREAD_STATE_SLEEPING; + //status = sem_wait_impl(thread->sleep_event, millis, nanos, interruptable); + + hymutex_unlock(thread->mutex); return (status == TM_ERROR_INTERRUPT && interruptable) ? TM_ERROR_INTERRUPT : TM_ERROR_NONE; } @@ -599,7 +606,7 @@ return TM_ERROR_OUT_OF_MEMORY; } } - + fast_thread_array[thread->thread_id] = thread; thread->group = group; @@ -648,8 +655,13 @@ assert (status == TM_ERROR_NONE); status = hysem_create(&ptr->sleep_event, 0, 1); assert (status == TM_ERROR_NONE); + status = hymutex_create(&ptr->mutex, TM_MUTEX_NESTED); + assert (status == TM_ERROR_NONE); + status = hycond_create(&ptr->condition); + assert (status == TM_ERROR_NONE); ptr->state = TM_THREAD_STATE_ALLOCATED; + return ptr; } Index: vm/thread/src/thread_native_fat_monitor.c =================================================================== --- vm/thread/src/thread_native_fat_monitor.c (revision 474428) +++ vm/thread/src/thread_native_fat_monitor.c (working copy) @@ -203,10 +203,19 @@ if (status != TM_ERROR_NONE) return status; set_suspend_disable(saved_disable_count); -#else +#else + hymutex_lock(self->mutex); + self->monitor = mon_ptr; + self->state |= TM_THREAD_STATE_IN_MONITOR_WAIT; + + hymutex_unlock(self->mutex); //printf("starting wait: %x, %x \n", mon_ptr->condition, hythread_self()); status = condvar_wait_impl(mon_ptr->condition, mon_ptr->mutex, ms, nano, interruptable); //printf("finishing wait: %x, %x \n", mon_ptr->condition, hythread_self()); + hymutex_lock(self->mutex); + self->state &= ~TM_THREAD_STATE_IN_MONITOR_WAIT; + self->monitor = 0; + hymutex_unlock(self->mutex); #endif if(self->suspend_request) { hymutex_unlock(mon_ptr->mutex); Index: vm/thread/src/thread_native_interrupt.c =================================================================== --- vm/thread/src/thread_native_interrupt.c (revision 474428) +++ vm/thread/src/thread_native_interrupt.c (working copy) @@ -28,6 +28,8 @@ #include "thread_private.h" #include +static int interrupter_thread_function(void *args); + /** * Interrupt a thread. * @@ -40,15 +42,58 @@ */ void VMCALL hythread_interrupt(hythread_t thread) { IDATA status; + hymutex_lock(thread->mutex); thread->state |= TM_THREAD_STATE_INTERRUPTED; - // If thread was doing any kind of wait, notify it. - if (thread->current_condition) { - status=hycond_notify_all(thread->current_condition); - assert (status == TM_ERROR_NONE); + if (thread == tm_self_tls) { + hymutex_unlock(thread->mutex); + fflush(NULL); + return; } + + if (thread->state & (TM_THREAD_STATE_PARKED | TM_THREAD_STATE_SLEEPING)) { + // If thread was doing any kind of wait, notify it. + if (thread->current_condition) { + status=hycond_notify_all(thread->current_condition); + assert (status == TM_ERROR_NONE); + } + + } else if (thread->state & TM_THREAD_STATE_IN_MONITOR_WAIT) { + if (thread->monitor && (hythread_monitor_try_enter(thread->monitor) == TM_ERROR_NONE)) { + hythread_monitor_notify_all(thread->monitor); + hythread_monitor_exit(thread->monitor); + } else { + status = hythread_create(&thread->interrupter, 0, 0, 0, interrupter_thread_function, (void *)thread); + assert (status == TM_ERROR_NONE); + } + } + + hymutex_unlock(thread->mutex); } +static int interrupter_thread_function(void *args) { + hythread_t thread = (hythread_t)args; + hythread_monitor_t monitor = NULL; + hymutex_lock(thread->mutex); + + if (thread->monitor) { + monitor = thread->monitor; + } else { + hymutex_unlock(thread->mutex); + hythread_exit(NULL); + return 0; + } + + hymutex_unlock(thread->mutex); + + + hythread_monitor_enter(monitor); + hythread_monitor_notify_all(monitor); + + hythread_exit(monitor); + return 0; +} + /** * Returns interrupted status and clear interrupted flag. * @@ -56,9 +101,12 @@ * @returns TM_ERROR_INTERRUPT if thread was interruped, TM_ERROR_NONE otherwise */ UDATA VMCALL hythread_clear_interrupted_other(hythread_t thread) { - int interrupted = thread->state & TM_THREAD_STATE_INTERRUPTED; - thread->state &= ~TM_THREAD_STATE_INTERRUPTED; - return interrupted?TM_ERROR_INTERRUPT:TM_ERROR_NONE; + int interrupted; + hymutex_lock(thread->mutex); + interrupted = thread->state & TM_THREAD_STATE_INTERRUPTED; + thread->state &= ~TM_THREAD_STATE_INTERRUPTED; + hymutex_unlock(thread->mutex); + return interrupted?TM_ERROR_INTERRUPT:TM_ERROR_NONE; } /** Index: vm/thread/src/thread_native_park.c =================================================================== --- vm/thread/src/thread_native_park.c (revision 474428) +++ vm/thread/src/thread_native_park.c (working copy) @@ -47,16 +47,28 @@ * @see hythread_unpark */ IDATA VMCALL hythread_park(I_64 millis, IDATA nanos) { - IDATA status; + IDATA status = 0; hythread_t t = tm_self_tls; assert(t); - status = hysem_wait_interruptable(t->park_event, millis, nanos); + + hymutex_lock(t->mutex); + + if (t->state & TM_THREAD_STATE_UNPARKED) { + t->state &= ~TM_THREAD_STATE_UNPARKED; + hymutex_unlock(t->mutex); + return (t->state & TM_THREAD_STATE_INTERRUPTED) ? TM_ERROR_INTERRUPT : TM_ERROR_NONE; + } + + status = hycond_wait_interruptable(t->condition, t->mutex, millis, nanos); + + //status = hysem_wait_interruptable(t->park_event, millis, nanos); //the status should be restored for j.u.c.LockSupport //// if (status == TM_ERROR_INTERRUPT) { t->state |= TM_THREAD_STATE_INTERRUPTED; } - + + hymutex_unlock(t->mutex); return status; } @@ -72,11 +84,18 @@ * @see hythread_park */ void VMCALL hythread_unpark(hythread_t thread) { - IDATA UNUSED status; if(thread == NULL) { return; } - status = hysem_post(thread->park_event); - assert(status == TM_ERROR_NONE); + hymutex_lock(thread->mutex); + + if (thread->state & TM_THREAD_STATE_PARKED) { + thread->state &= ~TM_THREAD_STATE_PARKED; + hycond_notify_all(thread->condition); + } else { + thread->state |= TM_THREAD_STATE_UNPARKED; + } + + hymutex_unlock(thread->mutex); } Index: vm/thread/src/thread_private.h =================================================================== --- vm/thread/src/thread_private.h (revision 474428) +++ vm/thread/src/thread_private.h (working copy) @@ -251,8 +251,18 @@ /** * Event reserved for sleeping threads. */ - hysem_t sleep_event; + hysem_t sleep_event; + /* + * Thread local lock, used to serialize thread state; + */ + hymutex_t mutex; + + /* + * Conditional variable used to implement wait function for sleep/park; + */ + hycond_t condition; + /** * Event reserved for threads that invoke join. */ @@ -262,8 +272,17 @@ * Current conditional variable thread is waiting on (used for interrupting) */ hycond_t current_condition; - - + + /** + * Current monitor this thread is waiting on; + */ + hythread_monitor_t monitor; + + /** + * thread run to interrupt this one; + */ + hythread_t interrupter; + // State /**