< prev index next >

src/hotspot/share/runtime/mutex.hpp

Print this page

        

*** 35,45 **** // The default length of monitor name was originally chosen to be 64 to avoid // false sharing. Now, PaddedMonitor is available for this purpose. // TODO: Check if _name[MONITOR_NAME_LEN] should better get replaced by const char*. static const int MONITOR_NAME_LEN = 64; ! class Monitor : public CHeapObj<mtSynchronizer> { public: // A special lock: Is a lock where you are guaranteed not to block while you are // holding it, i.e., no vm operation can happen, taking other (blocking) locks, etc. // The rank 'access' is similar to 'special' and has the same restrictions on usage. --- 35,45 ---- // The default length of monitor name was originally chosen to be 64 to avoid // false sharing. Now, PaddedMonitor is available for this purpose. // TODO: Check if _name[MONITOR_NAME_LEN] should better get replaced by const char*. static const int MONITOR_NAME_LEN = 64; ! class Mutex : public CHeapObj<mtSynchronizer> { public: // A special lock: Is a lock where you are guaranteed not to block while you are // holding it, i.e., no vm operation can happen, taking other (blocking) locks, etc. // The rank 'access' is similar to 'special' and has the same restrictions on usage.
*** 82,104 **** // Debugging fields for naming, deadlock detection, etc. (some only used in debug mode) #ifndef PRODUCT bool _allow_vm_block; DEBUG_ONLY(int _rank;) // rank (to avoid/detect potential deadlocks) ! DEBUG_ONLY(Monitor * _next;) // Used by a Thread to link up owned locks DEBUG_ONLY(Thread* _last_owner;) // the last thread to own the lock ! DEBUG_ONLY(static bool contains(Monitor * locks, Monitor * lock);) ! DEBUG_ONLY(static Monitor * get_least_ranked_lock(Monitor * locks);) ! DEBUG_ONLY(Monitor * get_least_ranked_lock_besides_this(Monitor * locks);) #endif void set_owner_implementation(Thread* owner) PRODUCT_RETURN; void check_prelock_state (Thread* thread, bool safepoint_check) PRODUCT_RETURN; void check_block_state (Thread* thread) PRODUCT_RETURN; void check_safepoint_state (Thread* thread, bool safepoint_check) NOT_DEBUG_RETURN; void assert_owner (Thread* expected) NOT_DEBUG_RETURN; - void assert_wait_lock_state (Thread* self) NOT_DEBUG_RETURN; public: enum { _allow_vm_block_flag = true, _as_suspend_equivalent_flag = true --- 82,103 ---- // Debugging fields for naming, deadlock detection, etc. (some only used in debug mode) #ifndef PRODUCT bool _allow_vm_block; DEBUG_ONLY(int _rank;) // rank (to avoid/detect potential deadlocks) ! DEBUG_ONLY(Mutex* _next;) // Used by a Thread to link up owned locks DEBUG_ONLY(Thread* _last_owner;) // the last thread to own the lock ! DEBUG_ONLY(static bool contains(Mutex* locks, Mutex* lock);) ! DEBUG_ONLY(static Mutex* get_least_ranked_lock(Mutex* locks);) ! DEBUG_ONLY(Mutex* get_least_ranked_lock_besides_this(Mutex* locks);) #endif void set_owner_implementation(Thread* owner) PRODUCT_RETURN; void check_prelock_state (Thread* thread, bool safepoint_check) PRODUCT_RETURN; void check_block_state (Thread* thread) PRODUCT_RETURN; void check_safepoint_state (Thread* thread, bool safepoint_check) NOT_DEBUG_RETURN; void assert_owner (Thread* expected) NOT_DEBUG_RETURN; public: enum { _allow_vm_block_flag = true, _as_suspend_equivalent_flag = true
*** 128,163 **** _safepoint_check_flag, _no_safepoint_check_flag }; enum SafepointCheckRequired { ! _safepoint_check_never, // Monitors with this value will cause errors // when acquired by a JavaThread with a safepoint check. _safepoint_check_sometimes, // A couple of special locks are acquired by JavaThreads sometimes // with and sometimes without safepoint checks. These // locks will not produce errors when locked. ! _safepoint_check_always // Monitors with this value will cause errors // when acquired by a JavaThread without a safepoint check. }; NOT_PRODUCT(SafepointCheckRequired _safepoint_check_required;) public: ! Monitor(int rank, const char *name, bool allow_vm_block = false, SafepointCheckRequired safepoint_check_required = _safepoint_check_always); ! ~Monitor(); ! ! // Wait until monitor is notified (or times out). ! // Defaults are to make safepoint checks, wait time is forever (i.e., ! // zero), and not a suspend-equivalent condition. Returns true if wait ! // times out; otherwise returns false. ! bool wait(long timeout = 0, ! bool as_suspend_equivalent = !_as_suspend_equivalent_flag); ! bool wait_without_safepoint_check(long timeout = 0); ! void notify(); ! void notify_all(); ! void lock(); // prints out warning if VM thread blocks void lock(Thread *thread); // overloaded with current thread void unlock(); bool is_locked() const { return _owner != NULL; } --- 127,151 ---- _safepoint_check_flag, _no_safepoint_check_flag }; enum SafepointCheckRequired { ! _safepoint_check_never, // Mutexes with this value will cause errors // when acquired by a JavaThread with a safepoint check. _safepoint_check_sometimes, // A couple of special locks are acquired by JavaThreads sometimes // with and sometimes without safepoint checks. These // locks will not produce errors when locked. ! _safepoint_check_always // Mutexes with this value will cause errors // when acquired by a JavaThread without a safepoint check. }; NOT_PRODUCT(SafepointCheckRequired _safepoint_check_required;) public: ! Mutex(int rank, const char *name, bool allow_vm_block = false, SafepointCheckRequired safepoint_check_required = _safepoint_check_always); ! ~Mutex(); void lock(); // prints out warning if VM thread blocks void lock(Thread *thread); // overloaded with current thread void unlock(); bool is_locked() const { return _owner != NULL; }
*** 184,253 **** void print_on(outputStream* st) const; void print() const { print_on(::tty); } DEBUG_ONLY(int rank() const { return _rank; }) bool allow_vm_block() { return _allow_vm_block; } ! DEBUG_ONLY(Monitor *next() const { return _next; }) ! DEBUG_ONLY(void set_next(Monitor *next) { _next = next; }) #endif void set_owner(Thread* owner) { #ifndef PRODUCT set_owner_implementation(owner); ! DEBUG_ONLY(void verify_Monitor(Thread* thr);) #else _owner = owner; #endif } }; - class PaddedMonitor : public Monitor { - enum { - CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Monitor), - PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1 - }; - char _padding[PADDING_LEN]; - public: - PaddedMonitor(int rank, const char *name, bool allow_vm_block = false, - SafepointCheckRequired safepoint_check_required = _safepoint_check_always) : - Monitor(rank, name, allow_vm_block, safepoint_check_required) {}; - }; ! // Normally we'd expect Monitor to extend Mutex in the sense that a monitor ! // constructed from pthreads primitives might extend a mutex by adding ! // a condvar and some extra metadata. In fact this was the case until J2SE7. ! // ! // Currently, however, the base object is a monitor. Monitor contains all the ! // logic for wait(), notify(), etc. Mutex extends monitor and restricts the ! // visibility of wait(), notify(), and notify_all(). ! // ! // Another viable alternative would have been to have Monitor extend Mutex and ! // implement all the normal mutex and wait()-notify() logic in Mutex base class. ! // The wait()-notify() facility would be exposed via special protected member functions ! // (e.g., _Wait() and _Notify()) in Mutex. Monitor would extend Mutex and expose wait() ! // as a call to _Wait(). That is, the public wait() would be a wrapper for the protected ! // _Wait(). ! // ! // An even better alternative is to simply eliminate Mutex:: and use Monitor:: instead. ! // After all, monitors are sufficient for Java-level synchronization. At one point in time ! // there may have been some benefit to having distinct mutexes and monitors, but that time ! // has passed. ! // ! class Mutex : public Monitor { // degenerate Monitor public: ! Mutex(int rank, const char *name, bool allow_vm_block = false, SafepointCheckRequired safepoint_check_required = _safepoint_check_always); // default destructor ! private: void notify(); void notify_all(); - bool wait(long timeout, bool as_suspend_equivalent); - bool wait_without_safepoint_check(long timeout); }; class PaddedMutex : public Mutex { enum { CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Mutex), PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1 }; --- 172,218 ---- void print_on(outputStream* st) const; void print() const { print_on(::tty); } DEBUG_ONLY(int rank() const { return _rank; }) bool allow_vm_block() { return _allow_vm_block; } ! DEBUG_ONLY(Mutex *next() const { return _next; }) ! DEBUG_ONLY(void set_next(Mutex *next) { _next = next; }) #endif void set_owner(Thread* owner) { #ifndef PRODUCT set_owner_implementation(owner); ! DEBUG_ONLY(void verify_mutex(Thread* thr);) #else _owner = owner; #endif } }; ! // PlatformMonitor extends PlatformMutex so this makes sense. ! class Monitor : public Mutex { ! void assert_wait_lock_state (Thread* self) NOT_DEBUG_RETURN; public: ! Monitor(int rank, const char *name, bool allow_vm_block = false, SafepointCheckRequired safepoint_check_required = _safepoint_check_always); // default destructor ! ! // Wait until monitor is notified (or times out). ! // Defaults are to make safepoint checks, wait time is forever (i.e., ! // zero), and not a suspend-equivalent condition. Returns true if wait ! // times out; otherwise returns false. ! bool wait(long timeout = 0, ! bool as_suspend_equivalent = !_as_suspend_equivalent_flag); ! bool wait_without_safepoint_check(long timeout = 0); void notify(); void notify_all(); }; + class PaddedMutex : public Mutex { enum { CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Mutex), PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1 };
*** 256,261 **** --- 221,238 ---- PaddedMutex(int rank, const char *name, bool allow_vm_block = false, SafepointCheckRequired safepoint_check_required = _safepoint_check_always) : Mutex(rank, name, allow_vm_block, safepoint_check_required) {}; }; + class PaddedMonitor : public Monitor { + enum { + CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Monitor), + PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1 + }; + char _padding[PADDING_LEN]; + public: + PaddedMonitor(int rank, const char *name, bool allow_vm_block = false, + SafepointCheckRequired safepoint_check_required = _safepoint_check_always) : + Monitor(rank, name, allow_vm_block, safepoint_check_required) {}; + }; + #endif // SHARE_RUNTIME_MUTEX_HPP
< prev index next >