src/share/vm/runtime/mutex.hpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/runtime/mutex.hpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,276 @@
     1.4 +/*
     1.5 + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 + * or visit www.oracle.com if you need additional information or have any
    1.24 + * questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +#ifndef SHARE_VM_RUNTIME_MUTEX_HPP
    1.29 +#define SHARE_VM_RUNTIME_MUTEX_HPP
    1.30 +
    1.31 +#include "memory/allocation.hpp"
    1.32 +#include "runtime/os.hpp"
    1.33 +#include "utilities/histogram.hpp"
    1.34 +
    1.35 +// The SplitWord construct allows us to colocate the contention queue
    1.36 +// (cxq) with the lock-byte.  The queue elements are ParkEvents, which are
    1.37 +// always aligned on 256-byte addresses - the least significant byte of
    1.38 +// a ParkEvent is always 0.  Colocating the lock-byte with the queue
    1.39 +// allows us to easily avoid what would otherwise be a race in lock()
    1.40 +// if we were to use two completely separate fields for the contention queue
    1.41 +// and the lock indicator.  Specifically, colocation renders us immune
    1.42 +// from the race where a thread might enqueue itself in the lock() slow-path
    1.43 +// immediately after the lock holder drops the outer lock in the unlock()
    1.44 +// fast-path.
    1.45 +//
    1.46 +// Colocation allows us to use a fast-path unlock() form that uses
    1.47 +// A MEMBAR instead of a CAS.  MEMBAR has lower local latency than CAS
    1.48 +// on many platforms.
    1.49 +//
    1.50 +// See:
    1.51 +// +  http://blogs.sun.com/dave/entry/biased_locking_in_hotspot
    1.52 +// +  http://blogs.sun.com/dave/resource/synchronization-public2.pdf
    1.53 +//
    1.54 +// Note that we're *not* using word-tearing the classic sense.
    1.55 +// The lock() fast-path will CAS the lockword and the unlock()
    1.56 +// fast-path will store into the lock-byte colocated within the lockword.
    1.57 +// We depend on the fact that all our reference platforms have
    1.58 +// coherent and atomic byte accesses.  More precisely, byte stores
    1.59 +// interoperate in a safe, sane, and expected manner with respect to
    1.60 +// CAS, ST and LDs to the full-word containing the byte.
    1.61 +// If you're porting HotSpot to a platform where that isn't the case
    1.62 +// then you'll want change the unlock() fast path from:
    1.63 +//    STB;MEMBAR #storeload; LDN
    1.64 +// to a full-word CAS of the lockword.
    1.65 +
    1.66 +
    1.67 +union SplitWord {   // full-word with separately addressable LSB
    1.68 +  volatile intptr_t FullWord ;
    1.69 +  volatile void * Address ;
    1.70 +  volatile jbyte Bytes [sizeof(intptr_t)] ;
    1.71 +} ;
    1.72 +
    1.73 +// Endian-ness ... index of least-significant byte in SplitWord.Bytes[]
    1.74 +#ifdef VM_LITTLE_ENDIAN
    1.75 + #define _LSBINDEX 0
    1.76 +#else
    1.77 + #define _LSBINDEX (sizeof(intptr_t)-1)
    1.78 +#endif
    1.79 +
    1.80 +class ParkEvent ;
    1.81 +
    1.82 +// See orderAccess.hpp.  We assume throughout the VM that mutex lock and
    1.83 +// try_lock do fence-lock-acquire, and that unlock does a release-unlock,
    1.84 +// *in that order*.  If their implementations change such that these
    1.85 +// assumptions are violated, a whole lot of code will break.
    1.86 +
    1.87 +// The default length of monitor name is chosen to be 64 to avoid false sharing.
    1.88 +static const int MONITOR_NAME_LEN = 64;
    1.89 +
    1.90 +class Monitor : public CHeapObj<mtInternal> {
    1.91 +
    1.92 + public:
    1.93 +  // A special lock: Is a lock where you are guaranteed not to block while you are
    1.94 +  // holding it, i.e., no vm operation can happen, taking other locks, etc.
    1.95 +  // NOTE: It is critical that the rank 'special' be the lowest (earliest)
    1.96 +  // (except for "event"?) for the deadlock dection to work correctly.
    1.97 +  // The rank native is only for use in Mutex's created by JVM_RawMonitorCreate,
    1.98 +  // which being external to the VM are not subject to deadlock detection.
    1.99 +  // The rank safepoint is used only for synchronization in reaching a
   1.100 +  // safepoint and leaving a safepoint.  It is only used for the Safepoint_lock
   1.101 +  // currently.  While at a safepoint no mutexes of rank safepoint are held
   1.102 +  // by any thread.
   1.103 +  // The rank named "leaf" is probably historical (and should
   1.104 +  // be changed) -- mutexes of this rank aren't really leaf mutexes
   1.105 +  // at all.
   1.106 +  enum lock_types {
   1.107 +       event,
   1.108 +       special,
   1.109 +       suspend_resume,
   1.110 +       leaf        = suspend_resume +   2,
   1.111 +       safepoint   = leaf           +  10,
   1.112 +       barrier     = safepoint      +   1,
   1.113 +       nonleaf     = barrier        +   1,
   1.114 +       max_nonleaf = nonleaf        + 900,
   1.115 +       native      = max_nonleaf    +   1
   1.116 +  };
   1.117 +
   1.118 +  // The WaitSet and EntryList linked lists are composed of ParkEvents.
   1.119 +  // I use ParkEvent instead of threads as ParkEvents are immortal and
   1.120 +  // type-stable, meaning we can safely unpark() a possibly stale
   1.121 +  // list element in the unlock()-path.
   1.122 +
   1.123 + protected:                              // Monitor-Mutex metadata
   1.124 +  SplitWord _LockWord ;                  // Contention queue (cxq) colocated with Lock-byte
   1.125 +  enum LockWordBits { _LBIT=1 } ;
   1.126 +  Thread * volatile _owner;              // The owner of the lock
   1.127 +                                         // Consider sequestering _owner on its own $line
   1.128 +                                         // to aid future synchronization mechanisms.
   1.129 +  ParkEvent * volatile _EntryList ;      // List of threads waiting for entry
   1.130 +  ParkEvent * volatile _OnDeck ;         // heir-presumptive
   1.131 +  volatile intptr_t _WaitLock [1] ;      // Protects _WaitSet
   1.132 +  ParkEvent * volatile  _WaitSet ;       // LL of ParkEvents
   1.133 +  volatile bool     _snuck;              // Used for sneaky locking (evil).
   1.134 +  int NotifyCount ;                      // diagnostic assist
   1.135 +  char _name[MONITOR_NAME_LEN];          // Name of mutex
   1.136 +
   1.137 +  // Debugging fields for naming, deadlock detection, etc. (some only used in debug mode)
   1.138 +#ifndef PRODUCT
   1.139 +  bool      _allow_vm_block;
   1.140 +  debug_only(int _rank;)                 // rank (to avoid/detect potential deadlocks)
   1.141 +  debug_only(Monitor * _next;)           // Used by a Thread to link up owned locks
   1.142 +  debug_only(Thread* _last_owner;)       // the last thread to own the lock
   1.143 +  debug_only(static bool contains(Monitor * locks, Monitor * lock);)
   1.144 +  debug_only(static Monitor * get_least_ranked_lock(Monitor * locks);)
   1.145 +  debug_only(Monitor * get_least_ranked_lock_besides_this(Monitor * locks);)
   1.146 +#endif
   1.147 +
   1.148 +  void set_owner_implementation(Thread* owner)                        PRODUCT_RETURN;
   1.149 +  void check_prelock_state     (Thread* thread)                       PRODUCT_RETURN;
   1.150 +  void check_block_state       (Thread* thread)                       PRODUCT_RETURN;
   1.151 +
   1.152 +  // platform-dependent support code can go here (in os_<os_family>.cpp)
   1.153 + public:
   1.154 +  enum {
   1.155 +    _no_safepoint_check_flag    = true,
   1.156 +    _allow_vm_block_flag        = true,
   1.157 +    _as_suspend_equivalent_flag = true
   1.158 +  };
   1.159 +
   1.160 +  enum WaitResults {
   1.161 +    CONDVAR_EVENT,         // Wait returned because of condition variable notification
   1.162 +    INTERRUPT_EVENT,       // Wait returned because waiting thread was interrupted
   1.163 +    NUMBER_WAIT_RESULTS
   1.164 +  };
   1.165 +
   1.166 + private:
   1.167 +   int  TrySpin (Thread * Self) ;
   1.168 +   int  TryLock () ;
   1.169 +   int  TryFast () ;
   1.170 +   int  AcquireOrPush (ParkEvent * ev) ;
   1.171 +   void IUnlock (bool RelaxAssert) ;
   1.172 +   void ILock (Thread * Self) ;
   1.173 +   int  IWait (Thread * Self, jlong timo);
   1.174 +   int  ILocked () ;
   1.175 +
   1.176 + protected:
   1.177 +   static void ClearMonitor (Monitor * m, const char* name = NULL) ;
   1.178 +   Monitor() ;
   1.179 +
   1.180 + public:
   1.181 +  Monitor(int rank, const char *name, bool allow_vm_block=false);
   1.182 +  ~Monitor();
   1.183 +
   1.184 +  // Wait until monitor is notified (or times out).
   1.185 +  // Defaults are to make safepoint checks, wait time is forever (i.e.,
   1.186 +  // zero), and not a suspend-equivalent condition. Returns true if wait
   1.187 +  // times out; otherwise returns false.
   1.188 +  bool wait(bool no_safepoint_check = !_no_safepoint_check_flag,
   1.189 +            long timeout = 0,
   1.190 +            bool as_suspend_equivalent = !_as_suspend_equivalent_flag);
   1.191 +  bool notify();
   1.192 +  bool notify_all();
   1.193 +
   1.194 +
   1.195 +  void lock(); // prints out warning if VM thread blocks
   1.196 +  void lock(Thread *thread); // overloaded with current thread
   1.197 +  void unlock();
   1.198 +  bool is_locked() const                     { return _owner != NULL; }
   1.199 +
   1.200 +  bool try_lock(); // Like lock(), but unblocking. It returns false instead
   1.201 +
   1.202 +  // Lock without safepoint check. Should ONLY be used by safepoint code and other code
   1.203 +  // that is guaranteed not to block while running inside the VM.
   1.204 +  void lock_without_safepoint_check();
   1.205 +  void lock_without_safepoint_check (Thread * Self) ;
   1.206 +
   1.207 +  // Current owner - not not MT-safe. Can only be used to guarantee that
   1.208 +  // the current running thread owns the lock
   1.209 +  Thread* owner() const         { return _owner; }
   1.210 +  bool owned_by_self() const;
   1.211 +
   1.212 +  // Support for JVM_RawMonitorEnter & JVM_RawMonitorExit. These can be called by
   1.213 +  // non-Java thread. (We should really have a RawMonitor abstraction)
   1.214 +  void jvm_raw_lock();
   1.215 +  void jvm_raw_unlock();
   1.216 +  const char *name() const                  { return _name; }
   1.217 +
   1.218 +  void print_on_error(outputStream* st) const;
   1.219 +
   1.220 +  #ifndef PRODUCT
   1.221 +    void print_on(outputStream* st) const;
   1.222 +    void print() const                      { print_on(tty); }
   1.223 +    debug_only(int    rank() const          { return _rank; })
   1.224 +    bool   allow_vm_block()                 { return _allow_vm_block; }
   1.225 +
   1.226 +    debug_only(Monitor *next()  const         { return _next; })
   1.227 +    debug_only(void   set_next(Monitor *next) { _next = next; })
   1.228 +  #endif
   1.229 +
   1.230 +  void set_owner(Thread* owner) {
   1.231 +  #ifndef PRODUCT
   1.232 +    set_owner_implementation(owner);
   1.233 +    debug_only(void verify_Monitor(Thread* thr));
   1.234 +  #else
   1.235 +    _owner = owner;
   1.236 +  #endif
   1.237 +  }
   1.238 +
   1.239 +};
   1.240 +
   1.241 +// Normally we'd expect Monitor to extend Mutex in the sense that a monitor
   1.242 +// constructed from pthreads primitives might extend a mutex by adding
   1.243 +// a condvar and some extra metadata.  In fact this was the case until J2SE7.
   1.244 +//
   1.245 +// Currently, however, the base object is a monitor.  Monitor contains all the
   1.246 +// logic for wait(), notify(), etc.   Mutex extends monitor and restricts the
   1.247 +// visiblity of wait(), notify(), and notify_all().
   1.248 +//
   1.249 +// Another viable alternative would have been to have Monitor extend Mutex and
   1.250 +// implement all the normal mutex and wait()-notify() logic in Mutex base class.
   1.251 +// The wait()-notify() facility would be exposed via special protected member functions
   1.252 +// (e.g., _Wait() and _Notify()) in Mutex.  Monitor would extend Mutex and expose wait()
   1.253 +// as a call to _Wait().  That is, the public wait() would be a wrapper for the protected
   1.254 +// _Wait().
   1.255 +//
   1.256 +// An even better alternative is to simply eliminate Mutex:: and use Monitor:: instead.
   1.257 +// After all, monitors are sufficient for Java-level synchronization.   At one point in time
   1.258 +// there may have been some benefit to having distinct mutexes and monitors, but that time
   1.259 +// has past.
   1.260 +//
   1.261 +// The Mutex/Monitor design parallels that of Java-monitors, being based on
   1.262 +// thread-specific park-unpark platform-specific primitives.
   1.263 +
   1.264 +
   1.265 +class Mutex : public Monitor {      // degenerate Monitor
   1.266 + public:
   1.267 +   Mutex (int rank, const char *name, bool allow_vm_block=false);
   1.268 +   ~Mutex () ;
   1.269 + private:
   1.270 +   bool notify ()    { ShouldNotReachHere(); return false; }
   1.271 +   bool notify_all() { ShouldNotReachHere(); return false; }
   1.272 +   bool wait (bool no_safepoint_check, long timeout, bool as_suspend_equivalent) {
   1.273 +     ShouldNotReachHere() ;
   1.274 +     return false ;
   1.275 +   }
   1.276 +};
   1.277 +
   1.278 +
   1.279 +#endif // SHARE_VM_RUNTIME_MUTEX_HPP

mercurial