60 #include "runtime/stubRoutines.hpp" |
60 #include "runtime/stubRoutines.hpp" |
61 #include "runtime/thread.inline.hpp" |
61 #include "runtime/thread.inline.hpp" |
62 #include "runtime/threadCritical.hpp" |
62 #include "runtime/threadCritical.hpp" |
63 #include "runtime/timer.hpp" |
63 #include "runtime/timer.hpp" |
64 #include "runtime/vm_version.hpp" |
64 #include "runtime/vm_version.hpp" |
65 #include "semaphore_windows.hpp" |
|
66 #include "services/attachListener.hpp" |
65 #include "services/attachListener.hpp" |
67 #include "services/memTracker.hpp" |
66 #include "services/memTracker.hpp" |
68 #include "services/runtimeService.hpp" |
67 #include "services/runtimeService.hpp" |
69 #include "utilities/align.hpp" |
68 #include "utilities/align.hpp" |
70 #include "utilities/decoder.hpp" |
69 #include "utilities/decoder.hpp" |
1843 error = errno; |
1842 error = errno; |
1844 } |
1843 } |
1845 return (int)error; |
1844 return (int)error; |
1846 } |
1845 } |
1847 |
1846 |
1848 WindowsSemaphore::WindowsSemaphore(uint value) { |
|
1849 _semaphore = ::CreateSemaphore(NULL, value, LONG_MAX, NULL); |
|
1850 |
|
1851 guarantee(_semaphore != NULL, "CreateSemaphore failed with error code: %lu", GetLastError()); |
|
1852 } |
|
1853 |
|
1854 WindowsSemaphore::~WindowsSemaphore() { |
|
1855 ::CloseHandle(_semaphore); |
|
1856 } |
|
1857 |
|
1858 void WindowsSemaphore::signal(uint count) { |
|
1859 if (count > 0) { |
|
1860 BOOL ret = ::ReleaseSemaphore(_semaphore, count, NULL); |
|
1861 |
|
1862 assert(ret != 0, "ReleaseSemaphore failed with error code: %lu", GetLastError()); |
|
1863 } |
|
1864 } |
|
1865 |
|
1866 void WindowsSemaphore::wait() { |
|
1867 DWORD ret = ::WaitForSingleObject(_semaphore, INFINITE); |
|
1868 assert(ret != WAIT_FAILED, "WaitForSingleObject failed with error code: %lu", GetLastError()); |
|
1869 assert(ret == WAIT_OBJECT_0, "WaitForSingleObject failed with return value: %lu", ret); |
|
1870 } |
|
1871 |
|
1872 bool WindowsSemaphore::trywait() { |
|
1873 DWORD ret = ::WaitForSingleObject(_semaphore, 0); |
|
1874 assert(ret != WAIT_FAILED, "WaitForSingleObject failed with error code: %lu", GetLastError()); |
|
1875 return ret == WAIT_OBJECT_0; |
|
1876 } |
|
1877 |
|
1878 // sun.misc.Signal |
1847 // sun.misc.Signal |
1879 // NOTE that this is a workaround for an apparent kernel bug where if |
1848 // NOTE that this is a workaround for an apparent kernel bug where if |
1880 // a signal handler for SIGBREAK is installed then that signal handler |
1849 // a signal handler for SIGBREAK is installed then that signal handler |
1881 // takes priority over the console control handler for CTRL_CLOSE_EVENT. |
1850 // takes priority over the console control handler for CTRL_CLOSE_EVENT. |
1882 // See bug 4416763. |
1851 // See bug 4416763. |
1964 return NSIG; |
1933 return NSIG; |
1965 } |
1934 } |
1966 |
1935 |
1967 // a counter for each possible signal value, including signal_thread exit signal |
1936 // a counter for each possible signal value, including signal_thread exit signal |
1968 static volatile jint pending_signals[NSIG+1] = { 0 }; |
1937 static volatile jint pending_signals[NSIG+1] = { 0 }; |
1969 static HANDLE sig_sem = NULL; |
1938 static Semaphore* sig_sem = NULL; |
1970 |
1939 |
1971 void os::signal_init_pd() { |
1940 void os::signal_init_pd() { |
1972 // Initialize signal structures |
1941 // Initialize signal structures |
1973 memset((void*)pending_signals, 0, sizeof(pending_signals)); |
1942 memset((void*)pending_signals, 0, sizeof(pending_signals)); |
1974 |
1943 |
1975 sig_sem = ::CreateSemaphore(NULL, 0, NSIG+1, NULL); |
1944 // Initialize signal semaphore |
|
1945 sig_sem = new Semaphore(); |
1976 |
1946 |
1977 // Programs embedding the VM do not want it to attempt to receive |
1947 // Programs embedding the VM do not want it to attempt to receive |
1978 // events like CTRL_LOGOFF_EVENT, which are used to implement the |
1948 // events like CTRL_LOGOFF_EVENT, which are used to implement the |
1979 // shutdown hooks mechanism introduced in 1.3. For example, when |
1949 // shutdown hooks mechanism introduced in 1.3. For example, when |
1980 // the VM is run as part of a Windows NT service (i.e., a servlet |
1950 // the VM is run as part of a Windows NT service (i.e., a servlet |
1992 // Add a CTRL-C handler |
1962 // Add a CTRL-C handler |
1993 SetConsoleCtrlHandler(consoleHandler, TRUE); |
1963 SetConsoleCtrlHandler(consoleHandler, TRUE); |
1994 } |
1964 } |
1995 } |
1965 } |
1996 |
1966 |
1997 void os::signal_notify(int signal_number) { |
1967 void os::signal_notify(int sig) { |
1998 BOOL ret; |
|
1999 if (sig_sem != NULL) { |
1968 if (sig_sem != NULL) { |
2000 Atomic::inc(&pending_signals[signal_number]); |
1969 Atomic::inc(&pending_signals[sig]); |
2001 ret = ::ReleaseSemaphore(sig_sem, 1, NULL); |
1970 sig_sem->signal(); |
2002 assert(ret != 0, "ReleaseSemaphore() failed"); |
1971 } else { |
2003 } |
1972 // Signal thread is not created with ReduceSignalUsage and signal_init_pd |
2004 } |
1973 // initialization isn't called. |
2005 |
1974 assert(ReduceSignalUsage, "signal semaphore should be created"); |
2006 static int check_pending_signals(bool wait_for_signal) { |
1975 } |
2007 DWORD ret; |
1976 } |
|
1977 |
|
1978 static int check_pending_signals() { |
2008 while (true) { |
1979 while (true) { |
2009 for (int i = 0; i < NSIG + 1; i++) { |
1980 for (int i = 0; i < NSIG + 1; i++) { |
2010 jint n = pending_signals[i]; |
1981 jint n = pending_signals[i]; |
2011 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) { |
1982 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) { |
2012 return i; |
1983 return i; |
2013 } |
1984 } |
2014 } |
1985 } |
2015 if (!wait_for_signal) { |
|
2016 return -1; |
|
2017 } |
|
2018 |
|
2019 JavaThread *thread = JavaThread::current(); |
1986 JavaThread *thread = JavaThread::current(); |
2020 |
1987 |
2021 ThreadBlockInVM tbivm(thread); |
1988 ThreadBlockInVM tbivm(thread); |
2022 |
1989 |
2023 bool threadIsSuspended; |
1990 bool threadIsSuspended; |
2024 do { |
1991 do { |
2025 thread->set_suspend_equivalent(); |
1992 thread->set_suspend_equivalent(); |
2026 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() |
1993 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() |
2027 ret = ::WaitForSingleObject(sig_sem, INFINITE); |
1994 sig_sem->wait(); |
2028 assert(ret == WAIT_OBJECT_0, "WaitForSingleObject() failed"); |
|
2029 |
1995 |
2030 // were we externally suspended while we were waiting? |
1996 // were we externally suspended while we were waiting? |
2031 threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); |
1997 threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); |
2032 if (threadIsSuspended) { |
1998 if (threadIsSuspended) { |
2033 // The semaphore has been incremented, but while we were waiting |
1999 // The semaphore has been incremented, but while we were waiting |
2034 // another thread suspended us. We don't want to continue running |
2000 // another thread suspended us. We don't want to continue running |
2035 // while suspended because that would surprise the thread that |
2001 // while suspended because that would surprise the thread that |
2036 // suspended us. |
2002 // suspended us. |
2037 ret = ::ReleaseSemaphore(sig_sem, 1, NULL); |
2003 sig_sem->signal(); |
2038 assert(ret != 0, "ReleaseSemaphore() failed"); |
|
2039 |
2004 |
2040 thread->java_suspend_self(); |
2005 thread->java_suspend_self(); |
2041 } |
2006 } |
2042 } while (threadIsSuspended); |
2007 } while (threadIsSuspended); |
2043 } |
2008 } |
2044 } |
2009 } |
2045 |
2010 |
2046 int os::signal_lookup() { |
|
2047 return check_pending_signals(false); |
|
2048 } |
|
2049 |
|
2050 int os::signal_wait() { |
2011 int os::signal_wait() { |
2051 return check_pending_signals(true); |
2012 return check_pending_signals(); |
2052 } |
2013 } |
2053 |
2014 |
2054 // Implicit OS exception handling |
2015 // Implicit OS exception handling |
2055 |
2016 |
2056 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, |
2017 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, |