< prev index next >

src/os/windows/vm/os_windows.cpp

Print this page

        

*** 906,916 **** } } void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { if (!win32::_has_performance_count) { ! // javaTimeMillis() doesn't have much percision, // but it is not going to wrap -- so all 64 bits info_ptr->max_value = ALL_64_BITS; // this is a wall clock timer, so may skip info_ptr->may_skip_backward = true; --- 906,916 ---- } } void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { if (!win32::_has_performance_count) { ! // javaTimeMillis() doesn't have much precision, // but it is not going to wrap -- so all 64 bits info_ptr->max_value = ALL_64_BITS; // this is a wall clock timer, so may skip info_ptr->may_skip_backward = true;
*** 3884,3893 **** --- 3884,3894 ---- jio_snprintf(ebuf, ebuflen, "os::win32::load_windows_dll() cannot load %s from system directories.", name); return NULL; } + #define MAXIMUM_THREADS_TO_KEEP (16 * MAXIMUM_WAIT_OBJECTS) #define EXIT_TIMEOUT 300000 /* 5 minutes */ static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) { InitializeCriticalSection((CRITICAL_SECTION*)pcrit_sect); return TRUE;
*** 3902,3925 **** if (os::win32::has_exit_bug()) { // The array holds handles of the threads that have started exiting by calling // _endthreadex(). // Should be large enough to avoid blocking the exiting thread due to lack of // a free slot. ! static HANDLE handles[MAXIMUM_WAIT_OBJECTS]; static int handle_count = 0; static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT; static CRITICAL_SECTION crit_sect; static volatile jint process_exiting = 0; int i, j; DWORD res; HANDLE hproc, hthr; // The first thread that reached this point, initializes the critical section. if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) { warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__); } else if (OrderAccess::load_acquire(&process_exiting) == 0) { EnterCriticalSection(&crit_sect); if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) { // Remove from the array those handles of the threads that have completed exiting. for (i = 0, j = 0; i < handle_count; ++i) { --- 3903,3930 ---- if (os::win32::has_exit_bug()) { // The array holds handles of the threads that have started exiting by calling // _endthreadex(). // Should be large enough to avoid blocking the exiting thread due to lack of // a free slot. ! static HANDLE handles[MAXIMUM_THREADS_TO_KEEP]; static int handle_count = 0; static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT; static CRITICAL_SECTION crit_sect; static volatile jint process_exiting = 0; + jint pr_ex; int i, j; DWORD res; HANDLE hproc, hthr; // The first thread that reached this point, initializes the critical section. if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) { warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__); } else if (OrderAccess::load_acquire(&process_exiting) == 0) { + if (what != EPT_THREAD) { + Atomic::cmpxchg((jint)GetCurrentThreadId(), &process_exiting, 0); + } EnterCriticalSection(&crit_sect); if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) { // Remove from the array those handles of the threads that have completed exiting. for (i = 0, j = 0; i < handle_count; ++i) {
*** 3936,3962 **** } } // If there's no free slot in the array of the kept handles, we'll have to // wait until at least one thread completes exiting. ! if ((handle_count = j) == MAXIMUM_WAIT_OBJECTS) { // Raise the priority of the oldest exiting thread to increase its chances // to complete sooner. SetThreadPriority(handles[0], THREAD_PRIORITY_ABOVE_NORMAL); res = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, handles, FALSE, EXIT_TIMEOUT); if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) { i = (res - WAIT_OBJECT_0); ! handle_count = MAXIMUM_WAIT_OBJECTS - 1; for (; i < handle_count; ++i) { handles[i] = handles[i + 1]; } } else { warning("WaitForMultipleObjects %s (%u) in %s: %d\n", (res == WAIT_FAILED ? "failed" : "timed out"), GetLastError(), __FILE__, __LINE__); // Don't keep handles, if we failed waiting for them. ! for (i = 0; i < MAXIMUM_WAIT_OBJECTS; ++i) { CloseHandle(handles[i]); } handle_count = 0; } } --- 3941,3967 ---- } } // If there's no free slot in the array of the kept handles, we'll have to // wait until at least one thread completes exiting. ! if ((handle_count = j) == MAXIMUM_THREADS_TO_KEEP) { // Raise the priority of the oldest exiting thread to increase its chances // to complete sooner. SetThreadPriority(handles[0], THREAD_PRIORITY_ABOVE_NORMAL); res = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, handles, FALSE, EXIT_TIMEOUT); if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) { i = (res - WAIT_OBJECT_0); ! handle_count = MAXIMUM_THREADS_TO_KEEP - 1; for (; i < handle_count; ++i) { handles[i] = handles[i + 1]; } } else { warning("WaitForMultipleObjects %s (%u) in %s: %d\n", (res == WAIT_FAILED ? "failed" : "timed out"), GetLastError(), __FILE__, __LINE__); // Don't keep handles, if we failed waiting for them. ! for (i = 0; i < MAXIMUM_THREADS_TO_KEEP; ++i) { CloseHandle(handles[i]); } handle_count = 0; } }
*** 3975,4018 **** // The current exiting thread has stored its handle in the array, and now // should leave the critical section before calling _endthreadex(). } else if (what != EPT_THREAD) { if (handle_count > 0) { // Before ending the process, make sure all the threads that had called // _endthreadex() completed. // Set the priority level of the current thread to the same value as // the priority level of exiting threads. // This is to ensure it will be given a fair chance to execute if // the timeout expires. hthr = GetCurrentThread(); SetThreadPriority(hthr, THREAD_PRIORITY_ABOVE_NORMAL); ! for (i = 0; i < handle_count; ++i) { ! SetThreadPriority(handles[i], THREAD_PRIORITY_ABOVE_NORMAL); } ! res = WaitForMultipleObjects(handle_count, handles, TRUE, EXIT_TIMEOUT); if (res == WAIT_FAILED || res == WAIT_TIMEOUT) { warning("WaitForMultipleObjects %s (%u) in %s: %d\n", (res == WAIT_FAILED ? "failed" : "timed out"), GetLastError(), __FILE__, __LINE__); } ! for (i = 0; i < handle_count; ++i) { ! CloseHandle(handles[i]); } handle_count = 0; } - - OrderAccess::release_store(&process_exiting, 1); } LeaveCriticalSection(&crit_sect); } ! if (what == EPT_THREAD) { ! while (OrderAccess::load_acquire(&process_exiting) != 0) { // Some other thread is about to call exit(), so we ! // don't let the current thread proceed to _endthreadex() SuspendThread(GetCurrentThread()); // Avoid busy-wait loop, if SuspendThread() failed. Sleep(EXIT_TIMEOUT); } } --- 3980,4040 ---- // The current exiting thread has stored its handle in the array, and now // should leave the critical section before calling _endthreadex(). } else if (what != EPT_THREAD) { if (handle_count > 0) { + jlong start_time, finish_time, timeout_left; // Before ending the process, make sure all the threads that had called // _endthreadex() completed. // Set the priority level of the current thread to the same value as // the priority level of exiting threads. // This is to ensure it will be given a fair chance to execute if // the timeout expires. hthr = GetCurrentThread(); SetThreadPriority(hthr, THREAD_PRIORITY_ABOVE_NORMAL); ! start_time = os::javaTimeNanos(); ! finish_time = start_time + ((jlong)EXIT_TIMEOUT * 1000000L); ! for (i = 0; ; ) { ! int portion_count = handle_count - i; ! if (portion_count > MAXIMUM_WAIT_OBJECTS) { ! portion_count = MAXIMUM_WAIT_OBJECTS; ! } ! for (j = 0; j < portion_count; ++j) { ! SetThreadPriority(handles[i + j], THREAD_PRIORITY_ABOVE_NORMAL); ! } ! timeout_left = (finish_time - start_time) / 1000000L; ! if (timeout_left < 0) { ! timeout_left = 0; } ! res = WaitForMultipleObjects(portion_count, handles + i, TRUE, timeout_left); if (res == WAIT_FAILED || res == WAIT_TIMEOUT) { warning("WaitForMultipleObjects %s (%u) in %s: %d\n", (res == WAIT_FAILED ? "failed" : "timed out"), GetLastError(), __FILE__, __LINE__); + portion_count = handle_count - i; } ! for (j = 0; j < portion_count; ++j) { ! CloseHandle(handles[i + j]); ! } ! if ((i += portion_count) >= handle_count) { ! break; ! } ! start_time = os::javaTimeNanos(); } handle_count = 0; } } LeaveCriticalSection(&crit_sect); } ! if ((pr_ex = OrderAccess::load_acquire(&process_exiting)) != 0) { ! jint curr_id = (jint)GetCurrentThreadId(); ! while (pr_ex != curr_id) { // Some other thread is about to call exit(), so we ! // don't let the current thread proceed to exit() or _endthreadex() SuspendThread(GetCurrentThread()); // Avoid busy-wait loop, if SuspendThread() failed. Sleep(EXIT_TIMEOUT); } }
< prev index next >