< prev index next >

src/os/windows/vm/os_windows.cpp

Print this page




 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     jint pr_ex;
3915     int i, j;
3916     DWORD res;
3917     HANDLE hproc, hthr;
3918 
3919     // The first thread that reached this point, initializes the critical section.
3920     if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) {
3921       warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);
3922     } else if (OrderAccess::load_acquire(&process_exiting) == 0) {
3923       if (what != EPT_THREAD) {
3924         Atomic::cmpxchg((jint)GetCurrentThreadId(), &process_exiting, 0);
3925       }
3926       EnterCriticalSection(&crit_sect);
3927 
3928       if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) {
3929         // Remove from the array those handles of the threads that have completed exiting.
3930         for (i = 0, j = 0; i < handle_count; ++i) {
3931           res = WaitForSingleObject(handles[i], 0 /* don't wait */);
3932           if (res == WAIT_TIMEOUT) {
3933             handles[j++] = handles[i];
3934           } else {
3935             if (res == WAIT_FAILED) {
3936               warning("WaitForSingleObject failed (%u) in %s: %d\n",
3937                       GetLastError(), __FILE__, __LINE__);
3938             }
3939             // Don't keep the handle, if we failed waiting for it.
3940             CloseHandle(handles[i]);
3941           }
3942         }
3943 
3944         // If there's no free slot in the array of the kept handles, we'll have to
3945         // wait until at least one thread completes exiting.
3946         if ((handle_count = j) == MAXIMUM_THREADS_TO_KEEP) {
3947           // Raise the priority of the oldest exiting thread to increase its chances
3948           // to complete sooner.
3949           SetThreadPriority(handles[0], THREAD_PRIORITY_ABOVE_NORMAL);
3950           res = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, handles, FALSE, EXIT_TIMEOUT);
3951           if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) {
3952             i = (res - WAIT_OBJECT_0);
3953             handle_count = MAXIMUM_THREADS_TO_KEEP - 1;
3954             for (; i < handle_count; ++i) {
3955               handles[i] = handles[i + 1];
3956             }
3957           } else {
3958             warning("WaitForMultipleObjects %s (%u) in %s: %d\n",
3959                     (res == WAIT_FAILED ? "failed" : "timed out"),
3960                     GetLastError(), __FILE__, __LINE__);
3961             // Don't keep handles, if we failed waiting for them.
3962             for (i = 0; i < MAXIMUM_THREADS_TO_KEEP; ++i) {
3963               CloseHandle(handles[i]);
3964             }
3965             handle_count = 0;
3966           }
3967         }
3968 
3969         // Store a duplicate of the current thread handle in the array of handles.
3970         hproc = GetCurrentProcess();
3971         hthr = GetCurrentThread();
3972         if (!DuplicateHandle(hproc, hthr, hproc, &handles[handle_count],
3973                              0, FALSE, DUPLICATE_SAME_ACCESS)) {
3974           warning("DuplicateHandle failed (%u) in %s: %d\n",
3975                   GetLastError(), __FILE__, __LINE__);
3976         } else {
3977           ++handle_count;
3978         }
3979 
3980         // The current exiting thread has stored its handle in the array, and now
3981         // should leave the critical section before calling _endthreadex().
3982 
3983       } else if (what != EPT_THREAD) {
3984         if (handle_count > 0) {
3985           jlong start_time, finish_time, timeout_left;
3986           // Before ending the process, make sure all the threads that had called
3987           // _endthreadex() completed.
3988 
3989           // Set the priority level of the current thread to the same value as
3990           // the priority level of exiting threads.
3991           // This is to ensure it will be given a fair chance to execute if
3992           // the timeout expires.
3993           hthr = GetCurrentThread();
3994           SetThreadPriority(hthr, THREAD_PRIORITY_ABOVE_NORMAL);
3995           start_time = os::javaTimeNanos();
3996           finish_time = start_time + ((jlong)EXIT_TIMEOUT * 1000000L);
3997           for (i = 0; ; ) {
3998             int portion_count = handle_count - i;
3999             if (portion_count > MAXIMUM_WAIT_OBJECTS) {
4000                 portion_count = MAXIMUM_WAIT_OBJECTS;
4001             }
4002             for (j = 0; j < portion_count; ++j) {
4003               SetThreadPriority(handles[i + j], THREAD_PRIORITY_ABOVE_NORMAL);
4004             }
4005             timeout_left = (finish_time - start_time) / 1000000L;
4006             if (timeout_left < 0) {
4007               timeout_left = 0;
4008             }
4009             res = WaitForMultipleObjects(portion_count, handles + i, TRUE, timeout_left);
4010             if (res == WAIT_FAILED || res == WAIT_TIMEOUT) {
4011               warning("WaitForMultipleObjects %s (%u) in %s: %d\n",
4012                       (res == WAIT_FAILED ? "failed" : "timed out"),
4013                       GetLastError(), __FILE__, __LINE__);
4014               portion_count = handle_count - i;
4015             }
4016             for (j = 0; j < portion_count; ++j) {
4017               CloseHandle(handles[i + j]);
4018             }
4019             if ((i += portion_count) >= handle_count) {
4020               break;
4021             }
4022             start_time = os::javaTimeNanos();
4023           }
4024           handle_count = 0;
4025         }


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


< prev index next >