< prev index next >

src/hotspot/share/runtime/thread.hpp

Print this page

        

*** 108,128 **** // // 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; --- 108,148 ---- // // 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;
*** 140,149 **** --- 160,172 ---- // (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
*** 416,425 **** --- 439,463 ---- 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();
*** 794,816 **** 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; // Noncopyable. --- 832,861 ---- 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. ! // 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. ! // 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; // Noncopyable.
*** 842,852 **** 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; --- 887,896 ----
*** 873,883 **** }; // 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; --- 917,927 ---- }; // 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;
*** 1830,1842 **** 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 --- 1874,1886 ---- 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
*** 1885,1897 **** // 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: --- 1929,1944 ---- // 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 >