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