33 #include "code/vtableStubs.hpp" |
33 #include "code/vtableStubs.hpp" |
34 #include "compiler/compileBroker.hpp" |
34 #include "compiler/compileBroker.hpp" |
35 #include "compiler/disassembler.hpp" |
35 #include "compiler/disassembler.hpp" |
36 #include "interpreter/interpreter.hpp" |
36 #include "interpreter/interpreter.hpp" |
37 #include "jvm_windows.h" |
37 #include "jvm_windows.h" |
|
38 #include "logging/log.hpp" |
38 #include "memory/allocation.inline.hpp" |
39 #include "memory/allocation.inline.hpp" |
39 #include "memory/filemap.hpp" |
40 #include "memory/filemap.hpp" |
40 #include "mutex_windows.inline.hpp" |
41 #include "mutex_windows.inline.hpp" |
41 #include "oops/oop.inline.hpp" |
42 #include "oops/oop.inline.hpp" |
42 #include "os_share_windows.hpp" |
43 #include "os_share_windows.hpp" |
69 #include "services/runtimeService.hpp" |
70 #include "services/runtimeService.hpp" |
70 #include "utilities/decoder.hpp" |
71 #include "utilities/decoder.hpp" |
71 #include "utilities/defaultStream.hpp" |
72 #include "utilities/defaultStream.hpp" |
72 #include "utilities/events.hpp" |
73 #include "utilities/events.hpp" |
73 #include "utilities/growableArray.hpp" |
74 #include "utilities/growableArray.hpp" |
|
75 #include "utilities/macros.hpp" |
74 #include "utilities/vmError.hpp" |
76 #include "utilities/vmError.hpp" |
75 |
77 |
76 #ifdef _DEBUG |
78 #ifdef _DEBUG |
77 #include <crtdbg.h> |
79 #include <crtdbg.h> |
78 #endif |
80 #endif |
434 int res = 30115; // non-java thread |
436 int res = 30115; // non-java thread |
435 if (thread->is_Java_thread()) { |
437 if (thread->is_Java_thread()) { |
436 res = 20115; // java thread |
438 res = 20115; // java thread |
437 } |
439 } |
438 |
440 |
|
441 log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").", os::current_thread_id()); |
|
442 |
439 // Install a win32 structured exception handler around every thread created |
443 // 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- |
444 // by VM, so VM can generate error dump when an exception occurred in non- |
441 // Java thread (e.g. VM thread). |
445 // Java thread (e.g. VM thread). |
442 __try { |
446 __try { |
443 thread->run(); |
447 thread->run(); |
444 } __except(topLevelExceptionFilter( |
448 } __except(topLevelExceptionFilter( |
445 (_EXCEPTION_POINTERS*)_exception_info())) { |
449 (_EXCEPTION_POINTERS*)_exception_info())) { |
446 // Nothing to do. |
450 // Nothing to do. |
447 } |
451 } |
448 |
452 |
|
453 log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id()); |
|
454 |
449 // One less thread is executing |
455 // One less thread is executing |
450 // When the VMThread gets here, the main thread may have already exited |
456 // When the VMThread gets here, the main thread may have already exited |
451 // which frees the CodeHeap containing the Atomic::add code |
457 // which frees the CodeHeap containing the Atomic::add code |
452 if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) { |
458 if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) { |
453 Atomic::dec_ptr((intptr_t*)&os::win32::_os_thread_count); |
459 Atomic::dec_ptr((intptr_t*)&os::win32::_os_thread_count); |
507 |
513 |
508 // Initial thread state is RUNNABLE |
514 // Initial thread state is RUNNABLE |
509 osthread->set_state(RUNNABLE); |
515 osthread->set_state(RUNNABLE); |
510 |
516 |
511 thread->set_osthread(osthread); |
517 thread->set_osthread(osthread); |
|
518 |
|
519 log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ").", |
|
520 os::current_thread_id()); |
|
521 |
512 return true; |
522 return true; |
513 } |
523 } |
514 |
524 |
515 bool os::create_main_thread(JavaThread* thread) { |
525 bool os::create_main_thread(JavaThread* thread) { |
516 #ifdef ASSERT |
526 #ifdef ASSERT |
526 // The primordial thread is runnable from the start) |
536 // The primordial thread is runnable from the start) |
527 _starting_thread->set_state(RUNNABLE); |
537 _starting_thread->set_state(RUNNABLE); |
528 |
538 |
529 thread->set_osthread(_starting_thread); |
539 thread->set_osthread(_starting_thread); |
530 return true; |
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; |
531 } |
563 } |
532 |
564 |
533 // Allocate and initialize a new OSThread |
565 // Allocate and initialize a new OSThread |
534 bool os::create_thread(Thread* thread, ThreadType thr_type, |
566 bool os::create_thread(Thread* thread, ThreadType thr_type, |
535 size_t stack_size) { |
567 size_t stack_size) { |
594 // for CreateThread() that can treat 'stack_size' as stack size. However we |
626 // for CreateThread() that can treat 'stack_size' as stack size. However we |
595 // are not supposed to call CreateThread() directly according to MSDN |
627 // are not supposed to call CreateThread() directly according to MSDN |
596 // document because JVM uses C runtime library. The good news is that the |
628 // document because JVM uses C runtime library. The good news is that the |
597 // flag appears to work with _beginthredex() as well. |
629 // flag appears to work with _beginthredex() as well. |
598 |
630 |
|
631 const unsigned initflag = CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION; |
599 HANDLE thread_handle = |
632 HANDLE thread_handle = |
600 (HANDLE)_beginthreadex(NULL, |
633 (HANDLE)_beginthreadex(NULL, |
601 (unsigned)stack_size, |
634 (unsigned)stack_size, |
602 (unsigned (__stdcall *)(void*)) java_start, |
635 (unsigned (__stdcall *)(void*)) java_start, |
603 thread, |
636 thread, |
604 CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, |
637 initflag, |
605 &thread_id); |
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 } |
606 |
648 |
607 if (thread_handle == NULL) { |
649 if (thread_handle == NULL) { |
608 // Need to clean up stuff we've allocated so far |
650 // Need to clean up stuff we've allocated so far |
609 CloseHandle(osthread->interrupt_event()); |
651 CloseHandle(osthread->interrupt_event()); |
610 thread->set_osthread(NULL); |
652 thread->set_osthread(NULL); |