< prev index next >

src/os/windows/vm/os_windows.cpp

Print this page
rev 9726 : [mq]: 8145127-VM-warning-WaitForMultipleObjects-timed-out


 891   jlong secs = jlong(ticks / 10000000); // 10000 * 1000
 892   seconds = secs;
 893   nanos = jlong(ticks - (secs*10000000)) * 100;
 894 }
 895 
 896 jlong os::javaTimeNanos() {
 897   if (!win32::_has_performance_count) {
 898     return javaTimeMillis() * NANOSECS_PER_MILLISEC; // the best we can do.
 899   } else {
 900     LARGE_INTEGER current_count;
 901     QueryPerformanceCounter(&current_count);
 902     double current = as_long(current_count);
 903     double freq = performance_frequency;
 904     jlong time = (jlong)((current/freq) * NANOSECS_PER_SEC);
 905     return time;
 906   }
 907 }
 908 
 909 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
 910   if (!win32::_has_performance_count) {
 911     // javaTimeMillis() doesn't have much percision,
 912     // but it is not going to wrap -- so all 64 bits
 913     info_ptr->max_value = ALL_64_BITS;
 914 
 915     // this is a wall clock timer, so may skip
 916     info_ptr->may_skip_backward = true;
 917     info_ptr->may_skip_forward = true;
 918   } else {
 919     jlong freq = performance_frequency;
 920     if (freq < NANOSECS_PER_SEC) {
 921       // the performance counter is 64 bits and we will
 922       // be multiplying it -- so no wrap in 64 bits
 923       info_ptr->max_value = ALL_64_BITS;
 924     } else if (freq > NANOSECS_PER_SEC) {
 925       // use the max value the counter can reach to
 926       // determine the max value which could be returned
 927       julong max_counter = (julong)ALL_64_BITS;
 928       info_ptr->max_value = (jlong)(max_counter / (freq / NANOSECS_PER_SEC));
 929     } else {
 930       // the performance counter is 64 bits and we will
 931       // be using it directly -- so no wrap in 64 bits


3869   }
3870 
3871   // try Windows directory
3872   if ((size = GetWindowsDirectory(path, pathLen)) > 0) {
3873     if (size >= pathLen) {
3874       return NULL; // truncated
3875     }
3876     if (jio_snprintf(path + size, pathLen - size, "\\%s", name) == -1) {
3877       return NULL; // truncated
3878     }
3879     if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) {
3880       return result;
3881     }
3882   }
3883 
3884   jio_snprintf(ebuf, ebuflen,
3885                "os::win32::load_windows_dll() cannot load %s from system directories.", name);
3886   return NULL;
3887 }
3888 

