< prev index next >

src/hotspot/share/runtime/objectMonitor.cpp

Print this page
rev 51780 : imported patch syncknobs-00-base
rev 51781 : imported patch syncknobs-01-Knob_ReportSettings
rev 51782 : imported patch syncknobs-02-Knob_SpinBackOff
rev 51783 : imported patch syncknobs-03-BackOffMask
rev 51784 : imported patch syncknobs-04-Knob_ExitRelease
rev 51785 : imported patch syncknobs-05-Knob_InlineNotify
rev 51786 : imported patch syncknobs-06-Knob_Verbose
rev 51787 : imported patch syncknobs-07-Knob_VerifyInUse
rev 51788 : imported patch syncknobs-08-Knob_VerifyMatch
rev 51789 : imported patch syncknobs-09-Knob_SpinBase


  86     if (DTraceMonitorProbes) {                                             \
  87       DTRACE_MONITOR_PROBE_COMMON(obj, thread);                            \
  88       HOTSPOT_MONITOR_##probe(jtid,                                        \
  89                               (uintptr_t)(monitor), bytes, len);           \
  90     }                                                                      \
  91   }
  92 
  93 #else //  ndef DTRACE_ENABLED
  94 
  95 #define DTRACE_MONITOR_WAIT_PROBE(obj, thread, millis, mon)    {;}
  96 #define DTRACE_MONITOR_PROBE(probe, obj, thread, mon)          {;}
  97 
  98 #endif // ndef DTRACE_ENABLED
  99 
 100 // Tunables ...
 101 // The knob* variables are effectively final.  Once set they should
 102 // never be modified hence.  Consider using __read_mostly with GCC.
 103 
 104 int ObjectMonitor::Knob_SpinLimit    = 5000;    // derived by an external tool -
 105 
 106 static int Knob_SpinBase            = 0;       // Floor AKA SpinMin
 107 static int Knob_CASPenalty          = -1;      // Penalty for failed CAS
 108 static int Knob_OXPenalty           = -1;      // Penalty for observed _owner change
 109 static int Knob_SpinSetSucc         = 1;       // spinners set the _succ field
 110 static int Knob_SpinEarly           = 1;
 111 static int Knob_SuccEnabled         = 1;       // futile wake throttling
 112 static int Knob_SuccRestrict        = 0;       // Limit successors + spinners to at-most-one
 113 static int Knob_MaxSpinners         = -1;      // Should be a function of # CPUs
 114 static int Knob_Bonus               = 100;     // spin success bonus
 115 static int Knob_BonusB              = 100;     // spin success bonus
 116 static int Knob_Penalty             = 200;     // spin failure penalty
 117 static int Knob_Poverty             = 1000;
 118 static int Knob_SpinAfterFutile     = 1;       // Spin after returning from park()
 119 static int Knob_FixedSpin           = 0;
 120 static int Knob_OState              = 3;       // Spinner checks thread state of _owner
 121 static int Knob_UsePause            = 1;
 122 static int Knob_ExitPolicy          = 0;
 123 static int Knob_PreSpin             = 10;      // 20-100 likely better
 124 static int Knob_ResetEvent          = 0;
 125 
 126 static int Knob_FastHSSEC           = 0;


1829       return 1;
1830     }
1831     SpinPause();
1832   }
1833 
1834   // Admission control - verify preconditions for spinning
1835   //
1836   // We always spin a little bit, just to prevent _SpinDuration == 0 from
1837   // becoming an absorbing state.  Put another way, we spin briefly to
1838   // sample, just in case the system load, parallelism, contention, or lock
1839   // modality changed.
1840   //
1841   // Consider the following alternative:
1842   // Periodically set _SpinDuration = _SpinLimit and try a long/full
1843   // spin attempt.  "Periodically" might mean after a tally of
1844   // the # of failed spin attempts (or iterations) reaches some threshold.
1845   // This takes us into the realm of 1-out-of-N spinning, where we
1846   // hold the duration constant but vary the frequency.
1847 
1848   ctr = _SpinDuration;
1849   if (ctr < Knob_SpinBase) ctr = Knob_SpinBase;
1850   if (ctr <= 0) return 0;
1851 
1852   if (Knob_SuccRestrict && _succ != NULL) return 0;
1853   if (Knob_OState && NotRunnable (Self, (Thread *) _owner)) {
1854     return 0;
1855   }
1856 
1857   int MaxSpin = Knob_MaxSpinners;
1858   if (MaxSpin >= 0) {
1859     if (_Spinner > MaxSpin) {
1860       return 0;
1861     }
1862     // Slightly racy, but benign ...
1863     Adjust(&_Spinner, 1);
1864   }
1865 
1866   // We're good to spin ... spin ingress.
1867   // CONSIDER: use Prefetch::write() to avoid RTS->RTO upgrades
1868   // when preparing to LD...CAS _owner, etc and the CAS is likely
1869   // to succeed.


