1.1 --- a/src/share/vm/runtime/objectMonitor.hpp Mon Oct 18 09:33:24 2010 -0700 1.2 +++ b/src/share/vm/runtime/objectMonitor.hpp Fri Oct 22 15:59:34 2010 -0400 1.3 @@ -22,6 +22,32 @@ 1.4 * 1.5 */ 1.6 1.7 + 1.8 +// ObjectWaiter serves as a "proxy" or surrogate thread. 1.9 +// TODO-FIXME: Eliminate ObjectWaiter and use the thread-specific 1.10 +// ParkEvent instead. Beware, however, that the JVMTI code 1.11 +// knows about ObjectWaiters, so we'll have to reconcile that code. 1.12 +// See next_waiter(), first_waiter(), etc. 1.13 + 1.14 +class ObjectWaiter : public StackObj { 1.15 + public: 1.16 + enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ } ; 1.17 + enum Sorted { PREPEND, APPEND, SORTED } ; 1.18 + ObjectWaiter * volatile _next; 1.19 + ObjectWaiter * volatile _prev; 1.20 + Thread* _thread; 1.21 + ParkEvent * _event; 1.22 + volatile int _notified ; 1.23 + volatile TStates TState ; 1.24 + Sorted _Sorted ; // List placement disposition 1.25 + bool _active ; // Contention monitoring is enabled 1.26 + public: 1.27 + ObjectWaiter(Thread* thread); 1.28 + 1.29 + void wait_reenter_begin(ObjectMonitor *mon); 1.30 + void wait_reenter_end(ObjectMonitor *mon); 1.31 +}; 1.32 + 1.33 // WARNING: 1.34 // This is a very sensitive and fragile class. DO NOT make any 1.35 // change unless you are fully aware of the underlying semantics. 1.36 @@ -38,8 +64,6 @@ 1.37 // It is also used as RawMonitor by the JVMTI 1.38 1.39 1.40 -class ObjectWaiter; 1.41 - 1.42 class ObjectMonitor { 1.43 public: 1.44 enum { 1.45 @@ -74,13 +98,16 @@ 1.46 1.47 1.48 public: 1.49 - ObjectMonitor(); 1.50 - ~ObjectMonitor(); 1.51 - 1.52 markOop header() const; 1.53 void set_header(markOop hdr); 1.54 1.55 - intptr_t is_busy() const; 1.56 + intptr_t is_busy() const { 1.57 + // TODO-FIXME: merge _count and _waiters. 1.58 + // TODO-FIXME: assert _owner == null implies _recursions = 0 1.59 + // TODO-FIXME: assert _WaitSet != null implies _count > 0 1.60 + return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList ) ; 1.61 + } 1.62 + 1.63 intptr_t is_entered(Thread* current) const; 1.64 1.65 void* owner() const; 1.66 @@ -91,13 +118,58 @@ 1.67 intptr_t count() const; 1.68 void set_count(intptr_t count); 1.69 intptr_t contentions() const ; 1.70 + intptr_t recursions() const { return _recursions; } 1.71 1.72 // JVM/DI GetMonitorInfo() needs this 1.73 - Thread * thread_of_waiter (ObjectWaiter *) ; 1.74 - ObjectWaiter * first_waiter () ; 1.75 - ObjectWaiter * next_waiter(ObjectWaiter* o); 1.76 + ObjectWaiter* first_waiter() { return _WaitSet; } 1.77 + ObjectWaiter* next_waiter(ObjectWaiter* o) { return o->_next; } 1.78 + Thread* thread_of_waiter(ObjectWaiter* o) { return o->_thread; } 1.79 1.80 - intptr_t recursions() const { return _recursions; } 1.81 + // initialize the monitor, exception the semaphore, all other fields 1.82 + // are simple integers or pointers 1.83 + ObjectMonitor() { 1.84 + _header = NULL; 1.85 + _count = 0; 1.86 + _waiters = 0, 1.87 + _recursions = 0; 1.88 + _object = NULL; 1.89 + _owner = NULL; 1.90 + _WaitSet = NULL; 1.91 + _WaitSetLock = 0 ; 1.92 + _Responsible = NULL ; 1.93 + _succ = NULL ; 1.94 + _cxq = NULL ; 1.95 + FreeNext = NULL ; 1.96 + _EntryList = NULL ; 1.97 + _SpinFreq = 0 ; 1.98 + _SpinClock = 0 ; 1.99 + OwnerIsThread = 0 ; 1.100 + } 1.101 + 1.102 + ~ObjectMonitor() { 1.103 + // TODO: Add asserts ... 1.104 + // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0 1.105 + // _count == 0 _EntryList == NULL etc 1.106 + } 1.107 + 1.108 +private: 1.109 + void Recycle () { 1.110 + // TODO: add stronger asserts ... 1.111 + // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0 1.112 + // _count == 0 EntryList == NULL 1.113 + // _recursions == 0 _WaitSet == NULL 1.114 + // TODO: assert (is_busy()|_recursions) == 0 1.115 + _succ = NULL ; 1.116 + _EntryList = NULL ; 1.117 + _cxq = NULL ; 1.118 + _WaitSet = NULL ; 1.119 + _recursions = 0 ; 1.120 + _SpinFreq = 0 ; 1.121 + _SpinClock = 0 ; 1.122 + OwnerIsThread = 0 ; 1.123 + } 1.124 + 1.125 +public: 1.126 1.127 void* object() const; 1.128 void* object_addr(); 1.129 @@ -122,22 +194,9 @@ 1.130 intptr_t complete_exit(TRAPS); 1.131 void reenter(intptr_t recursions, TRAPS); 1.132 1.133 - int raw_enter(TRAPS); 1.134 - int raw_exit(TRAPS); 1.135 - int raw_wait(jlong millis, bool interruptable, TRAPS); 1.136 - int raw_notify(TRAPS); 1.137 - int raw_notifyAll(TRAPS); 1.138 - 1.139 private: 1.140 - // JVMTI support -- remove ASAP 1.141 - int SimpleEnter (Thread * Self) ; 1.142 - int SimpleExit (Thread * Self) ; 1.143 - int SimpleWait (Thread * Self, jlong millis) ; 1.144 - int SimpleNotify (Thread * Self, bool All) ; 1.145 - 1.146 - private: 1.147 - void Recycle () ; 1.148 void AddWaiter (ObjectWaiter * waiter) ; 1.149 + static void DeferredInitialize(); 1.150 1.151 ObjectWaiter * DequeueWaiter () ; 1.152 void DequeueSpecificWaiter (ObjectWaiter * waiter) ; 1.153 @@ -172,13 +231,17 @@ 1.154 // The VM assumes write ordering wrt these fields, which can be 1.155 // read from other threads. 1.156 1.157 + protected: // protected for jvmtiRawMonitor 1.158 void * volatile _owner; // pointer to owning thread OR BasicLock 1.159 volatile intptr_t _recursions; // recursion count, 0 for first entry 1.160 + private: 1.161 int OwnerIsThread ; // _owner is (Thread *) vs SP/BasicLock 1.162 ObjectWaiter * volatile _cxq ; // LL of recently-arrived threads blocked on entry. 1.163 // The list is actually composed of WaitNodes, acting 1.164 // as proxies for Threads. 1.165 + protected: 1.166 ObjectWaiter * volatile _EntryList ; // Threads blocked on entry or reentry. 1.167 + private: 1.168 Thread * volatile _succ ; // Heir presumptive thread - used for futile wakeup throttling 1.169 Thread * volatile _Responsible ; 1.170 int _PromptDrain ; // rqst to drain cxq into EntryList ASAP 1.171 @@ -196,8 +259,12 @@ 1.172 volatile intptr_t _count; // reference count to prevent reclaimation/deflation 1.173 // at stop-the-world time. See deflate_idle_monitors(). 1.174 // _count is approximately |_WaitSet| + |_EntryList| 1.175 + protected: 1.176 volatile intptr_t _waiters; // number of waiting threads 1.177 + private: 1.178 + protected: 1.179 ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor 1.180 + private: 1.181 volatile int _WaitSetLock; // protects Wait Queue - simple spinlock 1.182 1.183 public: 1.184 @@ -205,4 +272,37 @@ 1.185 ObjectMonitor * FreeNext ; // Free list linkage 1.186 intptr_t StatA, StatsB ; 1.187 1.188 + public: 1.189 + static void Initialize () ; 1.190 + static PerfCounter * _sync_ContendedLockAttempts ; 1.191 + static PerfCounter * _sync_FutileWakeups ; 1.192 + static PerfCounter * _sync_Parks ; 1.193 + static PerfCounter * _sync_EmptyNotifications ; 1.194 + static PerfCounter * _sync_Notifications ; 1.195 + static PerfCounter * _sync_SlowEnter ; 1.196 + static PerfCounter * _sync_SlowExit ; 1.197 + static PerfCounter * _sync_SlowNotify ; 1.198 + static PerfCounter * _sync_SlowNotifyAll ; 1.199 + static PerfCounter * _sync_FailedSpins ; 1.200 + static PerfCounter * _sync_SuccessfulSpins ; 1.201 + static PerfCounter * _sync_PrivateA ; 1.202 + static PerfCounter * _sync_PrivateB ; 1.203 + static PerfCounter * _sync_MonInCirculation ; 1.204 + static PerfCounter * _sync_MonScavenged ; 1.205 + static PerfCounter * _sync_Inflations ; 1.206 + static PerfCounter * _sync_Deflations ; 1.207 + static PerfLongVariable * _sync_MonExtant ; 1.208 + 1.209 + public: 1.210 + static int Knob_Verbose; 1.211 + static int Knob_SpinLimit; 1.212 }; 1.213 + 1.214 +#undef TEVENT 1.215 +#define TEVENT(nom) {if (SyncVerbose) FEVENT(nom); } 1.216 + 1.217 +#define FEVENT(nom) { static volatile int ctr = 0 ; int v = ++ctr ; if ((v & (v-1)) == 0) { ::printf (#nom " : %d \n", v); ::fflush(stdout); }} 1.218 + 1.219 +#undef TEVENT 1.220 +#define TEVENT(nom) {;} 1.221 +