hotspot/src/os/windows/vm/os_windows.cpp
changeset 27459 7fce477785a3
parent 27458 eb5f1b4f01e1
child 27467 cdc1d5bc86cf
equal deleted inserted replaced
27458:eb5f1b4f01e1 27459:7fce477785a3
   434       thread->set_lgrp_id(lgrp_id);
   434       thread->set_lgrp_id(lgrp_id);
   435     }
   435     }
   436   }
   436   }
   437 
   437 
   438   // Diagnostic code to investigate JDK-6573254
   438   // Diagnostic code to investigate JDK-6573254
   439   int res = 90115;  // non-java thread
   439   int res = 50115;  // non-java thread
   440   if (thread->is_Java_thread()) {
   440   if (thread->is_Java_thread()) {
   441     res = 60115;    // java thread
   441     res = 40115;    // java thread
   442   }
   442   }
   443 
   443 
   444   // Install a win32 structured exception handler around every thread created
   444   // Install a win32 structured exception handler around every thread created
   445   // by VM, so VM can generate error dump when an exception occurred in non-
   445   // by VM, so VM can generate error dump when an exception occurred in non-
   446   // Java thread (e.g. VM thread).
   446   // Java thread (e.g. VM thread).
  3738   jio_snprintf(ebuf, ebuflen,
  3738   jio_snprintf(ebuf, ebuflen,
  3739                "os::win32::load_windows_dll() cannot load %s from system directories.", name);
  3739                "os::win32::load_windows_dll() cannot load %s from system directories.", name);
  3740   return NULL;
  3740   return NULL;
  3741 }
  3741 }
  3742 
  3742 
  3743 #define MIN_EXIT_MUTEXES 1
  3743 #define MAX_EXIT_HANDLES    16
  3744 #define MAX_EXIT_MUTEXES 16
  3744 #define EXIT_TIMEOUT      1000 /* 1 sec */
  3745 
  3745 
  3746 struct ExitMutexes {
  3746 static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) {
  3747   DWORD count;
  3747   InitializeCriticalSection((CRITICAL_SECTION*)pcrit_sect);
  3748   HANDLE handles[MAX_EXIT_MUTEXES];
       
  3749 };
       
  3750 
       
  3751 static BOOL CALLBACK init_muts_call(PINIT_ONCE, PVOID ppmuts, PVOID*) {
       
  3752   static ExitMutexes muts;
       
  3753 
       
  3754   muts.count = os::processor_count();
       
  3755   if (muts.count < MIN_EXIT_MUTEXES) {
       
  3756     muts.count = MIN_EXIT_MUTEXES;
       
  3757   } else if (muts.count > MAX_EXIT_MUTEXES) {
       
  3758     muts.count = MAX_EXIT_MUTEXES;
       
  3759   }
       
  3760 
       
  3761   for (DWORD i = 0; i < muts.count; ++i) {
       
  3762     muts.handles[i] = CreateMutex(NULL, FALSE, NULL);
       
  3763     if (muts.handles[i] == NULL) {
       
  3764       return FALSE;
       
  3765     }
       
  3766   }
       
  3767   *((ExitMutexes**)ppmuts) = &muts;
       
  3768   return TRUE;
  3748   return TRUE;
  3769 }
  3749 }
  3770 
  3750 
  3771 int os::win32::exit_process_or_thread(Ept what, int exit_code) {
  3751 int os::win32::exit_process_or_thread(Ept what, int exit_code) {
       
  3752   // Basic approach:
       
  3753   //  - Each exiting thread registers its intent to exit and then does so.
       
  3754   //  - A thread trying to terminate the process must wait for all
       
  3755   //    threads currently exiting to complete their exit.
       
  3756 
  3772   if (os::win32::has_exit_bug()) {
  3757   if (os::win32::has_exit_bug()) {
  3773     static INIT_ONCE init_once_muts = INIT_ONCE_STATIC_INIT;
  3758     // The array holds handles of the threads that have started exiting by calling
  3774     static ExitMutexes* pmuts;
  3759     // _endthreadex().
  3775 
  3760     // Should be large enough to avoid blocking the exiting thread due to lack of
  3776     if (!InitOnceExecuteOnce(&init_once_muts, init_muts_call, &pmuts, NULL)) {
  3761     // a free slot.
  3777       warning("ExitMutex initialization failed in %s: %d\n", __FILE__, __LINE__);
  3762     static HANDLE handles[MAX_EXIT_HANDLES];
  3778     } else if (WaitForMultipleObjects(pmuts->count, pmuts->handles,
  3763     static int handle_count = 0;
  3779                                       (what != EPT_THREAD), // exiting process waits for all mutexes
  3764 
  3780                                       INFINITE) == WAIT_FAILED) {
  3765     static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;
  3781       warning("ExitMutex acquisition failed in %s: %d\n", __FILE__, __LINE__);
  3766     static CRITICAL_SECTION crit_sect;
  3782     }
  3767     int i, j;
  3783   }
  3768     DWORD res;
  3784 
  3769     HANDLE hproc, hthr;
  3785   switch (what) {
  3770 
  3786   case EPT_THREAD:
  3771     // The first thread that reached this point, initializes the critical section.
       
  3772     if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) {
       
  3773       warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);
       
  3774     } else {
       
  3775       EnterCriticalSection(&crit_sect);
       
  3776 
       
  3777       if (what == EPT_THREAD) {
       
  3778         // Remove from the array those handles of the threads that have completed exiting.
       
  3779         for (i = 0, j = 0; i < handle_count; ++i) {
       
  3780           res = WaitForSingleObject(handles[i], 0 /* don't wait */);
       
  3781           if (res == WAIT_TIMEOUT) {
       
  3782             handles[j++] = handles[i];
       
  3783           } else {
       
  3784             if (res != WAIT_OBJECT_0) {
       
  3785               warning("WaitForSingleObject failed in %s: %d\n", __FILE__, __LINE__);
       
  3786               // Don't keep the handle, if we failed waiting for it.
       
  3787             }
       
  3788             CloseHandle(handles[i]);
       
  3789           }
       
  3790         }
       
  3791 
       
  3792         // If there's no free slot in the array of the kept handles, we'll have to
       
  3793         // wait until at least one thread completes exiting.
       
  3794         if ((handle_count = j) == MAX_EXIT_HANDLES) {
       
  3795           res = WaitForMultipleObjects(MAX_EXIT_HANDLES, handles, FALSE, EXIT_TIMEOUT);
       
  3796           if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAX_EXIT_HANDLES)) {
       
  3797             i = (res - WAIT_OBJECT_0);
       
  3798             handle_count = MAX_EXIT_HANDLES - 1;
       
  3799             for (; i < handle_count; ++i) {
       
  3800               handles[i] = handles[i + 1];
       
  3801             }
       
  3802           } else {
       
  3803             warning("WaitForMultipleObjects failed in %s: %d\n", __FILE__, __LINE__);
       
  3804             // Don't keep handles, if we failed waiting for them.
       
  3805             for (i = 0; i < MAX_EXIT_HANDLES; ++i) {
       
  3806               CloseHandle(handles[i]);
       
  3807             }
       
  3808             handle_count = 0;
       
  3809           }
       
  3810         }
       
  3811 
       
  3812         // Store a duplicate of the current thread handle in the array of handles.
       
  3813         hproc = GetCurrentProcess();
       
  3814         hthr = GetCurrentThread();
       
  3815         if (!DuplicateHandle(hproc, hthr, hproc, &handles[handle_count],
       
  3816                              0, FALSE, DUPLICATE_SAME_ACCESS)) {
       
  3817           warning("DuplicateHandle failed in %s: %d\n", __FILE__, __LINE__);
       
  3818         } else {
       
  3819           ++handle_count;
       
  3820         }
       
  3821 
       
  3822         // The current exiting thread has stored its handle in the array, and now
       
  3823         // should leave the critical section before calling _endthreadex().
       
  3824 
       
  3825       } else { // what != EPT_THREAD
       
  3826         if (handle_count > 0) {
       
  3827           // Before ending the process, make sure all the threads that had called
       
  3828           // _endthreadex() completed.
       
  3829           res = WaitForMultipleObjects(handle_count, handles, TRUE, EXIT_TIMEOUT);
       
  3830           if (res == WAIT_FAILED) {
       
  3831             warning("WaitForMultipleObjects failed in %s: %d\n", __FILE__, __LINE__);
       
  3832           }
       
  3833           for (i = 0; i < handle_count; ++i) {
       
  3834             CloseHandle(handles[i]);
       
  3835           }
       
  3836           handle_count = 0;
       
  3837         }
       
  3838 
       
  3839         // End the process, not leaving critical section.
       
  3840         // This makes sure no other thread executes exit-related code at the same
       
  3841         // time, thus a race is avoided.
       
  3842         if (what == EPT_PROCESS) {
       
  3843           ::exit(exit_code);
       
  3844         } else {
       
  3845           _exit(exit_code);
       
  3846         }
       
  3847       }
       
  3848 
       
  3849       LeaveCriticalSection(&crit_sect);
       
  3850     }
       
  3851   }
       
  3852 
       
  3853   // We are here if either
       
  3854   // - there's no 'race at exit' bug on this OS release;
       
  3855   // - initialization of the critical section failed (unlikely);
       
  3856   // - the current thread has stored its handle and left the critical section.
       
  3857   if (what == EPT_THREAD) {
  3787     _endthreadex((unsigned)exit_code);
  3858     _endthreadex((unsigned)exit_code);
  3788     break;
  3859   } else if (what == EPT_PROCESS) {
  3789 
       
  3790   case EPT_PROCESS:
       
  3791     ::exit(exit_code);
  3860     ::exit(exit_code);
  3792     break;
  3861   } else {
  3793 
       
  3794   case EPT_PROCESS_DIE:
       
  3795     _exit(exit_code);
  3862     _exit(exit_code);
  3796     break;
  3863   }
  3797   }
  3864 
  3798 
  3865   // Should not reach here
  3799   // should not reach here
       
  3800   return exit_code;
  3866   return exit_code;
  3801 }
  3867 }
  3802 
  3868 
  3803 #undef MIN_EXIT_MUTEXES
  3869 #undef MAX_EXIT_HANDLES
  3804 #undef MAX_EXIT_MUTEXES
  3870 #undef EXIT_TIMEOUT
  3805 
  3871 
  3806 void os::win32::setmode_streams() {
  3872 void os::win32::setmode_streams() {
  3807   _setmode(_fileno(stdin), _O_BINARY);
  3873   _setmode(_fileno(stdin), _O_BINARY);
  3808   _setmode(_fileno(stdout), _O_BINARY);
  3874   _setmode(_fileno(stdout), _O_BINARY);
  3809   _setmode(_fileno(stderr), _O_BINARY);
  3875   _setmode(_fileno(stderr), _O_BINARY);