2167     NEWPERFCOUNTER(_sync_Notifications);
2168     NEWPERFVARIABLE(_sync_MonExtant);
2169 #undef NEWPERFCOUNTER
2170 #undef NEWPERFVARIABLE
2171   }
2172 }
2173 
2174 void ObjectMonitor::DeferredInitialize() {
2175   if (InitDone > 0) return;
2176   if (Atomic::cmpxchg (-1, &InitDone, 0) != 0) {
2177     while (InitDone != 1) /* empty */;
2178     return;
2179   }
2180 
2181   // One-shot global initialization ...
2182   // The initialization is idempotent, so we don't need locks.
2183   // In the future consider doing this via os::init_2().
2184 
2185   if (!os::is_MP()) {
2186     Knob_SpinLimit = 0;
2187     Knob_SpinBase  = 0;
2188     Knob_PreSpin   = 0;
2189     Knob_FixedSpin = -1;
2190   }
2191 
2192   OrderAccess::fence();
2193   InitDone = 1;
2194 }
2195 


  86     if (DTraceMonitorProbes) {                                             \
  87       DTRACE_MONITOR_PROBE_COMMON(obj, thread);                            \
  88       HOTSPOT_MONITOR_##probe(jtid,                                        \
  89                               (uintptr_t)(monitor), bytes, len);           \
  90     }                                                                      \
  91   }
  92 
  93 #else //  ndef DTRACE_ENABLED
  94 
  95 #define DTRACE_MONITOR_WAIT_PROBE(obj, thread, millis, mon)    {;}
  96 #define DTRACE_MONITOR_PROBE(probe, obj, thread, mon)          {;}
  97 
  98 #endif // ndef DTRACE_ENABLED
  99 
 100 // Tunables ...
 101 // The knob* variables are effectively final.  Once set they should
 102 // never be modified hence.  Consider using __read_mostly with GCC.
 103 
 104 int ObjectMonitor::Knob_SpinLimit    = 5000;    // derived by an external tool -
 105 

 106 static int Knob_CASPenalty          = -1;      // Penalty for failed CAS
 107 static int Knob_OXPenalty           = -1;      // Penalty for observed _owner change
 108 static int Knob_SpinSetSucc         = 1;       // spinners set the _succ field
 109 static int Knob_SpinEarly           = 1;
 110 static int Knob_SuccEnabled         = 1;       // futile wake throttling
 111 static int Knob_SuccRestrict        = 0;       // Limit successors + spinners to at-most-one
 112 static int Knob_MaxSpinners         = -1;      // Should be a function of # CPUs
 113 static int Knob_Bonus               = 100;     // spin success bonus
 114 static int Knob_BonusB              = 100;     // spin success bonus
 115 static int Knob_Penalty             = 200;     // spin failure penalty
 116 static int Knob_Poverty             = 1000;
 117 static int Knob_SpinAfterFutile     = 1;       // Spin after returning from park()
 118 static int Knob_FixedSpin           = 0;
 119 static int Knob_OState              = 3;       // Spinner checks thread state of _owner
 120 static int Knob_UsePause            = 1;
 121 static int Knob_ExitPolicy          = 0;
 122 static int Knob_PreSpin             = 10;      // 20-100 likely better
 123 static int Knob_ResetEvent          = 0;
 124 
 125 static int Knob_FastHSSEC           = 0;


1828       return 1;
1829     }
1830     SpinPause();
1831   }
1832 
1833   // Admission control - verify preconditions for spinning
1834   //
1835   // We always spin a little bit, just to prevent _SpinDuration == 0 from
1836   // becoming an absorbing state.  Put another way, we spin briefly to
1837   // sample, just in case the system load, parallelism, contention, or lock
1838   // modality changed.
1839   //
1840   // Consider the following alternative:
1841   // Periodically set _SpinDuration = _SpinLimit and try a long/full
1842   // spin attempt.  "Periodically" might mean after a tally of
1843   // the # of failed spin attempts (or iterations) reaches some threshold.
1844   // This takes us into the realm of 1-out-of-N spinning, where we
1845   // hold the duration constant but vary the frequency.
1846 
1847   ctr = _SpinDuration;

1848   if (ctr <= 0) return 0;
1849 
1850   if (Knob_SuccRestrict && _succ != NULL) return 0;
1851   if (Knob_OState && NotRunnable (Self, (Thread *) _owner)) {
1852     return 0;
1853   }
1854 
1855   int MaxSpin = Knob_MaxSpinners;
1856   if (MaxSpin >= 0) {
1857     if (_Spinner > MaxSpin) {
1858       return 0;
1859     }
1860     // Slightly racy, but benign ...
1861     Adjust(&_Spinner, 1);
1862   }
1863 
1864   // We're good to spin ... spin ingress.
1865   // CONSIDER: use Prefetch::write() to avoid RTS->RTO upgrades
1866   // when preparing to LD...CAS _owner, etc and the CAS is likely
1867   // to succeed.


2165     NEWPERFCOUNTER(_sync_Notifications);
2166     NEWPERFVARIABLE(_sync_MonExtant);
2167 #undef NEWPERFCOUNTER
2168 #undef NEWPERFVARIABLE
2169   }
2170 }
2171 
2172 void ObjectMonitor::DeferredInitialize() {
2173   if (InitDone > 0) return;
2174   if (Atomic::cmpxchg (-1, &InitDone, 0) != 0) {
2175     while (InitDone != 1) /* empty */;
2176     return;
2177   }
2178 
2179   // One-shot global initialization ...
2180   // The initialization is idempotent, so we don't need locks.
2181   // In the future consider doing this via os::init_2().
2182 
2183   if (!os::is_MP()) {
2184     Knob_SpinLimit = 0;

2185     Knob_PreSpin   = 0;
2186     Knob_FixedSpin = -1;
2187   }
2188 
2189   OrderAccess::fence();
2190   InitDone = 1;
2191 }
2192 
< prev index next >