src/hotspot/share/runtime/os.cpp
changeset 57998 849acc346a1d
parent 57903 5e2576c303a2
child 58041 d8902e9c307c
equal deleted inserted replaced
57996:bf3fb5465543 57998:849acc346a1d
  1834     return to;
  1834     return to;
  1835   }
  1835   }
  1836   return result;
  1836   return result;
  1837 }
  1837 }
  1838 #endif
  1838 #endif
       
  1839 
       
  1840 int os::sleep(Thread* thread, jlong millis, bool interruptible) {
       
  1841   assert(thread == Thread::current(),  "thread consistency check");
       
  1842 
       
  1843   ParkEvent * const slp = thread->_SleepEvent;
       
  1844   // Because there can be races with thread interruption sending an unpark()
       
  1845   // to the event, we explicitly reset it here to avoid an immediate return.
       
  1846   // The actual interrupt state will be checked before we park().
       
  1847   slp->reset();
       
  1848   // Thread interruption establishes a happens-before ordering in the
       
  1849   // Java Memory Model, so we need to ensure we synchronize with the
       
  1850   // interrupt state.
       
  1851   OrderAccess::fence();
       
  1852 
       
  1853   if (interruptible) {
       
  1854     jlong prevtime = javaTimeNanos();
       
  1855 
       
  1856     assert(thread->is_Java_thread(), "sanity check");
       
  1857     JavaThread *jt = (JavaThread *) thread;
       
  1858 
       
  1859     for (;;) {
       
  1860       // interruption has precedence over timing out
       
  1861       if (os::is_interrupted(thread, true)) {
       
  1862         return OS_INTRPT;
       
  1863       }
       
  1864 
       
  1865       jlong newtime = javaTimeNanos();
       
  1866 
       
  1867       if (newtime - prevtime < 0) {
       
  1868         // time moving backwards, should only happen if no monotonic clock
       
  1869         // not a guarantee() because JVM should not abort on kernel/glibc bugs
       
  1870         assert(!os::supports_monotonic_clock(),
       
  1871                "unexpected time moving backwards detected in os::sleep(interruptible)");
       
  1872       } else {
       
  1873         millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
       
  1874       }
       
  1875 
       
  1876       if (millis <= 0) {
       
  1877         return OS_OK;
       
  1878       }
       
  1879 
       
  1880       prevtime = newtime;
       
  1881 
       
  1882       {
       
  1883         ThreadBlockInVM tbivm(jt);
       
  1884         OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
       
  1885 
       
  1886         jt->set_suspend_equivalent();
       
  1887         // cleared by handle_special_suspend_equivalent_condition() or
       
  1888         // java_suspend_self() via check_and_wait_while_suspended()
       
  1889 
       
  1890         slp->park(millis);
       
  1891 
       
  1892         // were we externally suspended while we were waiting?
       
  1893         jt->check_and_wait_while_suspended();
       
  1894       }
       
  1895     }
       
  1896    } else {
       
  1897     OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
       
  1898     jlong prevtime = javaTimeNanos();
       
  1899 
       
  1900     for (;;) {
       
  1901       // It'd be nice to avoid the back-to-back javaTimeNanos() calls on
       
  1902       // the 1st iteration ...
       
  1903       jlong newtime = javaTimeNanos();
       
  1904 
       
  1905       if (newtime - prevtime < 0) {
       
  1906         // time moving backwards, should only happen if no monotonic clock
       
  1907         // not a guarantee() because JVM should not abort on kernel/glibc bugs
       
  1908         assert(!os::supports_monotonic_clock(),
       
  1909                "unexpected time moving backwards detected on os::sleep(!interruptible)");
       
  1910       } else {
       
  1911         millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
       
  1912       }
       
  1913 
       
  1914       if (millis <= 0) break ;
       
  1915 
       
  1916       prevtime = newtime;
       
  1917       slp->park(millis);
       
  1918     }
       
  1919     return OS_OK ;
       
  1920   }
       
  1921 }