< prev index next >
src/hotspot/share/runtime/thread.hpp
Print this page
*** 107,127 ****
//
// All Thread subclasses must be either JavaThread or NonJavaThread.
// This means !t->is_Java_thread() iff t is a NonJavaThread, or t is
// a partially constructed/destroyed Thread.
class Thread: public ThreadShadow {
friend class VMStructs;
friend class JVMCIVMStructs;
private:
#ifndef USE_LIBRARY_BASED_TLS_ONLY
// Current thread is maintained as a thread-local variable
static THREAD_LOCAL_DECL Thread* _thr_current;
#endif
- private:
// Thread local data area available to the GC. The internal
// structure and contents of this data area is GC-specific.
// Only GC and GC barrier code should access this data area.
GCThreadLocalData _gc_data;
--- 107,151 ----
//
// All Thread subclasses must be either JavaThread or NonJavaThread.
// This means !t->is_Java_thread() iff t is a NonJavaThread, or t is
// a partially constructed/destroyed Thread.
+ /*
+ Thread execution sequence and actions:
+
+ All threads:
+ - thread_native_entry // per-OS native entry point
+ - stack initialization
+ - other OS-level initialization (signal masks etc)
+ - handshake with creating thread (if not started suspended)
+ - this->call_run() // common shared entry point
+ - shared common initialization
+ - this->pre_run() // virtual per-thread-type initialization
+ - this->run() // virtual per-thread-type "main" logic
+ - shared common tear-down
+ - this->post_run() // virtual per-thread-type tear-down
+ - // 'this' no longer referenceable
+ - OS-level tear-down (minimal)
+ - final logging
+
+ For JavaThread:
+ - this->run() // virtual but not normally overridden
+ - this->thread_main_inner() // extra call level to ensure correct stack calculations
+ - this->entry_point() // set differently for each kind of JavaThread
+
+ */
+
class Thread: public ThreadShadow {
friend class VMStructs;
friend class JVMCIVMStructs;
private:
#ifndef USE_LIBRARY_BASED_TLS_ONLY
// Current thread is maintained as a thread-local variable
static THREAD_LOCAL_DECL Thread* _thr_current;
#endif
// Thread local data area available to the GC. The internal
// structure and contents of this data area is GC-specific.
// Only GC and GC barrier code should access this data area.
GCThreadLocalData _gc_data;
*** 139,148 ****
--- 163,175 ----
// (Note: _pending_exception and friends are in ThreadShadow)
//oop _pending_exception; // pending exception for current thread
// const char* _exception_file; // file information for exception (debugging only)
// int _exception_line; // line information for exception (debugging only)
protected:
+
+ DEBUG_ONLY(static Thread* _starting_thread;)
+
// Support for forcing alignment of thread objects for biased locking
void* _real_malloc_address;
// JavaThread lifecycle support:
friend class SafeThreadsListPtr; // for _threads_list_ptr, cmpxchg_threads_hazard_ptr(), {dec_,inc_,}nested_threads_hazard_ptr_cnt(), {g,s}et_threads_hazard_ptr(), inc_nested_handle_cnt(), tag_hazard_ptr() access
*** 415,424 ****
--- 442,466 ----
static void clear_thread_current(); // TLS cleanup needed before threads terminate
protected:
// To be implemented by children.
virtual void run() = 0;
+ virtual void pre_run() = 0;
+ virtual void post_run() = 0; // Note: Thread must not be deleted prior to calling this!
+
+ #ifdef ASSERT
+ enum RunState {
+ PRE_CALL_RUN,
+ CALL_RUN,
+ PRE_RUN,
+ RUN,
+ POST_RUN
+ // POST_CALL_RUN - can't define this one as 'this' may be deleted when we want to set it
+ };
+ RunState _run_state; // for lifecycle checks
+ #endif
+
public:
// invokes <ChildThreadClass>::run(), with common preparations and cleanups.
void call_run();
*** 793,813 ****
NonJavaThread* volatile _next;
class List;
static List _the_list;
public:
NonJavaThread();
~NonJavaThread();
class Iterator;
};
! // Provides iteration over the list of NonJavaThreads. Because list
! // management occurs in the NonJavaThread constructor and destructor,
! // entries in the list may not be fully constructed instances of a
! // derived class. Threads created after an iterator is constructed
// will not be visited by the iterator. The scope of an iterator is a
// critical section; there must be no safepoint checks in that scope.
class NonJavaThread::Iterator : public StackObj {
uint _protect_enter;
NonJavaThread* _current;
--- 835,871 ----
NonJavaThread* volatile _next;
class List;
static List _the_list;
+ void add_to_the_list();
+ void remove_from_the_list();
+
+ protected:
+ virtual void pre_run();
+ virtual void post_run();
+
public:
NonJavaThread();
~NonJavaThread();
class Iterator;
};
! // Provides iteration over the list of NonJavaThreads.
! // Normal list addition occurs in pre_run(), and removal occurs
! // in post_run(), so that only live fully-initialized threads can
! // be found in the list. There is a special case during VM startup
! // when the BarrierSet has not yet been created, where we add to the
! // list during the constructor. That set of initial threads (the main
! // thread, plus GC threads typically) is iterated over when the
! // BarrierSet is set and each thread is manually updated. The fact those
! // threads may not yet have executed is not an issue for that code.
! // However it is possible that those threads may still not have executed
! // by the time subsequent iterators are created and used - but they are
! // known to be fully initialized by their creating thread.
! // Threads created after an iterator is constructed
// will not be visited by the iterator. The scope of an iterator is a
// critical section; there must be no safepoint checks in that scope.
class NonJavaThread::Iterator : public StackObj {
uint _protect_enter;
NonJavaThread* _current;
*** 841,851 ****
public:
NamedThread();
~NamedThread();
// May only be called once per thread.
void set_name(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
- void initialize_named_thread();
virtual bool is_Named_thread() const { return true; }
virtual char* name() const { return _name == NULL ? (char*)"Unknown Thread" : _name; }
JavaThread *processed_thread() { return _processed_thread; }
void set_processed_thread(JavaThread *thread) { _processed_thread = thread; }
virtual void print_on(outputStream* st) const;
--- 899,908 ----
*** 872,882 ****
};
// A single WatcherThread is used for simulating timer interrupts.
class WatcherThread: public NonJavaThread {
friend class VMStructs;
! public:
virtual void run();
private:
static WatcherThread* _watcher_thread;
--- 929,939 ----
};
// A single WatcherThread is used for simulating timer interrupts.
class WatcherThread: public NonJavaThread {
friend class VMStructs;
! protected:
virtual void run();
private:
static WatcherThread* _watcher_thread;
*** 1829,1841 ****
void print_thread_state() const PRODUCT_RETURN;
void print_on_error(outputStream* st, char* buf, int buflen) const;
void print_name_on_error(outputStream* st, char* buf, int buflen) const;
void verify();
const char* get_thread_name() const;
! private:
// factor out low-level mechanics for use in both normal and error cases
! const char* get_thread_name_string(char* buf = NULL, int buflen = 0) const;
public:
const char* get_threadgroup_name() const;
const char* get_parent_name() const;
// Accessing frames
--- 1886,1898 ----
void print_thread_state() const PRODUCT_RETURN;
void print_on_error(outputStream* st, char* buf, int buflen) const;
void print_name_on_error(outputStream* st, char* buf, int buflen) const;
void verify();
const char* get_thread_name() const;
! protected:
// factor out low-level mechanics for use in both normal and error cases
! virtual const char* get_thread_name_string(char* buf = NULL, int buflen = 0) const;
public:
const char* get_threadgroup_name() const;
const char* get_parent_name() const;
// Accessing frames
*** 1884,1896 ****
// operation. You may not want that either.
static JavaThread* active();
inline CompilerThread* as_CompilerThread();
! public:
virtual void run();
void thread_main_inner();
private:
GrowableArray<oop>* _array_for_gc;
public:
--- 1941,1956 ----
// operation. You may not want that either.
static JavaThread* active();
inline CompilerThread* as_CompilerThread();
! protected:
! virtual void pre_run();
virtual void run();
void thread_main_inner();
+ virtual void post_run();
+
private:
GrowableArray<oop>* _array_for_gc;
public:
< prev index next >