objectMonitor.hpp revision 4668:f9be75d21404
1/*
2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
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
21 * questions.
22 *
23 */
24
25#ifndef SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
26#define SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
27
28#include "runtime/os.hpp"
29#include "runtime/park.hpp"
30#include "runtime/perfData.hpp"
31
32
33// ObjectWaiter serves as a "proxy" or surrogate thread.
34// TODO-FIXME: Eliminate ObjectWaiter and use the thread-specific
35// ParkEvent instead.  Beware, however, that the JVMTI code
36// knows about ObjectWaiters, so we'll have to reconcile that code.
37// See next_waiter(), first_waiter(), etc.
38
39class ObjectWaiter : public StackObj {
40 public:
41  enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ } ;
42  enum Sorted  { PREPEND, APPEND, SORTED } ;
43  ObjectWaiter * volatile _next;
44  ObjectWaiter * volatile _prev;
45  Thread*       _thread;
46  ParkEvent *   _event;
47  volatile int  _notified ;
48  volatile TStates TState ;
49  Sorted        _Sorted ;           // List placement disposition
50  bool          _active ;           // Contention monitoring is enabled
51 public:
52  ObjectWaiter(Thread* thread);
53
54  void wait_reenter_begin(ObjectMonitor *mon);
55  void wait_reenter_end(ObjectMonitor *mon);
56};
57
58// WARNING:
59//   This is a very sensitive and fragile class. DO NOT make any
60// change unless you are fully aware of the underlying semantics.
61
62//   This class can not inherit from any other class, because I have
63// to let the displaced header be the very first word. Otherwise I
64// have to let markOop include this file, which would export the
65// monitor data structure to everywhere.
66//
67// The ObjectMonitor class is used to implement JavaMonitors which have
68// transformed from the lightweight structure of the thread stack to a
69// heavy weight lock due to contention
70
71// It is also used as RawMonitor by the JVMTI
72
73
74class ObjectMonitor {
75 public:
76  enum {
77    OM_OK,                    // no error
78    OM_SYSTEM_ERROR,          // operating system error
79    OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
80    OM_INTERRUPTED,           // Thread.interrupt()
81    OM_TIMED_OUT              // Object.wait() timed out
82  };
83
84 public:
85  // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ...
86  // ByteSize would also be an appropriate type.
87  static int header_offset_in_bytes()      { return offset_of(ObjectMonitor, _header);     }
88  static int object_offset_in_bytes()      { return offset_of(ObjectMonitor, _object);     }
89  static int owner_offset_in_bytes()       { return offset_of(ObjectMonitor, _owner);      }
90  static int count_offset_in_bytes()       { return offset_of(ObjectMonitor, _count);      }
91  static int recursions_offset_in_bytes()  { return offset_of(ObjectMonitor, _recursions); }
92  static int cxq_offset_in_bytes()         { return offset_of(ObjectMonitor, _cxq) ;       }
93  static int succ_offset_in_bytes()        { return offset_of(ObjectMonitor, _succ) ;      }
94  static int EntryList_offset_in_bytes()   { return offset_of(ObjectMonitor, _EntryList);  }
95  static int FreeNext_offset_in_bytes()    { return offset_of(ObjectMonitor, FreeNext);    }
96  static int WaitSet_offset_in_bytes()     { return offset_of(ObjectMonitor, _WaitSet) ;   }
97  static int Responsible_offset_in_bytes() { return offset_of(ObjectMonitor, _Responsible);}
98  static int Spinner_offset_in_bytes()     { return offset_of(ObjectMonitor, _Spinner);    }
99
100 public:
101  // Eventaully we'll make provisions for multiple callbacks, but
102  // now one will suffice.
103  static int (*SpinCallbackFunction)(intptr_t, int) ;
104  static intptr_t SpinCallbackArgument ;
105
106
107 public:
108  markOop   header() const;
109  void      set_header(markOop hdr);
110
111  intptr_t is_busy() const {
112    // TODO-FIXME: merge _count and _waiters.
113    // TODO-FIXME: assert _owner == null implies _recursions = 0
114    // TODO-FIXME: assert _WaitSet != null implies _count > 0
115    return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList ) ;
116  }
117
118  intptr_t  is_entered(Thread* current) const;
119
120  void*     owner() const;
121  void      set_owner(void* owner);
122
123  intptr_t  waiters() const;
124
125  intptr_t  count() const;
126  void      set_count(intptr_t count);
127  intptr_t  contentions() const ;
128  intptr_t  recursions() const                                         { return _recursions; }
129
130  // JVM/DI GetMonitorInfo() needs this
131  ObjectWaiter* first_waiter()                                         { return _WaitSet; }
132  ObjectWaiter* next_waiter(ObjectWaiter* o)                           { return o->_next; }
133  Thread* thread_of_waiter(ObjectWaiter* o)                            { return o->_thread; }
134
135  // initialize the monitor, exception the semaphore, all other fields
136  // are simple integers or pointers
137  ObjectMonitor() {
138    _header       = NULL;
139    _count        = 0;
140    _waiters      = 0,
141    _recursions   = 0;
142    _object       = NULL;
143    _owner        = NULL;
144    _WaitSet      = NULL;
145    _WaitSetLock  = 0 ;
146    _Responsible  = NULL ;
147    _succ         = NULL ;
148    _cxq          = NULL ;
149    FreeNext      = NULL ;
150    _EntryList    = NULL ;
151    _SpinFreq     = 0 ;
152    _SpinClock    = 0 ;
153    OwnerIsThread = 0 ;
154  }
155
156  ~ObjectMonitor() {
157   // TODO: Add asserts ...
158   // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
159   // _count == 0 _EntryList  == NULL etc
160  }
161
162private:
163  void Recycle () {
164    // TODO: add stronger asserts ...
165    // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
166    // _count == 0 EntryList  == NULL
167    // _recursions == 0 _WaitSet == NULL
168    // TODO: assert (is_busy()|_recursions) == 0
169    _succ          = NULL ;
170    _EntryList     = NULL ;
171    _cxq           = NULL ;
172    _WaitSet       = NULL ;
173    _recursions    = 0 ;
174    _SpinFreq      = 0 ;
175    _SpinClock     = 0 ;
176    OwnerIsThread  = 0 ;
177  }
178
179public:
180
181  void*     object() const;
182  void*     object_addr();
183  void      set_object(void* obj);
184
185  bool      check(TRAPS);       // true if the thread owns the monitor.
186  void      check_slow(TRAPS);
187  void      clear();
188#ifndef PRODUCT
189  void      verify();
190  void      print();
191#endif
192
193  bool      try_enter (TRAPS) ;
194  void      enter(TRAPS);
195  void      exit(TRAPS);
196  void      wait(jlong millis, bool interruptable, TRAPS);
197  void      notify(TRAPS);
198  void      notifyAll(TRAPS);
199
200// Use the following at your own risk
201  intptr_t  complete_exit(TRAPS);
202  void      reenter(intptr_t recursions, TRAPS);
203
204 private:
205  void      AddWaiter (ObjectWaiter * waiter) ;
206  static    void DeferredInitialize();
207
208  ObjectWaiter * DequeueWaiter () ;
209  void      DequeueSpecificWaiter (ObjectWaiter * waiter) ;
210  void      EnterI (TRAPS) ;
211  void      ReenterI (Thread * Self, ObjectWaiter * SelfNode) ;
212  void      UnlinkAfterAcquire (Thread * Self, ObjectWaiter * SelfNode) ;
213  int       TryLock (Thread * Self) ;
214  int       NotRunnable (Thread * Self, Thread * Owner) ;
215  int       TrySpin_Fixed (Thread * Self) ;
216  int       TrySpin_VaryFrequency (Thread * Self) ;
217  int       TrySpin_VaryDuration  (Thread * Self) ;
218  void      ctAsserts () ;
219  void      ExitEpilog (Thread * Self, ObjectWaiter * Wakee) ;
220  bool      ExitSuspendEquivalent (JavaThread * Self) ;
221
222 private:
223  friend class ObjectSynchronizer;
224  friend class ObjectWaiter;
225  friend class VMStructs;
226
227  // WARNING: this must be the very first word of ObjectMonitor
228  // This means this class can't use any virtual member functions.
229  // TODO-FIXME: assert that offsetof(_header) is 0 or get rid of the
230  // implicit 0 offset in emitted code.
231
232  volatile markOop   _header;       // displaced object header word - mark
233  void*     volatile _object;       // backward object pointer - strong root
234
235  double SharingPad [1] ;           // temp to reduce false sharing
236
237  // All the following fields must be machine word aligned
238  // The VM assumes write ordering wrt these fields, which can be
239  // read from other threads.
240
241 protected:                         // protected for jvmtiRawMonitor
242  void *  volatile _owner;          // pointer to owning thread OR BasicLock
243  volatile intptr_t  _recursions;   // recursion count, 0 for first entry
244 private:
245  int OwnerIsThread ;               // _owner is (Thread *) vs SP/BasicLock
246  ObjectWaiter * volatile _cxq ;    // LL of recently-arrived threads blocked on entry.
247                                    // The list is actually composed of WaitNodes, acting
248                                    // as proxies for Threads.
249 protected:
250  ObjectWaiter * volatile _EntryList ;     // Threads blocked on entry or reentry.
251 private:
252  Thread * volatile _succ ;          // Heir presumptive thread - used for futile wakeup throttling
253  Thread * volatile _Responsible ;
254  int _PromptDrain ;                // rqst to drain cxq into EntryList ASAP
255
256  volatile int _Spinner ;           // for exit->spinner handoff optimization
257  volatile int _SpinFreq ;          // Spin 1-out-of-N attempts: success rate
258  volatile int _SpinClock ;
259  volatile int _SpinDuration ;
260  volatile intptr_t _SpinState ;    // MCS/CLH list of spinners
261
262  // TODO-FIXME: _count, _waiters and _recursions should be of
263  // type int, or int32_t but not intptr_t.  There's no reason
264  // to use 64-bit fields for these variables on a 64-bit JVM.
265
266  volatile intptr_t  _count;        // reference count to prevent reclaimation/deflation
267                                    // at stop-the-world time.  See deflate_idle_monitors().
268                                    // _count is approximately |_WaitSet| + |_EntryList|
269 protected:
270  volatile intptr_t  _waiters;      // number of waiting threads
271 private:
272 protected:
273  ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
274 private:
275  volatile int _WaitSetLock;        // protects Wait Queue - simple spinlock
276
277 public:
278  int _QMix ;                       // Mixed prepend queue discipline
279  ObjectMonitor * FreeNext ;        // Free list linkage
280  intptr_t StatA, StatsB ;
281
282 public:
283  static void Initialize () ;
284  static PerfCounter * _sync_ContendedLockAttempts ;
285  static PerfCounter * _sync_FutileWakeups ;
286  static PerfCounter * _sync_Parks ;
287  static PerfCounter * _sync_EmptyNotifications ;
288  static PerfCounter * _sync_Notifications ;
289  static PerfCounter * _sync_SlowEnter ;
290  static PerfCounter * _sync_SlowExit ;
291  static PerfCounter * _sync_SlowNotify ;
292  static PerfCounter * _sync_SlowNotifyAll ;
293  static PerfCounter * _sync_FailedSpins ;
294  static PerfCounter * _sync_SuccessfulSpins ;
295  static PerfCounter * _sync_PrivateA ;
296  static PerfCounter * _sync_PrivateB ;
297  static PerfCounter * _sync_MonInCirculation ;
298  static PerfCounter * _sync_MonScavenged ;
299  static PerfCounter * _sync_Inflations ;
300  static PerfCounter * _sync_Deflations ;
301  static PerfLongVariable * _sync_MonExtant ;
302
303 public:
304  static int Knob_Verbose;
305  static int Knob_SpinLimit;
306  void* operator new (size_t size) {
307    return AllocateHeap(size, mtInternal);
308  }
309  void* operator new[] (size_t size) {
310    return operator new (size);
311  }
312  void operator delete(void* p) {
313    FreeHeap(p, mtInternal);
314  }
315  void operator delete[] (void *p) {
316    operator delete(p);
317  }
318};
319
320#undef TEVENT
321#define TEVENT(nom) {if (SyncVerbose) FEVENT(nom); }
322
323#define FEVENT(nom) { static volatile int ctr = 0 ; int v = ++ctr ; if ((v & (v-1)) == 0) { ::printf (#nom " : %d \n", v); ::fflush(stdout); }}
324
325#undef  TEVENT
326#define TEVENT(nom) {;}
327
328
329#endif // SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
330