hotspot/src/share/vm/runtime/objectMonitor.hpp
changeset 6975 dc9b63952682
parent 5547 f4b087cbb361
child 7397 5b173b4ca846
--- a/hotspot/src/share/vm/runtime/objectMonitor.hpp	Mon Oct 18 09:33:24 2010 -0700
+++ b/hotspot/src/share/vm/runtime/objectMonitor.hpp	Fri Oct 22 15:59:34 2010 -0400
@@ -22,6 +22,32 @@
  *
  */
 
+
+// ObjectWaiter serves as a "proxy" or surrogate thread.
+// TODO-FIXME: Eliminate ObjectWaiter and use the thread-specific
+// ParkEvent instead.  Beware, however, that the JVMTI code
+// knows about ObjectWaiters, so we'll have to reconcile that code.
+// See next_waiter(), first_waiter(), etc.
+
+class ObjectWaiter : public StackObj {
+ public:
+  enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ } ;
+  enum Sorted  { PREPEND, APPEND, SORTED } ;
+  ObjectWaiter * volatile _next;
+  ObjectWaiter * volatile _prev;
+  Thread*       _thread;
+  ParkEvent *   _event;
+  volatile int  _notified ;
+  volatile TStates TState ;
+  Sorted        _Sorted ;           // List placement disposition
+  bool          _active ;           // Contention monitoring is enabled
+ public:
+  ObjectWaiter(Thread* thread);
+
+  void wait_reenter_begin(ObjectMonitor *mon);
+  void wait_reenter_end(ObjectMonitor *mon);
+};
+
 // WARNING:
 //   This is a very sensitive and fragile class. DO NOT make any
 // change unless you are fully aware of the underlying semantics.
@@ -38,8 +64,6 @@
 // It is also used as RawMonitor by the JVMTI
 
 
