hotspot/src/os/windows/vm/os_windows.cpp
changeset 35487 7c043e468890
parent 35462 a1bed49c67a8
child 35903 049dfbdc3ced
equal deleted inserted replaced
35486:b8d9cabc184d 35487:7c043e468890
  3813   jio_snprintf(ebuf, ebuflen,
  3813   jio_snprintf(ebuf, ebuflen,
  3814                "os::win32::load_windows_dll() cannot load %s from system directories.", name);
  3814                "os::win32::load_windows_dll() cannot load %s from system directories.", name);
  3815   return NULL;
  3815   return NULL;
  3816 }
  3816 }
  3817 
  3817 
       
  3818 #define MAXIMUM_THREADS_TO_KEEP (16 * MAXIMUM_WAIT_OBJECTS)
  3818 #define EXIT_TIMEOUT 300000 /* 5 minutes */
  3819 #define EXIT_TIMEOUT 300000 /* 5 minutes */
  3819 
  3820 
  3820 static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) {
  3821 static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) {
  3821   InitializeCriticalSection((CRITICAL_SECTION*)pcrit_sect);
  3822   InitializeCriticalSection((CRITICAL_SECTION*)pcrit_sect);
  3822   return TRUE;
  3823   return TRUE;
  3831   if (os::win32::has_exit_bug()) {
  3832   if (os::win32::has_exit_bug()) {
  3832     // The array holds handles of the threads that have started exiting by calling
  3833     // The array holds handles of the threads that have started exiting by calling
  3833     // _endthreadex().
  3834     // _endthreadex().
  3834     // Should be large enough to avoid blocking the exiting thread due to lack of
  3835     // Should be large enough to avoid blocking the exiting thread due to lack of
  3835     // a free slot.
  3836     // a free slot.
  3836     static HANDLE handles[MAXIMUM_WAIT_OBJECTS];
  3837     static HANDLE handles[MAXIMUM_THREADS_TO_KEEP];
  3837     static int handle_count = 0;
  3838     static int handle_count = 0;
  3838 
  3839 
  3839     static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;
  3840     static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;
  3840     static CRITICAL_SECTION crit_sect;
  3841     static CRITICAL_SECTION crit_sect;
  3841     static volatile jint process_exiting = 0;
  3842     static volatile jint process_exiting = 0;
  3845 
  3846 
  3846     // The first thread that reached this point, initializes the critical section.
  3847     // The first thread that reached this point, initializes the critical section.
  3847     if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) {
  3848     if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) {
  3848       warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);
  3849       warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);
  3849     } else if (OrderAccess::load_acquire(&process_exiting) == 0) {
  3850     } else if (OrderAccess::load_acquire(&process_exiting) == 0) {
       
  3851       if (what != EPT_THREAD) {
       
  3852         // Atomically set process_exiting before the critical section
       
  3853         // to increase the visibility between racing threads.
       
  3854         Atomic::cmpxchg((jint)GetCurrentThreadId(), &process_exiting, 0);
       
  3855       }
  3850       EnterCriticalSection(&crit_sect);
  3856       EnterCriticalSection(&crit_sect);
  3851 
  3857 
  3852       if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) {
  3858       if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) {
  3853         // Remove from the array those handles of the threads that have completed exiting.
  3859         // Remove from the array those handles of the threads that have completed exiting.
  3854         for (i = 0, j = 0; i < handle_count; ++i) {
  3860         for (i = 0, j = 0; i < handle_count; ++i) {
  3865           }
  3871           }
  3866         }
  3872         }
  3867 
  3873 
  3868         // If there's no free slot in the array of the kept handles, we'll have to
  3874         // If there's no free slot in the array of the kept handles, we'll have to
  3869         // wait until at least one thread completes exiting.
  3875         // wait until at least one thread completes exiting.
  3870         if ((handle_count = j) == MAXIMUM_WAIT_OBJECTS) {
  3876         if ((handle_count = j) == MAXIMUM_THREADS_TO_KEEP) {
  3871           // Raise the priority of the oldest exiting thread to increase its chances
  3877           // Raise the priority of the oldest exiting thread to increase its chances
  3872           // to complete sooner.
  3878           // to complete sooner.
  3873           SetThreadPriority(handles[0], THREAD_PRIORITY_ABOVE_NORMAL);
  3879           SetThreadPriority(handles[0], THREAD_PRIORITY_ABOVE_NORMAL);
  3874           res = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, handles, FALSE, EXIT_TIMEOUT);
  3880           res = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, handles, FALSE, EXIT_TIMEOUT);
  3875           if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) {
  3881           if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) {
  3876             i = (res - WAIT_OBJECT_0);
  3882             i = (res - WAIT_OBJECT_0);
  3877             handle_count = MAXIMUM_WAIT_OBJECTS - 1;
  3883             handle_count = MAXIMUM_THREADS_TO_KEEP - 1;
  3878             for (; i < handle_count; ++i) {
  3884             for (; i < handle_count; ++i) {
  3879               handles[i] = handles[i + 1];
  3885               handles[i] = handles[i + 1];
  3880             }
  3886             }
  3881           } else {
  3887           } else {
  3882             warning("WaitForMultipleObjects %s (%u) in %s: %d\n",
  3888             warning("WaitForMultipleObjects %s (%u) in %s: %d\n",
  3883                     (res == WAIT_FAILED ? "failed" : "timed out"),
  3889                     (res == WAIT_FAILED ? "failed" : "timed out"),
  3884                     GetLastError(), __FILE__, __LINE__);
  3890                     GetLastError(), __FILE__, __LINE__);
  3885             // Don't keep handles, if we failed waiting for them.
  3891             // Don't keep handles, if we failed waiting for them.
  3886             for (i = 0; i < MAXIMUM_WAIT_OBJECTS; ++i) {
  3892             for (i = 0; i < MAXIMUM_THREADS_TO_KEEP; ++i) {
  3887               CloseHandle(handles[i]);
  3893               CloseHandle(handles[i]);
  3888             }
  3894             }
  3889             handle_count = 0;
  3895             handle_count = 0;
  3890           }
  3896           }
  3891         }
  3897         }
  3902         }
  3908         }
  3903 
  3909 
  3904         // The current exiting thread has stored its handle in the array, and now
  3910         // The current exiting thread has stored its handle in the array, and now
  3905         // should leave the critical section before calling _endthreadex().
  3911         // should leave the critical section before calling _endthreadex().
  3906 
  3912 
  3907       } else if (what != EPT_THREAD) {
  3913       } else if (what != EPT_THREAD && handle_count > 0) {
  3908         if (handle_count > 0) {
  3914         jlong start_time, finish_time, timeout_left;
  3909           // Before ending the process, make sure all the threads that had called
  3915         // Before ending the process, make sure all the threads that had called
  3910           // _endthreadex() completed.
  3916         // _endthreadex() completed.
  3911 
  3917 
  3912           // Set the priority level of the current thread to the same value as
  3918         // Set the priority level of the current thread to the same value as
  3913           // the priority level of exiting threads.
  3919         // the priority level of exiting threads.
  3914           // This is to ensure it will be given a fair chance to execute if
  3920         // This is to ensure it will be given a fair chance to execute if
  3915           // the timeout expires.
  3921         // the timeout expires.
  3916           hthr = GetCurrentThread();
  3922         hthr = GetCurrentThread();
  3917           SetThreadPriority(hthr, THREAD_PRIORITY_ABOVE_NORMAL);
  3923         SetThreadPriority(hthr, THREAD_PRIORITY_ABOVE_NORMAL);
  3918           for (i = 0; i < handle_count; ++i) {
  3924         start_time = os::javaTimeNanos();
  3919             SetThreadPriority(handles[i], THREAD_PRIORITY_ABOVE_NORMAL);
  3925         finish_time = start_time + ((jlong)EXIT_TIMEOUT * 1000000L);
       
  3926         for (i = 0; ; ) {
       
  3927           int portion_count = handle_count - i;
       
  3928           if (portion_count > MAXIMUM_WAIT_OBJECTS) {
       
  3929             portion_count = MAXIMUM_WAIT_OBJECTS;
  3920           }
  3930           }
  3921           res = WaitForMultipleObjects(handle_count, handles, TRUE, EXIT_TIMEOUT);
  3931           for (j = 0; j < portion_count; ++j) {
       
  3932             SetThreadPriority(handles[i + j], THREAD_PRIORITY_ABOVE_NORMAL);
       
  3933           }
       
  3934           timeout_left = (finish_time - start_time) / 1000000L;
       
  3935           if (timeout_left < 0) {
       
  3936             timeout_left = 0;
       
  3937           }
       
  3938           res = WaitForMultipleObjects(portion_count, handles + i, TRUE, timeout_left);
  3922           if (res == WAIT_FAILED || res == WAIT_TIMEOUT) {
  3939           if (res == WAIT_FAILED || res == WAIT_TIMEOUT) {
  3923             warning("WaitForMultipleObjects %s (%u) in %s: %d\n",
  3940             warning("WaitForMultipleObjects %s (%u) in %s: %d\n",
  3924                     (res == WAIT_FAILED ? "failed" : "timed out"),
  3941                     (res == WAIT_FAILED ? "failed" : "timed out"),
  3925                     GetLastError(), __FILE__, __LINE__);
  3942                     GetLastError(), __FILE__, __LINE__);
       
  3943             // Reset portion_count so we close the remaining
       
  3944             // handles due to this error.
       
  3945             portion_count = handle_count - i;
  3926           }
  3946           }
  3927           for (i = 0; i < handle_count; ++i) {
  3947           for (j = 0; j < portion_count; ++j) {
  3928             CloseHandle(handles[i]);
  3948             CloseHandle(handles[i + j]);
  3929           }
  3949           }
  3930           handle_count = 0;
  3950           if ((i += portion_count) >= handle_count) {
       
  3951             break;
       
  3952           }
       
  3953           start_time = os::javaTimeNanos();
  3931         }
  3954         }
  3932 
  3955         handle_count = 0;
  3933         OrderAccess::release_store(&process_exiting, 1);
       
  3934       }
  3956       }
  3935 
  3957 
  3936       LeaveCriticalSection(&crit_sect);
  3958       LeaveCriticalSection(&crit_sect);
  3937     }
  3959     }
  3938 
  3960 
  3939     if (what == EPT_THREAD) {
  3961     if (OrderAccess::load_acquire(&process_exiting) != 0 &&
  3940       while (OrderAccess::load_acquire(&process_exiting) != 0) {
  3962         process_exiting != (jint)GetCurrentThreadId()) {
  3941         // Some other thread is about to call exit(), so we
  3963       // Some other thread is about to call exit(), so we
  3942         // don't let the current thread proceed to _endthreadex()
  3964       // don't let the current thread proceed to exit() or _endthreadex()
       
  3965       while (true) {
  3943         SuspendThread(GetCurrentThread());
  3966         SuspendThread(GetCurrentThread());
  3944         // Avoid busy-wait loop, if SuspendThread() failed.
  3967         // Avoid busy-wait loop, if SuspendThread() failed.
  3945         Sleep(EXIT_TIMEOUT);
  3968         Sleep(EXIT_TIMEOUT);
  3946       }
  3969       }
  3947     }
  3970     }