You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2007/04/13 14:45:03 UTC

svn commit: r528473 - in /harmony/enhanced/drlvm/trunk: src/test/regression/H3619/ src/test/regression/H3619/ObjectLongWaitTest.java vm/thread/src/linux/os_condvar.c

Author: gshimansky
Date: Fri Apr 13 05:45:02 2007
New Revision: 528473

URL: http://svn.apache.org/viewvc?view=rev&rev=528473
Log:
Applied HARMONY-3619 Object.wait(Long.MAX_VALUE) exits immediately


Added:
    harmony/enhanced/drlvm/trunk/src/test/regression/H3619/
    harmony/enhanced/drlvm/trunk/src/test/regression/H3619/ObjectLongWaitTest.java   (with props)
Modified:
    harmony/enhanced/drlvm/trunk/vm/thread/src/linux/os_condvar.c

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3619/ObjectLongWaitTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3619/ObjectLongWaitTest.java?view=auto&rev=528473
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3619/ObjectLongWaitTest.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3619/ObjectLongWaitTest.java Fri Apr 13 05:45:02 2007
@@ -0,0 +1,44 @@
+package org.apache.harmony.drlvm.tests.regression.h3619;
+
+import junit.framework.TestCase;
+
+public class ObjectLongWaitTest extends TestCase {
+    
+    public static void main(String args[]) throws Exception {
+       (new ObjectLongWaitTest()).test();
+    }
+
+    public void test() throws Exception {
+        TestThread testThread = new TestThread();
+        System.out.println("TestThread is starting...");
+        testThread.start();
+
+        Thread.sleep(2000); // give time to TestThread to behave
+        
+        if (testThread.finished) {
+            testThread.join();
+            fail("TestThread is returned from Object.wait(Long.MAX_VALUE)");
+        } else {
+            System.out.println("TestThread expectedly hanged up. Interrupting...");
+            testThread.interrupt();
+        }
+    }
+}
+
+class TestThread extends Thread {
+
+    public volatile boolean finished = false;
+
+    public void run() {
+        try {
+            System.out.println("TestThread started");
+            String lock = "lock";
+            synchronized (lock) {
+                lock.wait(Long.MAX_VALUE);
+            }
+            finished = true;
+            System.out.println("Object.wait(Long.MAX_VALUE) exited in couple of seconds");
+        } catch (InterruptedException e) {
+        }
+    }
+}

Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3619/ObjectLongWaitTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/linux/os_condvar.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/linux/os_condvar.c?view=diff&rev=528473&r1=528472&r2=528473
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/linux/os_condvar.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/linux/os_condvar.c Fri Apr 13 05:45:02 2007
@@ -37,15 +37,52 @@
 int os_cond_timedwait(hycond_t *cond, hymutex_t *mutex, I_64 ms, IDATA nano)
 {
     int r = 0;
+
     if (!ms && !nano) {
         r = pthread_cond_wait(cond, mutex);
     } else {
-        struct timespec abstime;
-        apr_time_t then = apr_time_now() + ms*1000 + nano/1000;
-        abstime.tv_sec = apr_time_sec(then);
-        abstime.tv_nsec = apr_time_usec(then)*1000 + nano%1000;
-        r = pthread_cond_timedwait(cond, mutex, &abstime);
+        // the main point here is to translate time from ms:nano
+        // format into sec:nano format (acceptable by pthread)
+
+        apr_time_t now = apr_time_now();
+
+        // translate 'now' into: seconds + nanos
+        I_64 Nsec = apr_time_sec(now);
+        I_64 Nnsec = (apr_time_usec(now) % APR_USEC_PER_SEC) * ((1000*1000*1000) / APR_USEC_PER_SEC);
+
+        // translate delay method parameters ('ms' and 'nano') into:
+        // seconds + nanos (taking care about overflow)
+        I_64 Dsec = (ms / 1000) + (nano / (1000 * 1000 * 1000));
+        I_64 Dnsec = (ms % 1000) * (1000 * 1000) + (nano % (1000 * 1000 * 1000));
+        Dsec = Dsec + (Dnsec / (1000 * 1000 * 1000));
+        Dnsec = Dnsec % (1000 * 1000 * 1000);
+        
+        // calculating result sec:nanos values
+        // (taking care about overflow as well)
+        I_64 Rsec = Dsec + Nsec + (Dnsec + Nnsec) / (1000 * 1000 * 1000);
+        I_64 Rnsec = (Dnsec + Nnsec) % (1000 * 1000 * 1000);
+
+        // wrap the resulting wake up time (absolute time) into struct
+        // acceptable by pthread_cond_timedwait()
+        struct timespec wakeup_time;
+
+        // final boundary checks: pthread struct sec is 32 bit
+        if (Rsec <= 0x7FFFFFFF) {
+           wakeup_time.tv_sec = Rsec;
+        } else {
+           wakeup_time.tv_sec = 0x7FFFFFFF;
+        }
+
+        // final boundary checks: pthread struct nanos is 32 bit as well
+        if (Rnsec <= 0x7FFFFFFF) {
+           wakeup_time.tv_nsec = Rnsec;
+        } else {
+           wakeup_time.tv_nsec = 0x7FFFFFFF;
+        }
+
+        r = pthread_cond_timedwait(cond, mutex, &wakeup_time);
     }
+
     if (r == ETIMEDOUT)
         r = TM_ERROR_TIMEOUT;
     else if (r == EINTR)