Creating a JavaThread and its java.lang.Thread oop

David Holmes - Sun Microsystems David.Holmes at Sun.COM
Tue Nov 6 14:31:05 PST 2007


Peter,

I agree with Tom. Initializing the pool should happen right at the very 
end of create_vm - as that should be the safest place. If you need to 
move it earlier then you can try that one step at a time later.

Your thread creation needs to be a combination, but variation, of 
attach_current_thread and JVM_StartThread. With attach_current_thread 
you have an existing native thread and need to create the JavaThread and 
java.lang.Thread. With JVM_StartThread you have a java.lang.Thread and 
need to create the JavaThread and native thread. With your pool you have 
nothing to start with so you need to:
- create the java.lang.Thread object
- invoke JVM_StartThread on it (logically not by an actual call) which 
will create the JavaThread and native thread

At present (and I haven't looked too deeply) it seems to me that you 
might be trying to create the new threads all associated with the 
current native thread. Create a raw java.lang.Thread first and then 
"start" it.

BTW if you initialize the pool during VM initialization then you 
shouldn't need to worry about any locking - the main thread is the only 
one that will be interacting with the pool.

Hope this helps.

David Holmes

Peter Helfer said the following on  7/11/07 03:04 AM:
> Hi all
> 
> I am still trying to get my thread pool, so far without real luck... ok, 
> so here is how I'm trying to achieve it:
> 
> - I'm preparing my own subsystem from runtime/init.cpp, which creates 
> some runtime-code etc..
> - When starting up (runtime/thread.cpp: Threads::create_vm(..) ), I'm 
> starting the thread pool
>   after everything is done, shortly before vm_init_completed is set, so 
> I can use Universe::...
> - I've been seeing a lot of different assertion errors, so I'm now 
> completely exhausted :-(
> 
> [create_vm(..)]:
>  initialize_class(vmSymbolHandles::java_lang_Compiler(), CHECK_0);
>  reset_vm_info_property(CHECK_0);
>  threadpool_init2(); // HERE COMES THE THREAD POOL
>  quicken_jni_functions();
>  set_init_completed();
>  HS_DTRACE_PROBE(hotspot, vm__init__end);
>  Management::record_vm_init_completed();
> 
> Now in this function I'm calling the constructor to it which calls the 
> initialize() function:
> 
> void Threadpool::initialize(){ // is called indirectly by 
> threadpool_init2();
>         assert(Threadpool::get_SpinWaitEntry() != 0, "the spin wait 
> entry is missing!");
>         Threadpool::might_be_available = 0; // static peek variable
>         Threadpool::threadID = 1; //static var
> 
>         // MutexLocker ml(ThreadPool); -
>         /* THIS CAUSED SOME LOCK INVERSION..
>          * it is skipped, but still safe, as all clients to this pool 
> first ask might_be_available > 0, which
>          * isnt the case. But it would be nicer..
>          */
> 
>         if(TracePoolGen) FlagSetting fs(TraceThreadEvents, true);
>         for(int i = 0; i < _size; i++){
>                 _pool[i] = 
> createThread((ThreadFunction)Speculation::get_SpinWaitEntry());
>                 Thread::start(_pool[i]); // and start it immediately
>         }
>         Threadpool::might_be_available = _size;
> }
> 
> This now calls the real creator:
> 
> JavaThread* Threadpool::createThread(ThreadFunction entrypoint){
>         EXCEPTION_MARK; // creates a ExceptionMark and THREAD
>         JavaThread* result_thread = NULL;
>         {
>                 result_thread = new JavaThread(entrypoint); //size = 0
>                 if (result_thread->osthread() != NULL) {
>                         oop group = Universe::main_thread_group();
>                         bool attach_failed = false;
>                         {
>                                 HandleMark hm(THREAD);
>                                 Handle thread_group(THREAD, group);
>                                 
> result_thread->allocate_threadObj(thread_group, "fromThreadPool", false, 
> THREAD);
>                                 if (HAS_PENDING_EXCEPTION) {
>                                         CLEAR_PENDING_EXCEPTION;
>                                         // cleanup outside the handle mark.
>                                         attach_failed = true;
>                                 }
>                         }
>                         if(attach_failed){
>                                 delete result_thread;
>                                 result_thread = NULL;
>                         }
>                 } else {
>                      delete result_thread;
>                      result_thread = NULL;
>                 }
>         }
>         return result_thread;
> }
> 
> 
> Now I've seen different errors with different configurations...
>  - inverted locks
>  - SIGSEV (that was before splitting the init into 2 parts...)
>  - looping forever with TracePoolGen/TraceThreadEvents set...
>     creating thread 0x8084800
>     creating thread 0x8086400
>     creating thread 0x8088000
>     creating thread 0x8089c00
>     creating thread 0x808b800
>     creating thread 0x808d400
>     creating thread 0x808f000
>     creating thread 0x8090c00
>     creating thread 0x8092800
>     creating thread 0x8094800
>     Thread::set priority 0x0806d400 [4d6c] main (prio: 5)
>     creating thread 0x80d4800
>     Thread::set priority 0x080d4800 [4d83] Reference Handler (prio: 10)
>     Thread::start 0x080d4800 [4d83] Reference Handler (prio: 10)
>     creating thread 0x80d6000
>     .. and here nothing happens anymore
>  - and the current one:
>     Internal Error 
> (/home/peterh/workspace/openjdk/hotspot/src/share/vm/runtime/handles.cpp:40), 
> pid=18280, tid=3084282768
>     #  Error: assert(thread == Thread::current(),"sanity check")
> 
> 
> Could somebody maybe point me in the right direction, or even hand out a 
> correct piece of code ? It seems that I am missing important parts, but 
> I have no clue what to look for.. and before I smash my monitor, I 
> rather give in and try to continue at a different end of my project..
> 
> Thanks & Regards,
> 
> Peter
> 
> 
> 
> 



More information about the hotspot-runtime-dev mailing list