comparison src/share/vm/runtime/objectMonitor.hpp @ 1878:fa83ab460c54

6988353: refactor contended sync subsystem Summary: reduce complexity by factoring synchronizer.cpp Reviewed-by: dholmes, never, coleenp
author acorn
date Fri, 22 Oct 2010 15:59:34 -0400
parents c18cbe5936b8
children f95d63e2154a
comparison
equal deleted inserted replaced
1874:75ab0162aa84 1878:fa83ab460c54
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