src/hotspot/share/runtime/thread.hpp
changeset 53103 67e3a8b3449c
parent 53084 293cec2f7670
child 53149 259c36ef27df
--- a/src/hotspot/share/runtime/thread.hpp	Wed Dec 26 19:24:00 2018 -0500
+++ b/src/hotspot/share/runtime/thread.hpp	Thu Dec 27 21:17:11 2018 -0500
@@ -110,6 +110,27 @@
 // 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;
@@ -120,7 +141,6 @@
   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.
@@ -142,6 +162,9 @@
   // 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;
 
@@ -418,6 +441,21 @@
  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.
@@ -796,6 +834,13 @@
   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();
@@ -803,12 +848,12 @@
   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.
+// 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;
@@ -844,7 +889,6 @@
   ~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; }
@@ -875,7 +919,7 @@
 // A single WatcherThread is used for simulating timer interrupts.
 class WatcherThread: public NonJavaThread {
   friend class VMStructs;
- public:
+ protected:
   virtual void run();
 
  private:
@@ -1832,9 +1876,9 @@
   void print_name_on_error(outputStream* st, char* buf, int buflen) const;
   void verify();
   const char* get_thread_name() const;
- private:
+ protected:
   // 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;
+  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;
@@ -1887,9 +1931,12 @@
 
   inline CompilerThread* as_CompilerThread();
 
- public:
+ protected:
+  virtual void pre_run();
   virtual void run();
   void thread_main_inner();
+  virtual void post_run();
+
 
  private:
   GrowableArray<oop>* _array_for_gc;