< prev index next >

src/os/windows/vm/os_windows.cpp

Print this page
rev 10257 : 8149036: Add tracing for thread related events at os level
Reviewed-by: coleenp, mlarsson, dholmes


  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 // Must be at least Windows Vista or Server 2008 to use InitOnceExecuteOnce
  26 #define _WIN32_WINNT 0x0600
  27 
  28 // no precompiled headers
  29 #include "classfile/classLoader.hpp"
  30 #include "classfile/systemDictionary.hpp"
  31 #include "classfile/vmSymbols.hpp"
  32 #include "code/icBuffer.hpp"
  33 #include "code/vtableStubs.hpp"
  34 #include "compiler/compileBroker.hpp"
  35 #include "compiler/disassembler.hpp"
  36 #include "interpreter/interpreter.hpp"
  37 #include "jvm_windows.h"

  38 #include "memory/allocation.inline.hpp"
  39 #include "memory/filemap.hpp"
  40 #include "mutex_windows.inline.hpp"
  41 #include "oops/oop.inline.hpp"
  42 #include "os_share_windows.hpp"
  43 #include "os_windows.inline.hpp"
  44 #include "prims/jniFastGetField.hpp"
  45 #include "prims/jvm.h"
  46 #include "prims/jvm_misc.hpp"
  47 #include "runtime/arguments.hpp"
  48 #include "runtime/atomic.inline.hpp"
  49 #include "runtime/extendedPC.hpp"
  50 #include "runtime/globals.hpp"
  51 #include "runtime/interfaceSupport.hpp"
  52 #include "runtime/java.hpp"
  53 #include "runtime/javaCalls.hpp"
  54 #include "runtime/mutexLocker.hpp"
  55 #include "runtime/objectMonitor.hpp"
  56 #include "runtime/orderAccess.inline.hpp"
  57 #include "runtime/osThread.hpp"
  58 #include "runtime/perfMemory.hpp"
  59 #include "runtime/sharedRuntime.hpp"
  60 #include "runtime/statSampler.hpp"
  61 #include "runtime/stubRoutines.hpp"
  62 #include "runtime/thread.inline.hpp"
  63 #include "runtime/threadCritical.hpp"
  64 #include "runtime/timer.hpp"
  65 #include "runtime/vm_version.hpp"
  66 #include "semaphore_windows.hpp"
  67 #include "services/attachListener.hpp"
  68 #include "services/memTracker.hpp"
  69 #include "services/runtimeService.hpp"
  70 #include "utilities/decoder.hpp"
  71 #include "utilities/defaultStream.hpp"
  72 #include "utilities/events.hpp"
  73 #include "utilities/growableArray.hpp"

  74 #include "utilities/vmError.hpp"
  75 
  76 #ifdef _DEBUG
  77 #include <crtdbg.h>
  78 #endif
  79 
  80 
  81 #include <windows.h>
  82 #include <sys/types.h>
  83 #include <sys/stat.h>
  84 #include <sys/timeb.h>
  85 #include <objidl.h>
  86 #include <shlobj.h>
  87 
  88 #include <malloc.h>
  89 #include <signal.h>
  90 #include <direct.h>
  91 #include <errno.h>
  92 #include <fcntl.h>
  93 #include <io.h>


 419   _alloca(((pid ^ counter++) & 7) * 128);
 420 
 421   thread->initialize_thread_current();
 422 
 423   OSThread* osthr = thread->osthread();
 424   assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
 425 
 426   if (UseNUMA) {
 427     int lgrp_id = os::numa_get_group_id();
 428     if (lgrp_id != -1) {
 429       thread->set_lgrp_id(lgrp_id);
 430     }
 431   }
 432 
 433   // Diagnostic code to investigate JDK-6573254
 434   int res = 30115;  // non-java thread
 435   if (thread->is_Java_thread()) {
 436     res = 20115;    // java thread
 437   }
 438 


 439   // Install a win32 structured exception handler around every thread created
 440   // by VM, so VM can generate error dump when an exception occurred in non-
 441   // Java thread (e.g. VM thread).
 442   __try {
 443     thread->run();
 444   } __except(topLevelExceptionFilter(
 445                                      (_EXCEPTION_POINTERS*)_exception_info())) {
 446     // Nothing to do.
 447   }
 448 


 449   // One less thread is executing
 450   // When the VMThread gets here, the main thread may have already exited
 451   // which frees the CodeHeap containing the Atomic::add code
 452   if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {
 453     Atomic::dec_ptr((intptr_t*)&os::win32::_os_thread_count);
 454   }
 455 
 456   // Thread must not return from exit_process_or_thread(), but if it does,
 457   // let it proceed to exit normally
 458   return (unsigned)os::win32::exit_process_or_thread(os::win32::EPT_THREAD, res);
 459 }
 460 
 461 static OSThread* create_os_thread(Thread* thread, HANDLE thread_handle,
 462                                   int thread_id) {
 463   // Allocate the OSThread object
 464   OSThread* osthread = new OSThread(NULL, NULL);
 465   if (osthread == NULL) return NULL;
 466 
 467   // Initialize support for Java interrupts
 468   HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);


 492 
 493 bool os::create_attached_thread(JavaThread* thread) {
 494 #ifdef ASSERT
 495   thread->verify_not_published();
 496 #endif
 497   HANDLE thread_h;
 498   if (!DuplicateHandle(main_process, GetCurrentThread(), GetCurrentProcess(),
 499                        &thread_h, THREAD_ALL_ACCESS, false, 0)) {
 500     fatal("DuplicateHandle failed\n");
 501   }
 502   OSThread* osthread = create_os_thread(thread, thread_h,
 503                                         (int)current_thread_id());
 504   if (osthread == NULL) {
 505     return false;
 506   }
 507 
 508   // Initial thread state is RUNNABLE
 509   osthread->set_state(RUNNABLE);
 510 
 511   thread->set_osthread(osthread);




 512   return true;
 513 }
 514 
 515 bool os::create_main_thread(JavaThread* thread) {
 516 #ifdef ASSERT
 517   thread->verify_not_published();
 518 #endif
 519   if (_starting_thread == NULL) {
 520     _starting_thread = create_os_thread(thread, main_thread, main_thread_id);
 521     if (_starting_thread == NULL) {
 522       return false;
 523     }
 524   }
 525 
 526   // The primordial thread is runnable from the start)
 527   _starting_thread->set_state(RUNNABLE);
 528 
 529   thread->set_osthread(_starting_thread);
 530   return true;
 531 }
 532 






















 533 // Allocate and initialize a new OSThread
 534 bool os::create_thread(Thread* thread, ThreadType thr_type,
 535                        size_t stack_size) {
 536   unsigned thread_id;
 537 
 538   // Allocate the OSThread object
 539   OSThread* osthread = new OSThread(NULL, NULL);
 540   if (osthread == NULL) {
 541     return false;
 542   }
 543 
 544   // Initialize support for Java interrupts
 545   HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);
 546   if (interrupt_event == NULL) {
 547     delete osthread;
 548     return NULL;
 549   }
 550   osthread->set_interrupt_event(interrupt_event);
 551   osthread->set_interrupted(false);
 552 


 579   //
 580   // Contrary to what MSDN document says, "stack_size" in _beginthreadex()
 581   // does not specify stack size. Instead, it specifies the size of
 582   // initially committed space. The stack size is determined by
 583   // PE header in the executable. If the committed "stack_size" is larger
 584   // than default value in the PE header, the stack is rounded up to the
 585   // nearest multiple of 1MB. For example if the launcher has default
 586   // stack size of 320k, specifying any size less than 320k does not
 587   // affect the actual stack size at all, it only affects the initial
 588   // commitment. On the other hand, specifying 'stack_size' larger than
 589   // default value may cause significant increase in memory usage, because
 590   // not only the stack space will be rounded up to MB, but also the
 591   // entire space is committed upfront.
 592   //
 593   // Finally Windows XP added a new flag 'STACK_SIZE_PARAM_IS_A_RESERVATION'
 594   // for CreateThread() that can treat 'stack_size' as stack size. However we
 595   // are not supposed to call CreateThread() directly according to MSDN
 596   // document because JVM uses C runtime library. The good news is that the
 597   // flag appears to work with _beginthredex() as well.
 598 

 599   HANDLE thread_handle =
 600     (HANDLE)_beginthreadex(NULL,
 601                            (unsigned)stack_size,
 602                            (unsigned (__stdcall *)(void*)) java_start,
 603                            thread,
 604                            CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
 605                            &thread_id);









 606 
 607   if (thread_handle == NULL) {
 608     // Need to clean up stuff we've allocated so far
 609     CloseHandle(osthread->interrupt_event());
 610     thread->set_osthread(NULL);
 611     delete osthread;
 612     return NULL;
 613   }
 614 
 615   Atomic::inc_ptr((intptr_t*)&os::win32::_os_thread_count);
 616 
 617   // Store info on the Win32 thread into the OSThread
 618   osthread->set_thread_handle(thread_handle);
 619   osthread->set_thread_id(thread_id);
 620 
 621   // Initial thread state is INITIALIZED, not SUSPENDED
 622   osthread->set_state(INITIALIZED);
 623 
 624   // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain
 625   return true;




  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 // Must be at least Windows Vista or Server 2008 to use InitOnceExecuteOnce
  26 #define _WIN32_WINNT 0x0600
  27 
  28 // no precompiled headers
  29 #include "classfile/classLoader.hpp"
  30 #include "classfile/systemDictionary.hpp"
  31 #include "classfile/vmSymbols.hpp"
  32 #include "code/icBuffer.hpp"
  33 #include "code/vtableStubs.hpp"
  34 #include "compiler/compileBroker.hpp"
  35 #include "compiler/disassembler.hpp"
  36 #include "interpreter/interpreter.hpp"
  37 #include "jvm_windows.h"
  38 #include "logging/log.hpp"
  39 #include "memory/allocation.inline.hpp"
  40 #include "memory/filemap.hpp"
  41 #include "mutex_windows.inline.hpp"
  42 #include "oops/oop.inline.hpp"
  43 #include "os_share_windows.hpp"
  44 #include "os_windows.inline.hpp"
  45 #include "prims/jniFastGetField.hpp"
  46 #include "prims/jvm.h"
  47 #include "prims/jvm_misc.hpp"
  48 #include "runtime/arguments.hpp"
  49 #include "runtime/atomic.inline.hpp"
  50 #include "runtime/extendedPC.hpp"
  51 #include "runtime/globals.hpp"
  52 #include "runtime/interfaceSupport.hpp"
  53 #include "runtime/java.hpp"
  54 #include "runtime/javaCalls.hpp"
  55 #include "runtime/mutexLocker.hpp"
  56 #include "runtime/objectMonitor.hpp"
  57 #include "runtime/orderAccess.inline.hpp"
  58 #include "runtime/osThread.hpp"
  59 #include "runtime/perfMemory.hpp"
  60 #include "runtime/sharedRuntime.hpp"
  61 #include "runtime/statSampler.hpp"
  62 #include "runtime/stubRoutines.hpp"
  63 #include "runtime/thread.inline.hpp"
  64 #include "runtime/threadCritical.hpp"
  65 #include "runtime/timer.hpp"
  66 #include "runtime/vm_version.hpp"
  67 #include "semaphore_windows.hpp"
  68 #include "services/attachListener.hpp"
  69 #include "services/memTracker.hpp"
  70 #include "services/runtimeService.hpp"
  71 #include "utilities/decoder.hpp"
  72 #include "utilities/defaultStream.hpp"
  73 #include "utilities/events.hpp"
  74 #include "utilities/growableArray.hpp"
  75 #include "utilities/macros.hpp"
  76 #include "utilities/vmError.hpp"
  77 
  78 #ifdef _DEBUG
  79 #include <crtdbg.h>
  80 #endif
  81 
  82 
  83 #include <windows.h>
  84 #include <sys/types.h>
  85 #include <sys/stat.h>
  86 #include <sys/timeb.h>
  87 #include <objidl.h>
  88 #include <shlobj.h>
  89 
  90 #include <malloc.h>
  91 #include <signal.h>
  92 #include <direct.h>
  93 #include <errno.h>
  94 #include <fcntl.h>
  95 #include <io.h>


 421   _alloca(((pid ^ counter++) & 7) * 128);
 422 
 423   thread->initialize_thread_current();
 424 
 425   OSThread* osthr = thread->osthread();
 426   assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
 427 
 428   if (UseNUMA) {
 429     int lgrp_id = os::numa_get_group_id();
 430     if (lgrp_id != -1) {
 431       thread->set_lgrp_id(lgrp_id);
 432     }
 433   }
 434 
 435   // Diagnostic code to investigate JDK-6573254
 436   int res = 30115;  // non-java thread
 437   if (thread->is_Java_thread()) {
 438     res = 20115;    // java thread
 439   }
 440 
 441   log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").", os::current_thread_id());
 442 
 443   // Install a win32 structured exception handler around every thread created
 444   // by VM, so VM can generate error dump when an exception occurred in non-
 445   // Java thread (e.g. VM thread).
 446   __try {
 447     thread->run();
 448   } __except(topLevelExceptionFilter(
 449                                      (_EXCEPTION_POINTERS*)_exception_info())) {
 450     // Nothing to do.
 451   }
 452 
 453   log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id());
 454 
 455   // One less thread is executing
 456   // When the VMThread gets here, the main thread may have already exited
 457   // which frees the CodeHeap containing the Atomic::add code
 458   if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {
 459     Atomic::dec_ptr((intptr_t*)&os::win32::_os_thread_count);
 460   }
 461 
 462   // Thread must not return from exit_process_or_thread(), but if it does,
 463   // let it proceed to exit normally
 464   return (unsigned)os::win32::exit_process_or_thread(os::win32::EPT_THREAD, res);
 465 }
 466 
 467 static OSThread* create_os_thread(Thread* thread, HANDLE thread_handle,
 468                                   int thread_id) {
 469   // Allocate the OSThread object
 470   OSThread* osthread = new OSThread(NULL, NULL);
 471   if (osthread == NULL) return NULL;
 472 
 473   // Initialize support for Java interrupts
 474   HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);


 498 
 499 bool os::create_attached_thread(JavaThread* thread) {
 500 #ifdef ASSERT
 501   thread->verify_not_published();
 502 #endif
 503   HANDLE thread_h;
 504   if (!DuplicateHandle(main_process, GetCurrentThread(), GetCurrentProcess(),
 505                        &thread_h, THREAD_ALL_ACCESS, false, 0)) {
 506     fatal("DuplicateHandle failed\n");
 507   }
 508   OSThread* osthread = create_os_thread(thread, thread_h,
 509                                         (int)current_thread_id());
 510   if (osthread == NULL) {
 511     return false;
 512   }
 513 
 514   // Initial thread state is RUNNABLE
 515   osthread->set_state(RUNNABLE);
 516 
 517   thread->set_osthread(osthread);
 518 
 519   log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ").",
 520     os::current_thread_id());
 521 
 522   return true;
 523 }
 524 
 525 bool os::create_main_thread(JavaThread* thread) {
 526 #ifdef ASSERT
 527   thread->verify_not_published();
 528 #endif
 529   if (_starting_thread == NULL) {
 530     _starting_thread = create_os_thread(thread, main_thread, main_thread_id);
 531     if (_starting_thread == NULL) {
 532       return false;
 533     }
 534   }
 535 
 536   // The primordial thread is runnable from the start)
 537   _starting_thread->set_state(RUNNABLE);
 538 
 539   thread->set_osthread(_starting_thread);
 540   return true;
 541 }
 542 
 543 // Helper function to trace _beginthreadex attributes,
 544 //  similar to os::Posix::describe_pthread_attr()
 545 static char* describe_beginthreadex_attributes(char* buf, size_t buflen,
 546   size_t stacksize, unsigned initflag)
 547 {
 548   stringStream ss(buf, buflen);
 549   if (stacksize == 0) {
 550     ss.print("stacksize: default, ");
 551   } else {
 552     ss.print("stacksize: " SIZE_FORMAT "k, ", stacksize / 1024);
 553   }
 554   ss.print("flags: ");
 555   #define PRINT_FLAG(f) if (initflag & f) ss.print( XSTR(f) " ");
 556   #define ALL(X) \
 557     X(CREATE_SUSPENDED) \
 558     X(STACK_SIZE_PARAM_IS_A_RESERVATION)
 559   ALL(PRINT_FLAG)
 560   #undef ALL
 561   #undef PRINT_FLAG
 562   return buf;
 563 }
 564 
 565 // Allocate and initialize a new OSThread
 566 bool os::create_thread(Thread* thread, ThreadType thr_type,
 567                        size_t stack_size) {
 568   unsigned thread_id;
 569 
 570   // Allocate the OSThread object
 571   OSThread* osthread = new OSThread(NULL, NULL);
 572   if (osthread == NULL) {
 573     return false;
 574   }
 575 
 576   // Initialize support for Java interrupts
 577   HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);
 578   if (interrupt_event == NULL) {
 579     delete osthread;
 580     return NULL;
 581   }
 582   osthread->set_interrupt_event(interrupt_event);
 583   osthread->set_interrupted(false);
 584 


 611   //
 612   // Contrary to what MSDN document says, "stack_size" in _beginthreadex()
 613   // does not specify stack size. Instead, it specifies the size of
 614   // initially committed space. The stack size is determined by
 615   // PE header in the executable. If the committed "stack_size" is larger
 616   // than default value in the PE header, the stack is rounded up to the
 617   // nearest multiple of 1MB. For example if the launcher has default
 618   // stack size of 320k, specifying any size less than 320k does not
 619   // affect the actual stack size at all, it only affects the initial
 620   // commitment. On the other hand, specifying 'stack_size' larger than
 621   // default value may cause significant increase in memory usage, because
 622   // not only the stack space will be rounded up to MB, but also the
 623   // entire space is committed upfront.
 624   //
 625   // Finally Windows XP added a new flag 'STACK_SIZE_PARAM_IS_A_RESERVATION'
 626   // for CreateThread() that can treat 'stack_size' as stack size. However we
 627   // are not supposed to call CreateThread() directly according to MSDN
 628   // document because JVM uses C runtime library. The good news is that the
 629   // flag appears to work with _beginthredex() as well.
 630 
 631   const unsigned initflag = CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION;
 632   HANDLE thread_handle =
 633     (HANDLE)_beginthreadex(NULL,
 634                            (unsigned)stack_size,
 635                            (unsigned (__stdcall *)(void*)) java_start,
 636                            thread,
 637                            initflag,
 638                            &thread_id);
 639 
 640   char buf[64];
 641   if (thread_handle != NULL) {
 642     log_info(os, thread)("Thread started (tid: %u, attributes: %s)",
 643       thread_id, describe_beginthreadex_attributes(buf, sizeof(buf), stack_size, initflag));
 644   } else {
 645     log_warning(os, thread)("Failed to start thread - _beginthreadex failed (%s) for attributes: %s.",
 646       strerror(errno), describe_beginthreadex_attributes(buf, sizeof(buf), stack_size, initflag));
 647   }
 648 
 649   if (thread_handle == NULL) {
 650     // Need to clean up stuff we've allocated so far
 651     CloseHandle(osthread->interrupt_event());
 652     thread->set_osthread(NULL);
 653     delete osthread;
 654     return NULL;
 655   }
 656 
 657   Atomic::inc_ptr((intptr_t*)&os::win32::_os_thread_count);
 658 
 659   // Store info on the Win32 thread into the OSThread
 660   osthread->set_thread_handle(thread_handle);
 661   osthread->set_thread_id(thread_id);
 662 
 663   // Initial thread state is INITIALIZED, not SUSPENDED
 664   osthread->set_state(INITIALIZED);
 665 
 666   // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain
 667   return true;


< prev index next >