duke@435: /* xdono@631: * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: duke@435: // The SplitWord construct allows us to colocate the contention queue duke@435: // (cxq) with the lock-byte. The queue elements are ParkEvents, which are duke@435: // always aligned on 256-byte addresses - the least significant byte of duke@435: // a ParkEvent is always 0. Colocating the lock-byte with the queue duke@435: // allows us to easily avoid what would otherwise be a race in lock() duke@435: // if we were to use two completely separate fields for the contention queue duke@435: // and the lock indicator. Specifically, colocation renders us immune duke@435: // from the race where a thread might enqueue itself in the lock() slow-path duke@435: // immediately after the lock holder drops the outer lock in the unlock() duke@435: // fast-path. duke@435: // duke@435: // Colocation allows us to use a fast-path unlock() form that uses duke@435: // A MEMBAR instead of a CAS. MEMBAR has lower local latency than CAS duke@435: // on many platforms. duke@435: // duke@435: // See: duke@435: // + http://blogs.sun.com/dave/entry/biased_locking_in_hotspot duke@435: // + http://blogs.sun.com/dave/resource/synchronization-public2.pdf duke@435: // duke@435: // Note that we're *not* using word-tearing the classic sense. duke@435: // The lock() fast-path will CAS the lockword and the unlock() duke@435: // fast-path will store into the lock-byte colocated within the lockword. duke@435: // We depend on the fact that all our reference platforms have duke@435: // coherent and atomic byte accesses. More precisely, byte stores duke@435: // interoperate in a safe, sane, and expected manner with respect to duke@435: // CAS, ST and LDs to the full-word containing the byte. duke@435: // If you're porting HotSpot to a platform where that isn't the case duke@435: // then you'll want change the unlock() fast path from: duke@435: // STB;MEMBAR #storeload; LDN duke@435: // to a full-word CAS of the lockword. duke@435: duke@435: duke@435: union SplitWord { // full-word with separately addressable LSB duke@435: volatile intptr_t FullWord ; duke@435: volatile void * Address ; duke@435: volatile jbyte Bytes [sizeof(intptr_t)] ; duke@435: } ; duke@435: duke@435: // Endian-ness ... index of least-significant byte in SplitWord.Bytes[] duke@435: #ifdef AMD64 // little duke@435: #define _LSBINDEX 0 duke@435: #else duke@435: #if IA32 // little duke@435: #define _LSBINDEX 0 duke@435: #else duke@435: #ifdef SPARC // big duke@435: #define _LSBINDEX (sizeof(intptr_t)-1) duke@435: #else duke@435: #error "unknown architecture" duke@435: #endif duke@435: #endif duke@435: #endif duke@435: duke@435: class ParkEvent ; duke@435: duke@435: // See orderAccess.hpp. We assume throughout the VM that mutex lock and duke@435: // try_lock do fence-lock-acquire, and that unlock does a release-unlock, duke@435: // *in that order*. If their implementations change such that these duke@435: // assumptions are violated, a whole lot of code will break. duke@435: xlu@490: // The default length of monitor name is choosen to be 64 to avoid false sharing. xlu@490: static const int MONITOR_NAME_LEN = 64; xlu@490: duke@435: class Monitor : public CHeapObj { duke@435: duke@435: public: duke@435: // A special lock: Is a lock where you are guaranteed not to block while you are duke@435: // holding it, i.e., no vm operation can happen, taking other locks, etc. duke@435: // NOTE: It is critical that the rank 'special' be the lowest (earliest) duke@435: // (except for "event"?) for the deadlock dection to work correctly. duke@435: // The rank native is only for use in Mutex's created by JVM_RawMonitorCreate, duke@435: // which being external to the VM are not subject to deadlock detection. duke@435: // The rank safepoint is used only for synchronization in reaching a duke@435: // safepoint and leaving a safepoint. It is only used for the Safepoint_lock duke@435: // currently. While at a safepoint no mutexes of rank safepoint are held duke@435: // by any thread. duke@435: // The rank named "leaf" is probably historical (and should duke@435: // be changed) -- mutexes of this rank aren't really leaf mutexes duke@435: // at all. duke@435: enum lock_types { duke@435: event, duke@435: special, duke@435: suspend_resume, duke@435: leaf = suspend_resume + 2, duke@435: safepoint = leaf + 10, duke@435: barrier = safepoint + 1, duke@435: nonleaf = barrier + 1, duke@435: max_nonleaf = nonleaf + 900, duke@435: native = max_nonleaf + 1 duke@435: }; duke@435: duke@435: // The WaitSet and EntryList linked lists are composed of ParkEvents. duke@435: // I use ParkEvent instead of threads as ParkEvents are immortal and duke@435: // type-stable, meaning we can safely unpark() a possibly stale duke@435: // list element in the unlock()-path. duke@435: duke@435: protected: // Monitor-Mutex metadata duke@435: SplitWord _LockWord ; // Contention queue (cxq) colocated with Lock-byte duke@435: enum LockWordBits { _LBIT=1 } ; duke@435: Thread * volatile _owner; // The owner of the lock duke@435: // Consider sequestering _owner on its own $line duke@435: // to aid future synchronization mechanisms. duke@435: ParkEvent * volatile _EntryList ; // List of threads waiting for entry duke@435: ParkEvent * volatile _OnDeck ; // heir-presumptive duke@435: volatile intptr_t _WaitLock [1] ; // Protects _WaitSet duke@435: ParkEvent * volatile _WaitSet ; // LL of ParkEvents duke@435: volatile bool _snuck; // Used for sneaky locking (evil). duke@435: int NotifyCount ; // diagnostic assist xlu@490: char _name[MONITOR_NAME_LEN]; // Name of mutex duke@435: duke@435: // Debugging fields for naming, deadlock detection, etc. (some only used in debug mode) duke@435: #ifndef PRODUCT duke@435: bool _allow_vm_block; duke@435: debug_only(int _rank;) // rank (to avoid/detect potential deadlocks) duke@435: debug_only(Monitor * _next;) // Used by a Thread to link up owned locks duke@435: debug_only(Thread* _last_owner;) // the last thread to own the lock duke@435: debug_only(static bool contains(Monitor * locks, Monitor * lock);) duke@435: debug_only(static Monitor * get_least_ranked_lock(Monitor * locks);) duke@435: debug_only(Monitor * get_least_ranked_lock_besides_this(Monitor * locks);) duke@435: #endif duke@435: duke@435: void set_owner_implementation(Thread* owner) PRODUCT_RETURN; duke@435: void check_prelock_state (Thread* thread) PRODUCT_RETURN; duke@435: void check_block_state (Thread* thread) PRODUCT_RETURN; duke@435: duke@435: // platform-dependent support code can go here (in os_.cpp) duke@435: public: duke@435: enum { duke@435: _no_safepoint_check_flag = true, duke@435: _allow_vm_block_flag = true, duke@435: _as_suspend_equivalent_flag = true duke@435: }; duke@435: duke@435: enum WaitResults { duke@435: CONDVAR_EVENT, // Wait returned because of condition variable notification duke@435: INTERRUPT_EVENT, // Wait returned because waiting thread was interrupted duke@435: NUMBER_WAIT_RESULTS duke@435: }; duke@435: duke@435: private: duke@435: int TrySpin (Thread * Self) ; duke@435: int TryLock () ; duke@435: int TryFast () ; duke@435: int AcquireOrPush (ParkEvent * ev) ; duke@435: void IUnlock (bool RelaxAssert) ; duke@435: void ILock (Thread * Self) ; duke@435: int IWait (Thread * Self, jlong timo); duke@435: int ILocked () ; duke@435: duke@435: protected: xlu@490: static void ClearMonitor (Monitor * m, const char* name = NULL) ; duke@435: Monitor() ; duke@435: duke@435: public: duke@435: Monitor(int rank, const char *name, bool allow_vm_block=false); duke@435: ~Monitor(); duke@435: duke@435: // Wait until monitor is notified (or times out). duke@435: // Defaults are to make safepoint checks, wait time is forever (i.e., duke@435: // zero), and not a suspend-equivalent condition. Returns true if wait duke@435: // times out; otherwise returns false. duke@435: bool wait(bool no_safepoint_check = !_no_safepoint_check_flag, duke@435: long timeout = 0, duke@435: bool as_suspend_equivalent = !_as_suspend_equivalent_flag); duke@435: bool notify(); duke@435: bool notify_all(); duke@435: duke@435: duke@435: void lock(); // prints out warning if VM thread blocks duke@435: void lock(Thread *thread); // overloaded with current thread duke@435: void unlock(); duke@435: bool is_locked() const { return _owner != NULL; } duke@435: duke@435: bool try_lock(); // Like lock(), but unblocking. It returns false instead duke@435: duke@435: // Lock without safepoint check. Should ONLY be used by safepoint code and other code duke@435: // that is guaranteed not to block while running inside the VM. duke@435: void lock_without_safepoint_check(); duke@435: void lock_without_safepoint_check (Thread * Self) ; duke@435: duke@435: // Current owner - not not MT-safe. Can only be used to guarantee that duke@435: // the current running thread owns the lock duke@435: Thread* owner() const { return _owner; } duke@435: bool owned_by_self() const; duke@435: duke@435: // Support for JVM_RawMonitorEnter & JVM_RawMonitorExit. These can be called by duke@435: // non-Java thread. (We should really have a RawMonitor abstraction) duke@435: void jvm_raw_lock(); duke@435: void jvm_raw_unlock(); duke@435: const char *name() const { return _name; } duke@435: duke@435: void print_on_error(outputStream* st) const; duke@435: duke@435: #ifndef PRODUCT duke@435: void print_on(outputStream* st) const; duke@435: void print() const { print_on(tty); } duke@435: debug_only(int rank() const { return _rank; }) duke@435: bool allow_vm_block() { return _allow_vm_block; } duke@435: duke@435: debug_only(Monitor *next() const { return _next; }) duke@435: debug_only(void set_next(Monitor *next) { _next = next; }) duke@435: #endif duke@435: duke@435: void set_owner(Thread* owner) { duke@435: #ifndef PRODUCT duke@435: set_owner_implementation(owner); duke@435: debug_only(void verify_Monitor(Thread* thr)); duke@435: #else duke@435: _owner = owner; duke@435: #endif duke@435: } duke@435: duke@435: }; duke@435: duke@435: // Normally we'd expect Monitor to extend Mutex in the sense that a monitor duke@435: // constructed from pthreads primitives might extend a mutex by adding duke@435: // a condvar and some extra metadata. In fact this was the case until J2SE7. duke@435: // duke@435: // Currently, however, the base object is a monitor. Monitor contains all the duke@435: // logic for wait(), notify(), etc. Mutex extends monitor and restricts the duke@435: // visiblity of wait(), notify(), and notify_all(). duke@435: // duke@435: // Another viable alternative would have been to have Monitor extend Mutex and duke@435: // implement all the normal mutex and wait()-notify() logic in Mutex base class. duke@435: // The wait()-notify() facility would be exposed via special protected member functions duke@435: // (e.g., _Wait() and _Notify()) in Mutex. Monitor would extend Mutex and expose wait() duke@435: // as a call to _Wait(). That is, the public wait() would be a wrapper for the protected duke@435: // _Wait(). duke@435: // duke@435: // An even better alternative is to simply eliminate Mutex:: and use Monitor:: instead. duke@435: // After all, monitors are sufficient for Java-level synchronization. At one point in time duke@435: // there may have been some benefit to having distinct mutexes and monitors, but that time duke@435: // has past. duke@435: // duke@435: // The Mutex/Monitor design parallels that of Java-monitors, being based on duke@435: // thread-specific park-unpark platform-specific primitives. duke@435: duke@435: duke@435: class Mutex : public Monitor { // degenerate Monitor duke@435: public: duke@435: Mutex (int rank, const char *name, bool allow_vm_block=false); duke@435: ~Mutex () ; duke@435: private: duke@435: bool notify () { ShouldNotReachHere(); return false; } duke@435: bool notify_all() { ShouldNotReachHere(); return false; } duke@435: bool wait (bool no_safepoint_check, long timeout, bool as_suspend_equivalent) { duke@435: ShouldNotReachHere() ; duke@435: return false ; duke@435: } duke@435: }; duke@435: duke@435: /* duke@435: * Per-thread blocking support for JSR166. See the Java-level duke@435: * Documentation for rationale. Basically, park acts like wait, unpark duke@435: * like notify. duke@435: * duke@435: * 6271289 -- duke@435: * To avoid errors where an os thread expires but the JavaThread still duke@435: * exists, Parkers are immortal (type-stable) and are recycled across duke@435: * new threads. This parallels the ParkEvent implementation. duke@435: * Because park-unpark allow spurious wakeups it is harmless if an duke@435: * unpark call unparks a new thread using the old Parker reference. duke@435: * duke@435: * In the future we'll want to think about eliminating Parker and using duke@435: * ParkEvent instead. There's considerable duplication between the two duke@435: * services. duke@435: * duke@435: */ duke@435: duke@435: class Parker : public os::PlatformParker { duke@435: private: duke@435: volatile int _counter ; duke@435: Parker * FreeNext ; duke@435: JavaThread * AssociatedWith ; // Current association duke@435: duke@435: public: duke@435: Parker() : PlatformParker() { duke@435: _counter = 0 ; duke@435: FreeNext = NULL ; duke@435: AssociatedWith = NULL ; duke@435: } duke@435: protected: duke@435: ~Parker() { ShouldNotReachHere(); } duke@435: public: duke@435: // For simplicity of interface with Java, all forms of park (indefinite, duke@435: // relative, and absolute) are multiplexed into one call. duke@435: void park(bool isAbsolute, jlong time); duke@435: void unpark(); duke@435: duke@435: // Lifecycle operators duke@435: static Parker * Allocate (JavaThread * t) ; duke@435: static void Release (Parker * e) ; duke@435: private: duke@435: static Parker * volatile FreeList ; duke@435: static volatile int ListLock ; duke@435: };