3889 #define EXIT_TIMEOUT 300000 /* 5 minutes */
3890 
3891 static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) {
3892   InitializeCriticalSection((CRITICAL_SECTION*)pcrit_sect);
3893   return TRUE;
3894 }
3895 
3896 int os::win32::exit_process_or_thread(Ept what, int exit_code) {
3897   // Basic approach:
3898   //  - Each exiting thread registers its intent to exit and then does so.
3899   //  - A thread trying to terminate the process must wait for all
3900   //    threads currently exiting to complete their exit.
3901 
3902   if (os::win32::has_exit_bug()) {
3903     // The array holds handles of the threads that have started exiting by calling
3904     // _endthreadex().
3905     // Should be large enough to avoid blocking the exiting thread due to lack of
3906     // a free slot.
3907     static HANDLE handles[MAXIMUM_WAIT_OBJECTS];
3908     static int handle_count = 0;
3909 
3910     static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;
3911     static CRITICAL_SECTION crit_sect;
3912     static volatile jint process_exiting = 0;
3913     int i, j;
3914     DWORD res;
3915     HANDLE hproc, hthr;
3916 
3917     // The first thread that reached this point, initializes the critical section.
3918     if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) {
3919       warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);
3920     } else if (OrderAccess::load_acquire(&process_exiting) == 0) {



3921       EnterCriticalSection(&crit_sect);
3922 
3923       if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) {
3924         // Remove from the array those handles of the threads that have completed exiting.
3925         for (i = 0, j = 0; i < handle_count; ++i) {
3926           res = WaitForSingleObject(handles[i], 0 /* don't wait */);
3927           if (res == WAIT_TIMEOUT) {
3928             handles[j++] = handles[i];
3929           } else {
3930             if (res == WAIT_FAILED) {
3931               warning("WaitForSingleObject failed (%u) in %s: %d\n",
3932                       GetLastError(), __FILE__, __LINE__);
3933             }
3934             // Don't keep the handle, if we failed waiting for it.
3935             CloseHandle(handles[i]);
3936           }
3937         }
3938 
3939         // If there's no free slot in the array of the kept handles, we'll have to
3940         // wait until at least one thread completes exiting.
3941         if ((handle_count = j) == MAXIMUM_WAIT_OBJECTS) {
3942           // Raise the priority of the oldest exiting thread to increase its chances
3943           // to complete sooner.
3944           SetThreadPriority(handles[0], THREAD_PRIORITY_ABOVE_NORMAL);
3945           res = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, handles, FALSE, EXIT_TIMEOUT);
3946           if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) {
3947             i = (res - WAIT_OBJECT_0);
3948             handle_count = MAXIMUM_WAIT_OBJECTS - 1;
3949             for (; i < handle_count; ++i) {
3950               handles[i] = handles[i + 1];
3951             }
3952           } else {
3953             warning("WaitForMultipleObjects %s (%u) in %s: %d\n",
3954                     (res == WAIT_FAILED ? "failed" : "timed out"),
3955                     GetLastError(), __FILE__, __LINE__);
3956             // Don't keep handles, if we failed waiting for them.
3957             for (i = 0; i < MAXIMUM_WAIT_OBJECTS; ++i) {
3958               CloseHandle(handles[i]);
3959             }
3960             handle_count = 0;
3961           }
3962         }
3963 
3964         // Store a duplicate of the current thread handle in the array of handles.
3965         hproc = GetCurrentProcess();
3966         hthr = GetCurrentThread();
3967         if (!DuplicateHandle(hproc, hthr, hproc, &handles[handle_count],
3968                              0, FALSE, DUPLICATE_SAME_ACCESS)) {
3969           warning("DuplicateHandle failed (%u) in %s: %d\n",
3970                   GetLastError(), __FILE__, __LINE__);
3971         } else {
3972           ++handle_count;
3973         }
3974 
3975         // The current exiting thread has stored its handle in the array, and now
3976         // should leave the critical section before calling _endthreadex().
3977 
3978       } else if (what != EPT_THREAD) {
3979         if (handle_count > 0) {

3980           // Before ending the process, make sure all the threads that had called
3981           // _endthreadex() completed.
3982 
3983           // Set the priority level of the current thread to the same value as
3984           // the priority level of exiting threads.
3985           // This is to ensure it will be given a fair chance to execute if
3986           // the timeout expires.
3987           hthr = GetCurrentThread();
3988           SetThreadPriority(hthr, THREAD_PRIORITY_ABOVE_NORMAL);
3989           for (i = 0; i < handle_count; ++i) {
3990             SetThreadPriority(handles[i], THREAD_PRIORITY_ABOVE_NORMAL);











3991           }
3992           res = WaitForMultipleObjects(handle_count, handles, TRUE, EXIT_TIMEOUT);
3993           if (res == WAIT_FAILED || res == WAIT_TIMEOUT) {
3994             warning("WaitForMultipleObjects %s (%u) in %s: %d\n",
3995                     (res == WAIT_FAILED ? "failed" : "timed out"),
3996                     GetLastError(), __FILE__, __LINE__);

3997           }
3998           for (i = 0; i < handle_count; ++i) {
3999             CloseHandle(handles[i]);





4000           }
4001           handle_count = 0;
4002         }
4003 
4004         OrderAccess::release_store(&process_exiting, 1);
4005       }
4006 
4007       LeaveCriticalSection(&crit_sect);
4008     }
4009 
4010     if (what == EPT_THREAD) {
4011       while (OrderAccess::load_acquire(&process_exiting) != 0) {

4012         // Some other thread is about to call exit(), so we
4013         // don't let the current thread proceed to _endthreadex()
4014         SuspendThread(GetCurrentThread());
4015         // Avoid busy-wait loop, if SuspendThread() failed.
4016         Sleep(EXIT_TIMEOUT);
4017       }
4018     }
4019   }
4020 
4021   // We are here if either
4022   // - there's no 'race at exit' bug on this OS release;
4023   // - initialization of the critical section failed (unlikely);
4024   // - the current thread has stored its handle and left the critical section;
4025   // - the process-exiting thread has raised the flag and left the critical section.
4026   if (what == EPT_THREAD) {
4027     _endthreadex((unsigned)exit_code);
4028   } else if (what == EPT_PROCESS) {
4029     ::exit(exit_code);
4030   } else {
4031     _exit(exit_code);
4032   }
4033 




 891   jlong secs = jlong(ticks / 10000000); // 10000 * 1000
 892   seconds = secs;
 893   nanos = jlong(ticks - (secs*10000000)) * 100;
 894 }
 895 
 896 jlong os::javaTimeNanos() {
 897   if (!win32::_has_performance_count) {
 898     return javaTimeMillis() * NANOSECS_PER_MILLISEC; // the best we can do.
 899   } else {
 900     LARGE_INTEGER current_count;
 901     QueryPerformanceCounter(&current_count);
 902     double current = as_long(current_count);
 903     double freq = performance_frequency;
 904     jlong time = (jlong)((current/freq) * NANOSECS_PER_SEC);
 905     return time;
 906   }
 907 }
 908 
 909 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
 910   if (!win32::_has_performance_count) {
 911     // javaTimeMillis() doesn't have much precision,
 912     // but it is not going to wrap -- so all 64 bits
 913     info_ptr->max_value = ALL_64_BITS;
 914 
 915     // this is a wall clock timer, so may skip
 916     info_ptr->may_skip_backward = true;
 917     info_ptr->may_skip_forward = true;
 918   } else {
 919     jlong freq = performance_frequency;
 920     if (freq < NANOSECS_PER_SEC) {
 921       // the performance counter is 64 bits and we will
 922       // be multiplying it -- so no wrap in 64 bits
 923       info_ptr->max_value = ALL_64_BITS;
 924     } else if (freq > NANOSECS_PER_SEC) {
 925       // use the max value the counter can reach to
 926       // determine the max value which could be returned
 927       julong max_counter = (julong)ALL_64_BITS;
 928       info_ptr->max_value = (jlong)(max_counter / (freq / NANOSECS_PER_SEC));
 929     } else {
 930       // the performance counter is 64 bits and we will
 931       // be using it directly -- so no wrap in 64 bits


3869   }
3870 
3871   // try Windows directory
3872   if ((size = GetWindowsDirectory(path, pathLen)) > 0) {
3873     if (size >= pathLen) {
3874       return NULL; // truncated
3875     }
3876     if (jio_snprintf(path + size, pathLen - size, "\\%s", name) == -1) {
3877       return NULL; // truncated
3878     }
3879     if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) {
3880       return result;
3881     }
3882   }
3883 
3884   jio_snprintf(ebuf, ebuflen,
3885                "os::win32::load_windows_dll() cannot load %s from system directories.", name);
3886   return NULL;
3887 }
3888 
3889 #define MAXIMUM_THREADS_TO_KEEP (16 * MAXIMUM_WAIT_OBJECTS)
3890 #define EXIT_TIMEOUT 300000 /* 5 minutes */
3891 
3892 static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) {
3893   InitializeCriticalSection((CRITICAL_SECTION*)pcrit_sect);
3894   return TRUE;
3895 }
3896 
3897 int os::win32::exit_process_or_thread(Ept what, int exit_code) {
3898   // Basic approach:
3899   //  - Each exiting thread registers its intent to exit and then does so.
3900   //  - A thread trying to terminate the process must wait for all
3901   //    threads currently exiting to complete their exit.
3902 
3903   if (os::win32::has_exit_bug()) {
3904     // The array holds handles of the threads that have started exiting by calling
3905     // _endthreadex().
3906     // Should be large enough to avoid blocking the exiting thread due to lack of
3907     // a free slot.
3908     static HANDLE handles[MAXIMUM_THREADS_TO_KEEP];
3909     static int handle_count = 0;
3910 
3911     static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;
3912     static CRITICAL_SECTION crit_sect;
3913     static volatile jint process_exiting = 0;
3914     int i, j;
3915     DWORD res;
3916     HANDLE hproc, hthr;
3917 
3918     // The first thread that reached this point, initializes the critical section.
3919     if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) {
3920       warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);
3921     } else if (OrderAccess::load_acquire(&process_exiting) == 0) {
3922       if (what != EPT_THREAD) {
3923         Atomic::cmpxchg((jint)GetCurrentThreadId(), &process_exiting, 0);
3924       }
3925       EnterCriticalSection(&crit_sect);
3926 
3927       if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) {
3928         // Remove from the array those handles of the threads that have completed exiting.
3929         for (i = 0, j = 0; i < handle_count; ++i) {
3930           res = WaitForSingleObject(handles[i], 0 /* don't wait */);
3931           if (res == WAIT_TIMEOUT) {
3932             handles[j++] = handles[i];
3933           } else {
3934             if (res == WAIT_FAILED) {
3935               warning("WaitForSingleObject failed (%u) in %s: %d\n",
3936                       GetLastError(), __FILE__, __LINE__);
3937             }
3938             // Don't keep the handle, if we failed waiting for it.
3939             CloseHandle(handles[i]);
3940           }
3941         }
3942 
3943         // If there's no free slot in the array of the kept handles, we'll have to
3944         // wait until at least one thread completes exiting.
3945         if ((handle_count = j) == MAXIMUM_THREADS_TO_KEEP) {
3946           // Raise the priority of the oldest exiting thread to increase its chances
3947           // to complete sooner.
3948           SetThreadPriority(handles[0], THREAD_PRIORITY_ABOVE_NORMAL);
3949           res = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, handles, FALSE, EXIT_TIMEOUT);
3950           if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) {
3951             i = (res - WAIT_OBJECT_0);
3952             handle_count = MAXIMUM_THREADS_TO_KEEP - 1;
3953             for (; i < handle_count; ++i) {
3954               handles[i] = handles[i + 1];
3955             }
3956           } else {
3957             warning("WaitForMultipleObjects %s (%u) in %s: %d\n",
3958                     (res == WAIT_FAILED ? "failed" : "timed out"),
3959                     GetLastError(), __FILE__, __LINE__);
3960             // Don't keep handles, if we failed waiting for them.
3961             for (i = 0; i < MAXIMUM_THREADS_TO_KEEP; ++i) {
3962               CloseHandle(handles[i]);
3963             }
3964             handle_count = 0;
3965           }
3966         }
3967 
3968         // Store a duplicate of the current thread handle in the array of handles.
3969         hproc = GetCurrentProcess();
3970         hthr = GetCurrentThread();
3971         if (!DuplicateHandle(hproc, hthr, hproc, &handles[handle_count],
3972                              0, FALSE, DUPLICATE_SAME_ACCESS)) {
3973           warning("DuplicateHandle failed (%u) in %s: %d\n",
3974                   GetLastError(), __FILE__, __LINE__);
3975         } else {
3976           ++handle_count;
3977         }
3978 
3979         // The current exiting thread has stored its handle in the array, and now
3980         // should leave the critical section before calling _endthreadex().
3981 
3982       } else if (what != EPT_THREAD) {
3983         if (handle_count > 0) {
3984           jlong start_time, finish_time, timeout_left;
3985           // Before ending the process, make sure all the threads that had called
3986           // _endthreadex() completed.
3987 
3988           // Set the priority level of the current thread to the same value as
3989           // the priority level of exiting threads.
3990           // This is to ensure it will be given a fair chance to execute if
3991           // the timeout expires.
3992           hthr = GetCurrentThread();
3993           SetThreadPriority(hthr, THREAD_PRIORITY_ABOVE_NORMAL);
3994           start_time = os::javaTimeNanos();
3995           finish_time = start_time + ((jlong)EXIT_TIMEOUT * 1000000L);
3996           for (i = 0; ; ) {
3997             int portion_count = handle_count - i;
3998             if (portion_count > MAXIMUM_WAIT_OBJECTS) {
3999                 portion_count = MAXIMUM_WAIT_OBJECTS;
4000             }
4001             for (j = 0; j < portion_count; ++j) {
4002               SetThreadPriority(handles[i + j], THREAD_PRIORITY_ABOVE_NORMAL);
4003             }
4004             timeout_left = (finish_time - start_time) / 1000000L;
4005             if (timeout_left < 0) {
4006               timeout_left = 0;
4007             }
4008             res = WaitForMultipleObjects(portion_count, handles + i, TRUE, timeout_left);
4009             if (res == WAIT_FAILED || res == WAIT_TIMEOUT) {
4010               warning("WaitForMultipleObjects %s (%u) in %s: %d\n",
4011                       (res == WAIT_FAILED ? "failed" : "timed out"),
4012                       GetLastError(), __FILE__, __LINE__);
4013               portion_count = handle_count - i;
4014             }
4015             for (j = 0; j < portion_count; ++j) {
4016               CloseHandle(handles[i + j]);
4017             }
4018             if ((i += portion_count) >= handle_count) {
4019               break;
4020             }
4021             start_time = os::javaTimeNanos();
4022           }
4023           handle_count = 0;
4024         }


4025       }
4026 
4027       LeaveCriticalSection(&crit_sect);
4028     }
4029 
4030     if (OrderAccess::load_acquire(&process_exiting) != 0 &&
4031         process_exiting != (jint)GetCurrentThreadId()) {
4032       while (true) {
4033         // Some other thread is about to call exit(), so we
4034         // don't let the current thread proceed to exit() or _endthreadex()
4035         SuspendThread(GetCurrentThread());
4036         // Avoid busy-wait loop, if SuspendThread() failed.
4037         Sleep(EXIT_TIMEOUT);
4038       }
4039     }
4040   }
4041 
4042   // We are here if either
4043   // - there's no 'race at exit' bug on this OS release;
4044   // - initialization of the critical section failed (unlikely);
4045   // - the current thread has stored its handle and left the critical section;
4046   // - the process-exiting thread has raised the flag and left the critical section.
4047   if (what == EPT_THREAD) {
4048     _endthreadex((unsigned)exit_code);
4049   } else if (what == EPT_PROCESS) {
4050     ::exit(exit_code);
4051   } else {
4052     _exit(exit_code);
4053   }
4054 


< prev index next >