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 } |