Return-Path: Delivered-To: apmail-harmony-commits-archive@www.apache.org Received: (qmail 72487 invoked from network); 6 Jun 2007 17:40:42 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 6 Jun 2007 17:40:41 -0000 Received: (qmail 26011 invoked by uid 500); 6 Jun 2007 17:40:41 -0000 Delivered-To: apmail-harmony-commits-archive@harmony.apache.org Received: (qmail 25988 invoked by uid 500); 6 Jun 2007 17:40:40 -0000 Mailing-List: contact commits-help@harmony.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@harmony.apache.org Delivered-To: mailing list commits@harmony.apache.org Received: (qmail 25949 invoked by uid 99); 6 Jun 2007 17:40:40 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 06 Jun 2007 10:40:40 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 06 Jun 2007 10:40:36 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 1E29B1A981D; Wed, 6 Jun 2007 10:40:16 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r544896 - in /harmony/enhanced/drlvm/trunk/vm: include/open/hythread_ext.h tests/smoke/thread/InterruptWait.java thread/src/thread_native_fat_monitor.c thread/src/thread_native_interrupt.c Date: Wed, 06 Jun 2007 17:40:15 -0000 To: commits@harmony.apache.org From: wjwashburn@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070606174016.1E29B1A981D@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: wjwashburn Date: Wed Jun 6 10:40:15 2007 New Revision: 544896 URL: http://svn.apache.org/viewvc?view=rev&rev=544896 Log: harmony-3641 bug is fixed. This patch substantially reduces the rate of spurious interrupts. "build test2" passes for the most part Added: harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/InterruptWait.java (with props) Modified: harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_fat_monitor.c harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c Modified: harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h?view=diff&rev=544896&r1=544895&r2=544896 ============================================================================== --- harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h (original) +++ harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h Wed Jun 6 10:40:15 2007 @@ -309,6 +309,9 @@ void VMCALL hythread_native_resource_is_live(U_32); void VMCALL hythread_reclaim_resources(); +IDATA VMCALL hythread_monitor_interrupt_wait(hythread_monitor_t mon_ptr, + hythread_t thread); + //@} /** @name State query */ Added: harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/InterruptWait.java URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/InterruptWait.java?view=auto&rev=544896 ============================================================================== --- harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/InterruptWait.java (added) +++ harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/InterruptWait.java Wed Jun 6 10:40:15 2007 @@ -0,0 +1,87 @@ +package thread; + +public class InterruptWait { + static boolean success = true; + + public static void main(String[] args) { + final Lock lock = new Lock(); + final Thread[] pool = new Thread[10]; + + for (int i = 0; i < pool.length; i++) { + pool[i] = new Thread() { + public void run() { + lock.lock(); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + System.out.println(this.toString() + " interrupted while working!"); + success = false; + } + lock.unlock(); + } + }; + } + for (int i = 0; i < pool.length; i++) { + pool[i].start(); + } + for (int i = 0; i < pool.length; i++) { + try { + pool[i].join(); + } catch (InterruptedException e) { + System.out.println(pool[i].toString() + " interrupted while joining!"); + success = false; + } + } + System.out.println(success ? "PASS" : "FAIL"); + } + + static class Lock { + final java.util.List waitQueue = new java.util.LinkedList(); + Thread owner; + + public void lock() { + final Thread currentThread = Thread.currentThread(); + + synchronized (this) { + if (owner == currentThread) { + return; + } + if (owner == null) { + owner = currentThread; + return; + } + waitQueue.add(currentThread); + + try { + wait(); + } catch (InterruptedException e) { + // Expected, ignore. + // System.out.println(Thread.currentThread().toString() + " interrupted while waiting!"); + } + } + } + + public void unlock() { + synchronized (this) { + if (owner == null) { + System.out.println("ERROR at " + Thread.currentThread() + ": Can\'t unlock not locked resource"); + success = false; + } + if (owner != Thread.currentThread()) { + System.out.println("ERROR at " + Thread.currentThread() + ": Not owner can\'t unlock resource"); + success = false; + } + while (!waitQueue.isEmpty()) { + final Thread nextThread = waitQueue.remove(0); + + if (!nextThread.isInterrupted()) { + owner = nextThread; + nextThread.interrupt(); + return; + } + } + owner = null; + } + } + } +} Propchange: harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/InterruptWait.java ------------------------------------------------------------------------------ svn:executable = * Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_fat_monitor.c URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_fat_monitor.c?view=diff&rev=544896&r1=544895&r2=544896 ============================================================================== --- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_fat_monitor.c (original) +++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_fat_monitor.c Wed Jun 6 10:40:15 2007 @@ -188,7 +188,7 @@ start = apr_time_now(); status = condvar_wait_impl(&mon_ptr->condition, &mon_ptr->mutex, ms, nano, interruptable); if (status != TM_ERROR_NONE - || mon_ptr->notify_flag || hythread_interrupted(self)) + || mon_ptr->notify_flag || hythread_interrupted(self)) break; // we should not change ms and nano if both are 0 (meaning "no timeout") if (ms || nano) { @@ -327,6 +327,30 @@ return TM_ERROR_ILLEGAL_STATE; } mon_ptr->notify_flag = mon_ptr->wait_count; + return hycond_notify_all(&mon_ptr->condition); +} + + +/** + * Interrupt thread that is waiting on monitor + * + * A thread is considered to be waiting on the monitor if + * it is currently blocked while executing hythread_monitor_wait on + * the monitor. + * + * @param[in] mon_ptr a monitor owned by thread to be interrupted + * @param[in] thread thread to be interrupted + * @return 0 once the monitor has been signaled
HYTHREAD_ILLEGAL_MONITOR_STATE if the current thread does not own the monitor + * + * @see hythread_monitor_notify, hythread_monitor_notify_all, hythread_monitor_enter, hythread_monitor_wait + */ +IDATA VMCALL hythread_monitor_interrupt_wait(hythread_monitor_t mon_ptr, + hythread_t thread) { + if (mon_ptr->owner != tm_self_tls) { + return TM_ERROR_ILLEGAL_STATE; + } + + assert (thread->state & TM_THREAD_STATE_INTERRUPTED); return hycond_notify_all(&mon_ptr->condition); } Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c?view=diff&rev=544896&r1=544895&r2=544896 ============================================================================== --- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c (original) +++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c Wed Jun 6 10:40:15 2007 @@ -54,7 +54,7 @@ } } else if (thread->state & TM_THREAD_STATE_IN_MONITOR_WAIT) { if (thread->current_condition && (hythread_monitor_try_enter(thread->waited_monitor) == TM_ERROR_NONE)) { - hythread_monitor_notify_all(thread->waited_monitor); + hythread_monitor_interrupt_wait(thread->waited_monitor, thread); hythread_monitor_exit(thread->waited_monitor); } else { status = hythread_create(&thr, 0, 0, 0, interrupter_thread_function, (void *)thread);