hotspot/src/share/vm/runtime/objectMonitor.hpp
changeset 6975 dc9b63952682
parent 5547 f4b087cbb361
child 7397 5b173b4ca846
equal deleted inserted replaced
6971:11c11e616b91 6975:dc9b63952682
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    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
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    21  * questions.
    22  *
    22  *
    23  */
    23  */
       
    24 
       
    25 
       
    26 // ObjectWaiter serves as a "proxy" or surrogate thread.
       
    27 // TODO-FIXME: Eliminate ObjectWaiter and use the thread-specific
       
    28 // ParkEvent instead.  Beware, however, that the JVMTI code
       
    29 // knows about ObjectWaiters, so we'll have to reconcile that code.
       
    30 // See next_waiter(), first_waiter(), etc.
       
    31 
       
    32 class ObjectWaiter : public StackObj {
       
    33  public:
       
    34   enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ } ;
       
    35   enum Sorted  { PREPEND, APPEND, SORTED } ;
       
    36   ObjectWaiter * volatile _next;
       
    37   ObjectWaiter * volatile _prev;
       
    38   Thread*       _thread;
       
    39   ParkEvent *   _event;
       
    40   volatile int  _notified ;
       
    41   volatile TStates TState ;
       
    42   Sorted        _Sorted ;           // List placement disposition
       
    43   bool          _active ;           // Contention monitoring is enabled
       
    44  public:
       
    45   ObjectWaiter(Thread* thread);
       
    46 
       
    47   void wait_reenter_begin(ObjectMonitor *mon);
       
    48   void wait_reenter_end(ObjectMonitor *mon);
       
    49 };
    24 
    50 
    25 // WARNING:
    51 // WARNING:
    26 //   This is a very sensitive and fragile class. DO NOT make any
    52 //   This is a very sensitive and fragile class. DO NOT make any
    27 // change unless you are fully aware of the underlying semantics.
    53 // change unless you are fully aware of the underlying semantics.
    28 
    54 
    35 // transformed from the lightweight structure of the thread stack to a
    61 // transformed from the lightweight structure of the thread stack to a
    36 // heavy weight lock due to contention
    62 // heavy weight lock due to contention
    37 
    63 
    38 // It is also used as RawMonitor by the JVMTI
    64 // It is also used as RawMonitor by the JVMTI
    39 
    65 
    40 
       
    41 class ObjectWaiter;
       
    42 
    66 
    43 class ObjectMonitor {
    67 class ObjectMonitor {
    44  public:
    68  public:
    45   enum {
    69   enum {
    46     OM_OK,                    // no error
    70     OM_OK,                    // no error
    72   static int (*SpinCallbackFunction)(intptr_t, int) ;
    96   static int (*SpinCallbackFunction)(intptr_t, int) ;
    73   static intptr_t SpinCallbackArgument ;
    97   static intptr_t SpinCallbackArgument ;
    74 
    98 
    75 
    99 
    76  public:
   100  public:
    77   ObjectMonitor();
       
    78   ~ObjectMonitor();
       
    79 
       
    80   markOop   header() const;
   101   markOop   header() const;
    81   void      set_header(markOop hdr);
   102   void      set_header(markOop hdr);
    82 
   103 
    83   intptr_t  is_busy() const;
   104   intptr_t is_busy() const {
       
   105     // TODO-FIXME: merge _count and _waiters.
       
   106     // TODO-FIXME: assert _owner == null implies _recursions = 0
       
   107     // TODO-FIXME: assert _WaitSet != null implies _count > 0
       
   108     return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList ) ;
       
   109   }
       
   110 
    84   intptr_t  is_entered(Thread* current) const;
   111   intptr_t  is_entered(Thread* current) const;
    85 
   112 
    86   void*     owner() const;
   113   void*     owner() const;
    87   void      set_owner(void* owner);
   114   void      set_owner(void* owner);
    88 
   115 
    89   intptr_t  waiters() const;
   116   intptr_t  waiters() const;
    90 
   117 
    91   intptr_t  count() const;
   118   intptr_t  count() const;
    92   void      set_count(intptr_t count);
   119   void      set_count(intptr_t count);
    93   intptr_t  contentions() const ;
   120   intptr_t  contentions() const ;
       
   121   intptr_t  recursions() const                                         { return _recursions; }
    94 
   122 
    95   // JVM/DI GetMonitorInfo() needs this
   123   // JVM/DI GetMonitorInfo() needs this
    96   Thread *  thread_of_waiter (ObjectWaiter *) ;
   124   ObjectWaiter* first_waiter()                                         { return _WaitSet; }
    97   ObjectWaiter * first_waiter () ;
   125   ObjectWaiter* next_waiter(ObjectWaiter* o)                           { return o->_next; }
    98   ObjectWaiter * next_waiter(ObjectWaiter* o);
   126   Thread* thread_of_waiter(ObjectWaiter* o)                            { return o->_thread; }
    99 
   127 
   100   intptr_t  recursions() const { return _recursions; }
   128   // initialize the monitor, exception the semaphore, all other fields
       
   129   // are simple integers or pointers
       
   130   ObjectMonitor() {
       
   131     _header       = NULL;
       
   132     _count        = 0;
       
   133     _waiters      = 0,
       
   134     _recursions   = 0;
       
   135     _object       = NULL;
       
   136     _owner        = NULL;
       
   137     _WaitSet      = NULL;
       
   138     _WaitSetLock  = 0 ;
       
   139     _Responsible  = NULL ;
       
   140     _succ         = NULL ;
       
   141     _cxq          = NULL ;
       
   142     FreeNext      = NULL ;
       
   143     _EntryList    = NULL ;
       
   144     _SpinFreq     = 0 ;
       
   145     _SpinClock    = 0 ;
       
   146     OwnerIsThread = 0 ;
       
   147   }
       
   148 
       
   149   ~ObjectMonitor() {
       
   150    // TODO: Add asserts ...
       
   151    // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
       
   152    // _count == 0 _EntryList  == NULL etc
       
   153   }
       
   154 
       
   155 private:
       
   156   void Recycle () {
       
   157     // TODO: add stronger asserts ...
       
   158     // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
       
   159     // _count == 0 EntryList  == NULL
       
   160     // _recursions == 0 _WaitSet == NULL
       
   161     // TODO: assert (is_busy()|_recursions) == 0
       
   162     _succ          = NULL ;
       
   163     _EntryList     = NULL ;
       
   164     _cxq           = NULL ;
       
   165     _WaitSet       = NULL ;
       
   166     _recursions    = 0 ;
       
   167     _SpinFreq      = 0 ;
       
   168     _SpinClock     = 0 ;
       
   169     OwnerIsThread  = 0 ;
       
   170   }
       
   171 
       
   172 public:
   101 
   173 
   102   void*     object() const;
   174   void*     object() const;
   103   void*     object_addr();
   175   void*     object_addr();
   104   void      set_object(void* obj);
   176   void      set_object(void* obj);
   105 
   177 
   120 
   192 
   121 // Use the following at your own risk
   193 // Use the following at your own risk
   122   intptr_t  complete_exit(TRAPS);
   194   intptr_t  complete_exit(TRAPS);
   123   void      reenter(intptr_t recursions, TRAPS);
   195   void      reenter(intptr_t recursions, TRAPS);
   124 
   196 
   125   int       raw_enter(TRAPS);
   197  private:
   126   int       raw_exit(TRAPS);
       
   127   int       raw_wait(jlong millis, bool interruptable, TRAPS);
       
   128   int       raw_notify(TRAPS);
       
   129   int       raw_notifyAll(TRAPS);
       
   130 
       
   131  private:
       
   132   // JVMTI support -- remove ASAP
       
   133   int       SimpleEnter (Thread * Self) ;
       
   134   int       SimpleExit  (Thread * Self) ;
       
   135   int       SimpleWait  (Thread * Self, jlong millis) ;
       
   136   int       SimpleNotify (Thread * Self, bool All) ;
       
   137 
       
   138  private:
       
   139   void      Recycle () ;
       
   140   void      AddWaiter (ObjectWaiter * waiter) ;
   198   void      AddWaiter (ObjectWaiter * waiter) ;
       
   199   static    void DeferredInitialize();
   141 
   200 
   142   ObjectWaiter * DequeueWaiter () ;
   201   ObjectWaiter * DequeueWaiter () ;
   143   void      DequeueSpecificWaiter (ObjectWaiter * waiter) ;
   202   void      DequeueSpecificWaiter (ObjectWaiter * waiter) ;
   144   void      EnterI (TRAPS) ;
   203   void      EnterI (TRAPS) ;
   145   void      ReenterI (Thread * Self, ObjectWaiter * SelfNode) ;
   204   void      ReenterI (Thread * Self, ObjectWaiter * SelfNode) ;
   170 
   229 
   171   // All the following fields must be machine word aligned
   230   // All the following fields must be machine word aligned
   172   // The VM assumes write ordering wrt these fields, which can be
   231   // The VM assumes write ordering wrt these fields, which can be
   173   // read from other threads.
   232   // read from other threads.
   174 
   233 
       
   234  protected:                         // protected for jvmtiRawMonitor
   175   void *  volatile _owner;          // pointer to owning thread OR BasicLock
   235   void *  volatile _owner;          // pointer to owning thread OR BasicLock
   176   volatile intptr_t  _recursions;   // recursion count, 0 for first entry
   236   volatile intptr_t  _recursions;   // recursion count, 0 for first entry
       
   237  private:
   177   int OwnerIsThread ;               // _owner is (Thread *) vs SP/BasicLock
   238   int OwnerIsThread ;               // _owner is (Thread *) vs SP/BasicLock
   178   ObjectWaiter * volatile _cxq ;    // LL of recently-arrived threads blocked on entry.
   239   ObjectWaiter * volatile _cxq ;    // LL of recently-arrived threads blocked on entry.
   179                                     // The list is actually composed of WaitNodes, acting
   240                                     // The list is actually composed of WaitNodes, acting
   180                                     // as proxies for Threads.
   241                                     // as proxies for Threads.
       
   242  protected:
   181   ObjectWaiter * volatile _EntryList ;     // Threads blocked on entry or reentry.
   243   ObjectWaiter * volatile _EntryList ;     // Threads blocked on entry or reentry.
       
   244  private:
   182   Thread * volatile _succ ;          // Heir presumptive thread - used for futile wakeup throttling
   245   Thread * volatile _succ ;          // Heir presumptive thread - used for futile wakeup throttling
   183   Thread * volatile _Responsible ;
   246   Thread * volatile _Responsible ;
   184   int _PromptDrain ;                // rqst to drain cxq into EntryList ASAP
   247   int _PromptDrain ;                // rqst to drain cxq into EntryList ASAP
   185 
   248 
   186   volatile int _Spinner ;           // for exit->spinner handoff optimization
   249   volatile int _Spinner ;           // for exit->spinner handoff optimization
   194   // to use 64-bit fields for these variables on a 64-bit JVM.
   257   // to use 64-bit fields for these variables on a 64-bit JVM.
   195 
   258 
   196   volatile intptr_t  _count;        // reference count to prevent reclaimation/deflation
   259   volatile intptr_t  _count;        // reference count to prevent reclaimation/deflation
   197                                     // at stop-the-world time.  See deflate_idle_monitors().
   260                                     // at stop-the-world time.  See deflate_idle_monitors().
   198                                     // _count is approximately |_WaitSet| + |_EntryList|
   261                                     // _count is approximately |_WaitSet| + |_EntryList|
       
   262  protected:
   199   volatile intptr_t  _waiters;      // number of waiting threads
   263   volatile intptr_t  _waiters;      // number of waiting threads
       
   264  private:
       
   265  protected:
   200   ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
   266   ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
       
   267  private:
   201   volatile int _WaitSetLock;        // protects Wait Queue - simple spinlock
   268   volatile int _WaitSetLock;        // protects Wait Queue - simple spinlock
   202 
   269 
   203  public:
   270  public:
   204   int _QMix ;                       // Mixed prepend queue discipline
   271   int _QMix ;                       // Mixed prepend queue discipline
   205   ObjectMonitor * FreeNext ;        // Free list linkage
   272   ObjectMonitor * FreeNext ;        // Free list linkage
   206   intptr_t StatA, StatsB ;
   273   intptr_t StatA, StatsB ;
   207 
   274 
       
   275  public:
       
   276   static void Initialize () ;
       
   277   static PerfCounter * _sync_ContendedLockAttempts ;
       
   278   static PerfCounter * _sync_FutileWakeups ;
       
   279   static PerfCounter * _sync_Parks ;
       
   280   static PerfCounter * _sync_EmptyNotifications ;
       
   281   static PerfCounter * _sync_Notifications ;
       
   282   static PerfCounter * _sync_SlowEnter ;
       
   283   static PerfCounter * _sync_SlowExit ;
       
   284   static PerfCounter * _sync_SlowNotify ;
       
   285   static PerfCounter * _sync_SlowNotifyAll ;
       
   286   static PerfCounter * _sync_FailedSpins ;
       
   287   static PerfCounter * _sync_SuccessfulSpins ;
       
   288   static PerfCounter * _sync_PrivateA ;
       
   289   static PerfCounter * _sync_PrivateB ;
       
   290   static PerfCounter * _sync_MonInCirculation ;
       
   291   static PerfCounter * _sync_MonScavenged ;
       
   292   static PerfCounter * _sync_Inflations ;
       
   293   static PerfCounter * _sync_Deflations ;
       
   294   static PerfLongVariable * _sync_MonExtant ;
       
   295 
       
   296  public:
       
   297   static int Knob_Verbose;
       
   298   static int Knob_SpinLimit;
   208 };
   299 };
       
   300 
       
   301 #undef TEVENT
       
   302 #define TEVENT(nom) {if (SyncVerbose) FEVENT(nom); }
       
   303 
       
   304 #define FEVENT(nom) { static volatile int ctr = 0 ; int v = ++ctr ; if ((v & (v-1)) == 0) { ::printf (#nom " : %d \n", v); ::fflush(stdout); }}
       
   305 
       
   306 #undef  TEVENT
       
   307 #define TEVENT(nom) {;}
       
   308