82 OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException 83 OM_INTERRUPTED, // Thread.interrupt() 84 OM_TIMED_OUT // Object.wait() timed out 85 }; 86 87 public: 88 // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ... 89 // ByteSize would also be an appropriate type. 90 static int header_offset_in_bytes() { return offset_of(ObjectMonitor, _header); } 91 static int object_offset_in_bytes() { return offset_of(ObjectMonitor, _object); } 92 static int owner_offset_in_bytes() { return offset_of(ObjectMonitor, _owner); } 93 static int count_offset_in_bytes() { return offset_of(ObjectMonitor, _count); } 94 static int recursions_offset_in_bytes() { return offset_of(ObjectMonitor, _recursions); } 95 static int cxq_offset_in_bytes() { return offset_of(ObjectMonitor, _cxq) ; } 96 static int succ_offset_in_bytes() { return offset_of(ObjectMonitor, _succ) ; } 97 static int EntryList_offset_in_bytes() { return offset_of(ObjectMonitor, _EntryList); } 98 static int FreeNext_offset_in_bytes() { return offset_of(ObjectMonitor, FreeNext); } 99 static int WaitSet_offset_in_bytes() { return offset_of(ObjectMonitor, _WaitSet) ; } 100 static int Responsible_offset_in_bytes() { return offset_of(ObjectMonitor, _Responsible);} 101 static int Spinner_offset_in_bytes() { return offset_of(ObjectMonitor, _Spinner); } 102 103 public: 104 // Eventaully we'll make provisions for multiple callbacks, but 105 // now one will suffice. 106 static int (*SpinCallbackFunction)(intptr_t, int) ; 107 static intptr_t SpinCallbackArgument ; 108 109 110 public: 111 markOop header() const; 112 void set_header(markOop hdr); 113 114 intptr_t is_busy() const { 115 // TODO-FIXME: merge _count and _waiters. 116 // TODO-FIXME: assert _owner == null implies _recursions = 0 117 // TODO-FIXME: assert _WaitSet != null implies _count > 0 118 return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList ) ; 119 } 120 121 intptr_t is_entered(Thread* current) const; 122 123 void* owner() const; 124 void set_owner(void* owner); 125 126 intptr_t waiters() const; 127 128 intptr_t count() const; 129 void set_count(intptr_t count); 130 intptr_t contentions() const ; 131 intptr_t recursions() const { return _recursions; } 132 133 // JVM/DI GetMonitorInfo() needs this 134 ObjectWaiter* first_waiter() { return _WaitSet; } 135 ObjectWaiter* next_waiter(ObjectWaiter* o) { return o->_next; } 136 Thread* thread_of_waiter(ObjectWaiter* o) { return o->_thread; } 137 138 // initialize the monitor, exception the semaphore, all other fields 139 // are simple integers or pointers 140 ObjectMonitor() { 141 _header = NULL; 142 _count = 0; 143 _waiters = 0, 144 _recursions = 0; 145 _object = NULL; 146 _owner = NULL; 147 _WaitSet = NULL; 148 _WaitSetLock = 0 ; 149 _Responsible = NULL ; 150 _succ = NULL ; 151 _cxq = NULL ; 152 FreeNext = NULL ; 153 _EntryList = NULL ; 154 _SpinFreq = 0 ; 155 _SpinClock = 0 ; 156 OwnerIsThread = 0 ; 157 _previous_owner_tid = 0; 158 } 159 160 ~ObjectMonitor() { 161 // TODO: Add asserts ... 162 // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0 163 // _count == 0 _EntryList == NULL etc 164 } 165 166 private: 167 void Recycle () { 168 // TODO: add stronger asserts ... 169 // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0 170 // _count == 0 EntryList == NULL 171 // _recursions == 0 _WaitSet == NULL 172 // TODO: assert (is_busy()|_recursions) == 0 173 _succ = NULL ; 174 _EntryList = NULL ; 175 _cxq = NULL ; 176 _WaitSet = NULL ; 177 _recursions = 0 ; 178 _SpinFreq = 0 ; 179 _SpinClock = 0 ; 180 OwnerIsThread = 0 ; 181 } 182 183 public: 184 185 void* object() const; 186 void* object_addr(); 187 void set_object(void* obj); 188 189 bool check(TRAPS); // true if the thread owns the monitor. 190 void check_slow(TRAPS); 191 void clear(); 192 #ifndef PRODUCT 193 void verify(); 194 void print(); 195 #endif 196 197 bool try_enter (TRAPS) ; 198 void enter(TRAPS); 199 void exit(bool not_suspended, TRAPS); 200 void wait(jlong millis, bool interruptable, TRAPS); 201 void notify(TRAPS); 202 void notifyAll(TRAPS); 203 204 // Use the following at your own risk 205 intptr_t complete_exit(TRAPS); 206 void reenter(intptr_t recursions, TRAPS); 207 208 private: 209 void AddWaiter (ObjectWaiter * waiter) ; 210 static void DeferredInitialize(); 211 212 ObjectWaiter * DequeueWaiter () ; 213 void DequeueSpecificWaiter (ObjectWaiter * waiter) ; 214 void EnterI (TRAPS) ; 215 void ReenterI (Thread * Self, ObjectWaiter * SelfNode) ; 216 void UnlinkAfterAcquire (Thread * Self, ObjectWaiter * SelfNode) ; 217 int TryLock (Thread * Self) ; 218 int NotRunnable (Thread * Self, Thread * Owner) ; 219 int TrySpin_Fixed (Thread * Self) ; 220 int TrySpin_VaryFrequency (Thread * Self) ; 221 int TrySpin_VaryDuration (Thread * Self) ; 222 void ctAsserts () ; 223 void ExitEpilog (Thread * Self, ObjectWaiter * Wakee) ; 224 bool ExitSuspendEquivalent (JavaThread * Self) ; 225 void post_monitor_wait_event(EventJavaMonitorWait * event, 226 jlong notifier_tid, 227 jlong timeout, 228 bool timedout); 229 230 private: 231 friend class ObjectSynchronizer; 232 friend class ObjectWaiter; 233 friend class VMStructs; 234 258 protected: 259 ObjectWaiter * volatile _EntryList ; // Threads blocked on entry or reentry. 260 private: 261 Thread * volatile _succ ; // Heir presumptive thread - used for futile wakeup throttling 262 Thread * volatile _Responsible ; 263 int _PromptDrain ; // rqst to drain cxq into EntryList ASAP 264 265 volatile int _Spinner ; // for exit->spinner handoff optimization 266 volatile int _SpinFreq ; // Spin 1-out-of-N attempts: success rate 267 volatile int _SpinClock ; 268 volatile int _SpinDuration ; 269 volatile intptr_t _SpinState ; // MCS/CLH list of spinners 270 271 // TODO-FIXME: _count, _waiters and _recursions should be of 272 // type int, or int32_t but not intptr_t. There's no reason 273 // to use 64-bit fields for these variables on a 64-bit JVM. 274 275 volatile intptr_t _count; // reference count to prevent reclaimation/deflation 276 // at stop-the-world time. See deflate_idle_monitors(). 277 // _count is approximately |_WaitSet| + |_EntryList| 278 protected: 279 volatile intptr_t _waiters; // number of waiting threads 280 private: 281 protected: 282 ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor 283 private: 284 volatile int _WaitSetLock; // protects Wait Queue - simple spinlock 285 286 public: 287 int _QMix ; // Mixed prepend queue discipline 288 ObjectMonitor * FreeNext ; // Free list linkage 289 intptr_t StatA, StatsB ; 290 291 public: 292 static void Initialize () ; 293 static PerfCounter * _sync_ContendedLockAttempts ; 294 static PerfCounter * _sync_FutileWakeups ; 295 static PerfCounter * _sync_Parks ; 296 static PerfCounter * _sync_EmptyNotifications ; 297 static PerfCounter * _sync_Notifications ; | 82 OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException 83 OM_INTERRUPTED, // Thread.interrupt() 84 OM_TIMED_OUT // Object.wait() timed out 85 }; 86 87 public: 88 // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ... 89 // ByteSize would also be an appropriate type. 90 static int header_offset_in_bytes() { return offset_of(ObjectMonitor, _header); } 91 static int object_offset_in_bytes() { return offset_of(ObjectMonitor, _object); } 92 static int owner_offset_in_bytes() { return offset_of(ObjectMonitor, _owner); } 93 static int count_offset_in_bytes() { return offset_of(ObjectMonitor, _count); } 94 static int recursions_offset_in_bytes() { return offset_of(ObjectMonitor, _recursions); } 95 static int cxq_offset_in_bytes() { return offset_of(ObjectMonitor, _cxq) ; } 96 static int succ_offset_in_bytes() { return offset_of(ObjectMonitor, _succ) ; } 97 static int EntryList_offset_in_bytes() { return offset_of(ObjectMonitor, _EntryList); } 98 static int FreeNext_offset_in_bytes() { return offset_of(ObjectMonitor, FreeNext); } 99 static int WaitSet_offset_in_bytes() { return offset_of(ObjectMonitor, _WaitSet) ; } 100 static int Responsible_offset_in_bytes() { return offset_of(ObjectMonitor, _Responsible);} 101 static int Spinner_offset_in_bytes() { return offset_of(ObjectMonitor, _Spinner); } 102 static int trace_exit_stack_offset_in_bytes() { return offset_of(ObjectMonitor, _trace_exit_stack); } 103 104 public: 105 // Eventaully we'll make provisions for multiple callbacks, but 106 // now one will suffice. 107 static int (*SpinCallbackFunction)(intptr_t, int) ; 108 static intptr_t SpinCallbackArgument ; 109 110 111 public: 112 markOop header() const; 113 void set_header(markOop hdr); 114 115 intptr_t is_busy() const { 116 // TODO-FIXME: merge _count and _waiters. 117 // TODO-FIXME: assert _owner == null implies _recursions = 0 118 // TODO-FIXME: assert _WaitSet != null implies _count > 0 119 return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList ) ; 120 } 121 122 intptr_t is_entered(Thread* current) const; 123 124 void* owner() const; 125 void set_owner(void* owner); 126 127 intptr_t waiters() const; 128 129 intptr_t count() const; 130 void set_count(intptr_t count); 131 intptr_t contentions() const ; 132 intptr_t recursions() const { return _recursions; } 133 134 intptr_t next_trace_seq() { return Atomic::add_ptr(1, &_trace_current_seq); } 135 136 // JVM/DI GetMonitorInfo() needs this 137 ObjectWaiter* first_waiter() { return _WaitSet; } 138 ObjectWaiter* next_waiter(ObjectWaiter* o) { return o->_next; } 139 Thread* thread_of_waiter(ObjectWaiter* o) { return o->_thread; } 140 141 // initialize the monitor, exception the semaphore, all other fields 142 // are simple integers or pointers 143 ObjectMonitor() { 144 _header = NULL; 145 _count = 0; 146 _waiters = 0, 147 _recursions = 0; 148 _object = NULL; 149 _owner = NULL; 150 _WaitSet = NULL; 151 _WaitSetLock = 0 ; 152 _Responsible = NULL ; 153 _succ = NULL ; 154 _cxq = NULL ; 155 FreeNext = NULL ; 156 _EntryList = NULL ; 157 _SpinFreq = 0 ; 158 _SpinClock = 0 ; 159 OwnerIsThread = 0 ; 160 _previous_owner_tid = 0; 161 _trace_current_seq = 0; 162 _trace_exit_stack = 0; 163 } 164 165 ~ObjectMonitor() { 166 // TODO: Add asserts ... 167 // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0 168 // _count == 0 _EntryList == NULL etc 169 } 170 171 private: 172 void Recycle () { 173 // TODO: add stronger asserts ... 174 // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0 175 // _count == 0 EntryList == NULL 176 // _recursions == 0 _WaitSet == NULL 177 // TODO: assert (is_busy()|_recursions) == 0 178 _succ = NULL ; 179 _EntryList = NULL ; 180 _cxq = NULL ; 181 _WaitSet = NULL ; 182 _recursions = 0 ; 183 _SpinFreq = 0 ; 184 _SpinClock = 0 ; 185 OwnerIsThread = 0 ; 186 // tracing: do not reset _trace_current_seq, we also use it 187 // to detect pending events before a monitor is recycled 188 } 189 190 public: 191 192 void* object() const; 193 void* object_addr(); 194 void set_object(void* obj); 195 196 bool check(TRAPS); // true if the thread owns the monitor. 197 void check_slow(TRAPS); 198 void clear(); 199 #ifndef PRODUCT 200 void verify(); 201 void print(); 202 #endif 203 204 bool try_enter (TRAPS) ; 205 void enter(TRAPS); 206 void exit(bool not_suspended, TRAPS); 207 void wait(jlong millis, bool interruptable, TRAPS); 208 void notify(TRAPS); 209 void notifyAll(TRAPS); 210 211 // Use the following at your own risk 212 void complete_exit(intptr_t *saved_recursions, intptr_t *saved_trace_exit_stack, TRAPS); 213 void reenter(intptr_t saved_recursions, intptr_t saved_trace_exit_stack, TRAPS); 214 215 private: 216 void AddWaiter (ObjectWaiter * waiter) ; 217 static void DeferredInitialize(); 218 219 ObjectWaiter * DequeueWaiter () ; 220 void DequeueSpecificWaiter (ObjectWaiter * waiter) ; 221 void enter (int after_wait, TRAPS); 222 void exit(intptr_t *exit_stack_id_for_wait, bool not_suspended, TRAPS); 223 int EnterI (TRAPS) ; 224 void ReenterI (Thread * Self, ObjectWaiter * SelfNode) ; 225 void UnlinkAfterAcquire (Thread * Self, ObjectWaiter * SelfNode) ; 226 int TryLock (Thread * Self) ; 227 int NotRunnable (Thread * Self, Thread * Owner) ; 228 int TrySpin_Fixed (Thread * Self) ; 229 int TrySpin_VaryFrequency (Thread * Self) ; 230 int TrySpin_VaryDuration (Thread * Self) ; 231 void ctAsserts () ; 232 void ExitEpilog (Thread * Self, ObjectWaiter * Wakee) ; 233 bool ExitSuspendEquivalent (JavaThread * Self) ; 234 void post_monitor_wait_event(EventJavaMonitorWait * event, 235 jlong notifier_tid, 236 jlong timeout, 237 bool timedout); 238 239 private: 240 friend class ObjectSynchronizer; 241 friend class ObjectWaiter; 242 friend class VMStructs; 243 267 protected: 268 ObjectWaiter * volatile _EntryList ; // Threads blocked on entry or reentry. 269 private: 270 Thread * volatile _succ ; // Heir presumptive thread - used for futile wakeup throttling 271 Thread * volatile _Responsible ; 272 int _PromptDrain ; // rqst to drain cxq into EntryList ASAP 273 274 volatile int _Spinner ; // for exit->spinner handoff optimization 275 volatile int _SpinFreq ; // Spin 1-out-of-N attempts: success rate 276 volatile int _SpinClock ; 277 volatile int _SpinDuration ; 278 volatile intptr_t _SpinState ; // MCS/CLH list of spinners 279 280 // TODO-FIXME: _count, _waiters and _recursions should be of 281 // type int, or int32_t but not intptr_t. There's no reason 282 // to use 64-bit fields for these variables on a 64-bit JVM. 283 284 volatile intptr_t _count; // reference count to prevent reclaimation/deflation 285 // at stop-the-world time. See deflate_idle_monitors(). 286 // _count is approximately |_WaitSet| + |_EntryList| 287 288 // TODO: this class appears to be sensitive to false sharing. 289 // there might be a better location to place this field. 290 volatile intptr_t _trace_current_seq; 291 volatile intptr_t _trace_exit_stack; 292 protected: 293 volatile intptr_t _waiters; // number of waiting threads 294 private: 295 protected: 296 ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor 297 private: 298 volatile int _WaitSetLock; // protects Wait Queue - simple spinlock 299 300 public: 301 int _QMix ; // Mixed prepend queue discipline 302 ObjectMonitor * FreeNext ; // Free list linkage 303 intptr_t StatA, StatsB ; 304 305 public: 306 static void Initialize () ; 307 static PerfCounter * _sync_ContendedLockAttempts ; 308 static PerfCounter * _sync_FutileWakeups ; 309 static PerfCounter * _sync_Parks ; 310 static PerfCounter * _sync_EmptyNotifications ; 311 static PerfCounter * _sync_Notifications ; |