1 /*
  2  * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_RUNTIME_OSTHREAD_HPP
 26 #define SHARE_RUNTIME_OSTHREAD_HPP
 27 
 28 #include "runtime/frame.hpp"
 29 #include "runtime/handles.hpp"
 30 #include "runtime/javaFrameAnchor.hpp"
 31 #include "runtime/suspendedThreadTask.hpp"
 32 #include "utilities/macros.hpp"
 33 
 34 #if defined(LINUX) || defined(AIX) || defined(BSD)
 35 #include "suspendResume_posix.hpp"
 36 #endif
 37 
 38 class Monitor;
 39 
 40 // The OSThread class holds OS-specific thread information.  It is equivalent
 41 // to the sys_thread_t structure of the classic JVM implementation.
 42 
 43 // The thread states represented by the ThreadState values are platform-specific
 44 // and are likely to be only approximate, because most OSes don't give you access
 45 // to precise thread state information.
 46 
 47 // Note: the ThreadState is legacy code and is not correctly implemented.
 48 // Uses of ThreadState need to be replaced by the state in the JavaThread.
 49 
 50 enum ThreadState {
 51   ALLOCATED,                    // Memory has been allocated but not initialized
 52   INITIALIZED,                  // The thread has been initialized but yet started
 53   RUNNABLE,                     // Has been started and is runnable, but not necessarily running
 54   MONITOR_WAIT,                 // Waiting on a contended monitor lock
 55   CONDVAR_WAIT,                 // Waiting on a condition variable
 56   OBJECT_WAIT,                  // Waiting on an Object.wait() call
 57   BREAKPOINTED,                 // Suspended at breakpoint
 58   SLEEPING,                     // Thread.sleep()
 59   ZOMBIE                        // All done, but not reclaimed yet
 60 };
 61 
 62 typedef int (*OSThreadStartFunc)(void*);
 63 
 64 class OSThread: public CHeapObj<mtThread> {
 65   friend class VMStructs;
 66   friend class JVMCIVMStructs;
 67  private:
 68   volatile ThreadState _state;    // Thread state *hint*
 69 
 70   // Methods
 71  public:
 72   void set_state(ThreadState state)                { _state = state; }
 73   ThreadState get_state()                          { return _state; }
 74 
 75   OSThread();
 76   ~OSThread();
 77 
 78   // Printing
 79   void print_on(outputStream* st) const;
 80   void print() const;
 81 
 82   // Platform dependent stuff
 83 #include OS_HEADER(osThread)
 84 
 85  public:
 86 
 87   thread_id_t thread_id() const                   { return _thread_id; }
 88 
 89   void set_thread_id(thread_id_t id)              { _thread_id = id; }
 90 
 91  private:
 92   // _thread_id is kernel thread id (similar to LWP id on Solaris). Each
 93   // thread has a unique thread_id (BsdThreads or NPTL). It can be used
 94   // to access /proc.
 95   thread_id_t _thread_id;
 96 };
 97 
 98 
 99 // Utility class for use with condition variables:
100 class OSThreadWaitState : public StackObj {
101   OSThread*   _osthread;
102   ThreadState _old_state;
103  public:
104   OSThreadWaitState(OSThread* osthread, bool is_object_wait) {
105     _osthread  = osthread;
106     _old_state = osthread->get_state();
107     if (is_object_wait) {
108       osthread->set_state(OBJECT_WAIT);
109     } else {
110       osthread->set_state(CONDVAR_WAIT);
111     }
112   }
113   ~OSThreadWaitState() {
114     _osthread->set_state(_old_state);
115   }
116 };
117 
118 
119 // Utility class for use with contended monitors:
120 class OSThreadContendState : public StackObj {
121   OSThread*   _osthread;
122   ThreadState _old_state;
123  public:
124   OSThreadContendState(OSThread* osthread) {
125     _osthread  = osthread;
126     _old_state = osthread->get_state();
127     osthread->set_state(MONITOR_WAIT);
128   }
129   ~OSThreadContendState() {
130     _osthread->set_state(_old_state);
131   }
132 };
133 
134 #endif // SHARE_RUNTIME_OSTHREAD_HPP