-class ObjectWaiter;
-
 class ObjectMonitor {
  public:
   enum {
@@ -74,13 +98,16 @@
 
 
  public:
-  ObjectMonitor();
-  ~ObjectMonitor();
-
   markOop   header() const;
   void      set_header(markOop hdr);
 
-  intptr_t  is_busy() const;
+  intptr_t is_busy() const {
+    // TODO-FIXME: merge _count and _waiters.
+    // TODO-FIXME: assert _owner == null implies _recursions = 0
+    // TODO-FIXME: assert _WaitSet != null implies _count > 0
+    return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList ) ;
+  }
+
   intptr_t  is_entered(Thread* current) const;
 
   void*     owner() const;
@@ -91,13 +118,58 @@
   intptr_t  count() const;
   void      set_count(intptr_t count);
   intptr_t  contentions() const ;
+  intptr_t  recursions() const                                         { return _recursions; }
 
   // JVM/DI GetMonitorInfo() needs this
-  Thread *  thread_of_waiter (ObjectWaiter *) ;
-  ObjectWaiter * first_waiter () ;
-  ObjectWaiter * next_waiter(ObjectWaiter* o);
+  ObjectWaiter* first_waiter()                                         { return _WaitSet; }
+  ObjectWaiter* next_waiter(ObjectWaiter* o)                           { return o->_next; }
+  Thread* thread_of_waiter(ObjectWaiter* o)                            { return o->_thread; }
+
+  // initialize the monitor, exception the semaphore, all other fields
+  // are simple integers or pointers
+  ObjectMonitor() {
+    _header       = NULL;
+    _count        = 0;
+    _waiters      = 0,
+    _recursions   = 0;
+    _object       = NULL;
+    _owner        = NULL;
+    _WaitSet      = NULL;
+    _WaitSetLock  = 0 ;
+    _Responsible  = NULL ;
+    _succ         = NULL ;
+    _cxq          = NULL ;
+    FreeNext      = NULL ;
+    _EntryList    = NULL ;
+    _SpinFreq     = 0 ;
+    _SpinClock    = 0 ;
+    OwnerIsThread = 0 ;
+  }
 
-  intptr_t  recursions() const { return _recursions; }
+  ~ObjectMonitor() {
+   // TODO: Add asserts ...
+   // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
+   // _count == 0 _EntryList  == NULL etc
+  }
+
+private:
+  void Recycle () {
+    // TODO: add stronger asserts ...
+    // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
+    // _count == 0 EntryList  == NULL
+    // _recursions == 0 _WaitSet == NULL
+    // TODO: assert (is_busy()|_recursions) == 0
+    _succ          = NULL ;
+    _EntryList     = NULL ;
+    _cxq           = NULL ;
+    _WaitSet       = NULL ;
+    _recursions    = 0 ;
+    _SpinFreq      = 0 ;
+    _SpinClock     = 0 ;
+    OwnerIsThread  = 0 ;
+  }
+
+public:
 
   void*     object() const;
   void*     object_addr();
@@ -122,22 +194,9 @@
   intptr_t  complete_exit(TRAPS);
   void      reenter(intptr_t recursions, TRAPS);
 
-  int       raw_enter(TRAPS);
-  int       raw_exit(TRAPS);
-  int       raw_wait(jlong millis, bool interruptable, TRAPS);
-  int       raw_notify(TRAPS);
-  int       raw_notifyAll(TRAPS);
-
  private:
-  // JVMTI support -- remove ASAP
-  int       SimpleEnter (Thread * Self) ;
-  int       SimpleExit  (Thread * Self) ;
-  int       SimpleWait  (Thread * Self, jlong millis) ;
-  int       SimpleNotify (Thread * Self, bool All) ;
-
- private:
-  void      Recycle () ;
   void      AddWaiter (ObjectWaiter * waiter) ;
+  static    void DeferredInitialize();
 
   ObjectWaiter * DequeueWaiter () ;
   void      DequeueSpecificWaiter (ObjectWaiter * waiter) ;
@@ -172,13 +231,17 @@
   // The VM assumes write ordering wrt these fields, which can be
   // read from other threads.
 
+ protected:                         // protected for jvmtiRawMonitor
   void *  volatile _owner;          // pointer to owning thread OR BasicLock
   volatile intptr_t  _recursions;   // recursion count, 0 for first entry
+ private:
   int OwnerIsThread ;               // _owner is (Thread *) vs SP/BasicLock
   ObjectWaiter * volatile _cxq ;    // LL of recently-arrived threads blocked on entry.
                                     // The list is actually composed of WaitNodes, acting
                                     // as proxies for Threads.
+ protected:
   ObjectWaiter * volatile _EntryList ;     // Threads blocked on entry or reentry.
+ private:
   Thread * volatile _succ ;          // Heir presumptive thread - used for futile wakeup throttling
   Thread * volatile _Responsible ;
   int _PromptDrain ;                // rqst to drain cxq into EntryList ASAP
@@ -196,8 +259,12 @@
   volatile intptr_t  _count;        // reference count to prevent reclaimation/deflation
                                     // at stop-the-world time.  See deflate_idle_monitors().
                                     // _count is approximately |_WaitSet| + |_EntryList|
+ protected:
   volatile intptr_t  _waiters;      // number of waiting threads
+ private:
+ protected:
   ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
+ private:
   volatile int _WaitSetLock;        // protects Wait Queue - simple spinlock
 
  public:
@@ -205,4 +272,37 @@
   ObjectMonitor * FreeNext ;        // Free list linkage
   intptr_t StatA, StatsB ;
 
+ public:
+  static void Initialize () ;
+  static PerfCounter * _sync_ContendedLockAttempts ;
+  static PerfCounter * _sync_FutileWakeups ;
+  static PerfCounter * _sync_Parks ;
+  static PerfCounter * _sync_EmptyNotifications ;
+  static PerfCounter * _sync_Notifications ;
+  static PerfCounter * _sync_SlowEnter ;
+  static PerfCounter * _sync_SlowExit ;
+  static PerfCounter * _sync_SlowNotify ;
+  static PerfCounter * _sync_SlowNotifyAll ;
+  static PerfCounter * _sync_FailedSpins ;
+  static PerfCounter * _sync_SuccessfulSpins ;
+  static PerfCounter * _sync_PrivateA ;
+  static PerfCounter * _sync_PrivateB ;
+  static PerfCounter * _sync_MonInCirculation ;
+  static PerfCounter * _sync_MonScavenged ;
+  static PerfCounter * _sync_Inflations ;
+  static PerfCounter * _sync_Deflations ;
+  static PerfLongVariable * _sync_MonExtant ;
+
+ public:
+  static int Knob_Verbose;
+  static int Knob_SpinLimit;
 };
+
+#undef TEVENT
+#define TEVENT(nom) {if (SyncVerbose) FEVENT(nom); }
+
+#define FEVENT(nom) { static volatile int ctr = 0 ; int v = ++ctr ; if ((v & (v-1)) == 0) { ::printf (#nom " : %d \n", v); ::fflush(stdout); }}
+
+#undef  TEVENT
+#define TEVENT(nom) {;}
+