comparison src/share/vm/runtime/thread.hpp @ 1878:fa83ab460c54

6988353: refactor contended sync subsystem Summary: reduce complexity by factoring synchronizer.cpp Reviewed-by: dholmes, never, coleenp
author acorn
date Fri, 22 Oct 2010 15:59:34 -0400
parents 0715f0cf171d
children 2d26b0046e0d f95d63e2154a
comparison
equal deleted inserted replaced
1874:75ab0162aa84 1878:fa83ab460c54
28 class JvmtiThreadState; 28 class JvmtiThreadState;
29 class JvmtiGetLoadedClassesClosure; 29 class JvmtiGetLoadedClassesClosure;
30 class ThreadStatistics; 30 class ThreadStatistics;
31 class ConcurrentLocksDump; 31 class ConcurrentLocksDump;
32 class ParkEvent ; 32 class ParkEvent ;
33 class Parker;
33 34
34 class ciEnv; 35 class ciEnv;
35 class CompileThread; 36 class CompileThread;
36 class CompileLog; 37 class CompileLog;
37 class CompileTask; 38 class CompileTask;
542 static void SpinAcquire (volatile int * Lock, const char * Name) ; 543 static void SpinAcquire (volatile int * Lock, const char * Name) ;
543 static void SpinRelease (volatile int * Lock) ; 544 static void SpinRelease (volatile int * Lock) ;
544 static void muxAcquire (volatile intptr_t * Lock, const char * Name) ; 545 static void muxAcquire (volatile intptr_t * Lock, const char * Name) ;
545 static void muxAcquireW (volatile intptr_t * Lock, ParkEvent * ev) ; 546 static void muxAcquireW (volatile intptr_t * Lock, ParkEvent * ev) ;
546 static void muxRelease (volatile intptr_t * Lock) ; 547 static void muxRelease (volatile intptr_t * Lock) ;
547
548 }; 548 };
549 549
550 // Inline implementation of Thread::current() 550 // Inline implementation of Thread::current()
551 // Thread::current is "hot" it's called > 128K times in the 1st 500 msecs of 551 // Thread::current is "hot" it's called > 128K times in the 1st 500 msecs of
552 // startup. 552 // startup.
1767 if (_thread) _thread->leave_signal_handler(); 1767 if (_thread) _thread->leave_signal_handler();
1768 _thread = NULL; 1768 _thread = NULL;
1769 } 1769 }
1770 }; 1770 };
1771 1771
1772 // ParkEvents are type-stable and immortal.
1773 //
1774 // Lifecycle: Once a ParkEvent is associated with a thread that ParkEvent remains
1775 // associated with the thread for the thread's entire lifetime - the relationship is
1776 // stable. A thread will be associated at most one ParkEvent. When the thread
1777 // expires, the ParkEvent moves to the EventFreeList. New threads attempt to allocate from
1778 // the EventFreeList before creating a new Event. Type-stability frees us from
1779 // worrying about stale Event or Thread references in the objectMonitor subsystem.
1780 // (A reference to ParkEvent is always valid, even though the event may no longer be associated
1781 // with the desired or expected thread. A key aspect of this design is that the callers of
1782 // park, unpark, etc must tolerate stale references and spurious wakeups).
1783 //
1784 // Only the "associated" thread can block (park) on the ParkEvent, although
1785 // any other thread can unpark a reachable parkevent. Park() is allowed to
1786 // return spuriously. In fact park-unpark a really just an optimization to
1787 // avoid unbounded spinning and surrender the CPU to be a polite system citizen.
1788 // A degenerate albeit "impolite" park-unpark implementation could simply return.
1789 // See http://blogs.sun.com/dave for more details.
1790 //
1791 // Eventually I'd like to eliminate Events and ObjectWaiters, both of which serve as
1792 // thread proxies, and simply make the THREAD structure type-stable and persistent.
1793 // Currently, we unpark events associated with threads, but ideally we'd just
1794 // unpark threads.
1795 //
1796 // The base-class, PlatformEvent, is platform-specific while the ParkEvent is
1797 // platform-independent. PlatformEvent provides park(), unpark(), etc., and
1798 // is abstract -- that is, a PlatformEvent should never be instantiated except
1799 // as part of a ParkEvent.
1800 // Equivalently we could have defined a platform-independent base-class that
1801 // exported Allocate(), Release(), etc. The platform-specific class would extend
1802 // that base-class, adding park(), unpark(), etc.
1803 //
1804 // A word of caution: The JVM uses 2 very similar constructs:
1805 // 1. ParkEvent are used for Java-level "monitor" synchronization.
1806 // 2. Parkers are used by JSR166-JUC park-unpark.
1807 //
1808 // We'll want to eventually merge these redundant facilities and use ParkEvent.
1809
1810
1811 class ParkEvent : public os::PlatformEvent {
1812 private:
1813 ParkEvent * FreeNext ;
1814
1815 // Current association
1816 Thread * AssociatedWith ;
1817 intptr_t RawThreadIdentity ; // LWPID etc
1818 volatile int Incarnation ;
1819
1820 // diagnostic : keep track of last thread to wake this thread.
1821 // this is useful for construction of dependency graphs.
1822 void * LastWaker ;
1823
1824 public:
1825 // MCS-CLH list linkage and Native Mutex/Monitor
1826 ParkEvent * volatile ListNext ;
1827 ParkEvent * volatile ListPrev ;
1828 volatile intptr_t OnList ;
1829 volatile int TState ;
1830 volatile int Notified ; // for native monitor construct
1831 volatile int IsWaiting ; // Enqueued on WaitSet
1832
1833
1834 private:
1835 static ParkEvent * volatile FreeList ;
1836 static volatile int ListLock ;
1837
1838 // It's prudent to mark the dtor as "private"
1839 // ensuring that it's not visible outside the package.
1840 // Unfortunately gcc warns about such usage, so
1841 // we revert to the less desirable "protected" visibility.
1842 // The other compilers accept private dtors.
1843
1844 protected: // Ensure dtor is never invoked
1845 ~ParkEvent() { guarantee (0, "invariant") ; }
1846
1847 ParkEvent() : PlatformEvent() {
1848 AssociatedWith = NULL ;
1849 FreeNext = NULL ;
1850 ListNext = NULL ;
1851 ListPrev = NULL ;
1852 OnList = 0 ;
1853 TState = 0 ;
1854 Notified = 0 ;
1855 IsWaiting = 0 ;
1856 }
1857
1858 // We use placement-new to force ParkEvent instances to be
1859 // aligned on 256-byte address boundaries. This ensures that the least
1860 // significant byte of a ParkEvent address is always 0.
1861
1862 void * operator new (size_t sz) ;
1863 void operator delete (void * a) ;
1864
1865 public:
1866 static ParkEvent * Allocate (Thread * t) ;
1867 static void Release (ParkEvent * e) ;
1868 } ;