//Allocate and initialize a new OSThreadboolos::create_thread(Thread*thread, ThreadType thr_type, size_t stack_size) {
unsigned thread_id;//Allocate the OSThread objectOSThread*osthread=newOSThread(NULL, NULL);if(osthread==NULL) {returnfalse;
}//Initial state is ALLOCATED but not INITIALIZED{
MutexLockerEx ml(thread->SR_lock(), Mutex::_no_safepoint_check_flag);
osthread->set_state(ALLOCATED);
}//Initialize support for Java interruptsHANDLE interrupt_event=CreateEvent(NULL,true,false, NULL);if(interrupt_event==NULL) {
delete osthread;returnNULL;
}
osthread->set_interrupt_event(interrupt_event);
osthread->set_interrupted(false);
thread->set_osthread(osthread);if(stack_size==0) {switch(thr_type) {caseos::java_thread://Java threads use ThreadStackSize which default value can be changed with the flag -Xssif(JavaThread::stack_size_at_create()>0)
stack_size=JavaThread::stack_size_at_create();break;caseos::compiler_thread:if(CompilerThreadStackSize>0) {
stack_size=(size_t)(CompilerThreadStackSize*K);break;
}//else fall through://use VMThreadStackSize if CompilerThreadStackSize is not definedcaseos::vm_thread:caseos::pgc_thread:caseos::cgc_thread:caseos::watcher_thread:if(VMThreadStackSize>0) stack_size=(size_t)(VMThreadStackSize*K);break;
}
}//Create the Win32 threadContrary to what MSDN document says, "stack_size" in _beginthreadex()//does not specify stack size. Instead, it specifies the size of//initially committed space. The stack size is determined by//PE header in the executable. If the committed "stack_size" is larger//than default value in the PE header, the stack is rounded up to the//nearest multiple of 1MB. For example if the launcher has default//stack size of 320k, specifying any size less than 320k does not//affect the actual stack size at all, it only affects the initial//commitment. On the other hand, specifying 'stack_size' larger than//default value may cause significant increase in memory usage, because//not only the stack space will be rounded up to MB, but also the//entire space is committed upfront.Finally Windows XP added a new flag 'STACK_SIZE_PARAM_IS_A_RESERVATION'//for CreateThread() that can treat 'stack_size' as stack size. However we//are not supposed to call CreateThread() directly according to MSDN//document because JVM uses C runtime library. The good news is that the//flag appears to work with _beginthredex() as well.#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION#defineSTACK_SIZE_PARAM_IS_A_RESERVATION (0x10000)#endifHANDLE thread_handle=(HANDLE)_beginthreadex(NULL,
(unsigned)stack_size,
(unsigned (__stdcall*)(void*)) java_start,
thread,
CREATE_SUSPENDED|STACK_SIZE_PARAM_IS_A_RESERVATION,&thread_id);if(thread_handle==NULL) {//perhaps STACK_SIZE_PARAM_IS_A_RESERVATION is not supported, try again//without the flag.thread_handle=(HANDLE)_beginthreadex(NULL,
(unsigned)stack_size,
(unsigned (__stdcall*)(void*)) java_start,
thread,
CREATE_SUSPENDED,&thread_id);
}if(thread_handle==NULL) {//Need to clean up stuff we've allocated so farCloseHandle(osthread->interrupt_event());
thread->set_osthread(NULL);
delete osthread;returnNULL;
}
Atomic::inc_ptr((intptr_t*)&os::win32::_os_thread_count);//Store info on the Win32 thread into the OSThreadosthread->set_thread_handle(thread_handle);
osthread->set_thread_id(thread_id);//Initial thread state is INITIALIZED, not SUSPENDED{
MutexLockerEx ml(thread->SR_lock(), Mutex::_no_safepoint_check_flag);
osthread->set_state(INITIALIZED);
}//The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chainreturntrue;
}