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