< 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 >