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_ExitRelease = 0;
105 int ObjectMonitor::Knob_InlineNotify = 1;
106 int ObjectMonitor::Knob_Verbose = 0;
107 int ObjectMonitor::Knob_VerifyInUse = 0;
108 int ObjectMonitor::Knob_VerifyMatch = 0;
109 int ObjectMonitor::Knob_SpinLimit = 5000; // derived by an external tool -
110
111 static int Knob_SpinBase = 0; // Floor AKA SpinMin
112 static int Knob_SpinBackOff = 0; // spin-loop backoff
113 static int Knob_CASPenalty = -1; // Penalty for failed CAS
114 static int Knob_OXPenalty = -1; // Penalty for observed _owner change
115 static int Knob_SpinSetSucc = 1; // spinners set the _succ field
116 static int Knob_SpinEarly = 1;
117 static int Knob_SuccEnabled = 1; // futile wake throttling
118 static int Knob_SuccRestrict = 0; // Limit successors + spinners to at-most-one
119 static int Knob_MaxSpinners = -1; // Should be a function of # CPUs
120 static int Knob_Bonus = 100; // spin success bonus
121 static int Knob_BonusB = 100; // spin success bonus
122 static int Knob_Penalty = 200; // spin failure penalty
123 static int Knob_Poverty = 1000;
124 static int Knob_SpinAfterFutile = 1; // Spin after returning from park()
125 static int Knob_FixedSpin = 0;
126 static int Knob_OState = 3; // Spinner checks thread state of _owner
127 static int Knob_UsePause = 1;
128 static int Knob_ExitPolicy = 0;
129 static int Knob_PreSpin = 10; // 20-100 likely better
130 static int Knob_ResetEvent = 0;
131 static int BackOffMask = 0;
132
2198 NEWPERFCOUNTER(_sync_Parks);
2199 NEWPERFCOUNTER(_sync_Notifications);
2200 NEWPERFVARIABLE(_sync_MonExtant);
2201 #undef NEWPERFCOUNTER
2202 #undef NEWPERFVARIABLE
2203 }
2204 }
2205
2206 void ObjectMonitor::DeferredInitialize() {
2207 if (InitDone > 0) return;
2208 if (Atomic::cmpxchg (-1, &InitDone, 0) != 0) {
2209 while (InitDone != 1) /* empty */;
2210 return;
2211 }
2212
2213 // One-shot global initialization ...
2214 // The initialization is idempotent, so we don't need locks.
2215 // In the future consider doing this via os::init_2().
2216
2217 if (os::is_MP()) {
2218 BackOffMask = (1 << Knob_SpinBackOff) - 1;
2219 // CONSIDER: BackOffMask = ROUNDUP_NEXT_POWER2 (ncpus-1)
2220 } else {
2221 Knob_SpinLimit = 0;
2222 Knob_SpinBase = 0;
2223 Knob_PreSpin = 0;
2224 Knob_FixedSpin = -1;
2225 }
2226
2227 OrderAccess::fence();
2228 InitDone = 1;
2229 }
2230
|
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_ExitRelease = 0;
105 int ObjectMonitor::Knob_InlineNotify = 1;
106 int ObjectMonitor::Knob_Verbose = 0;
107 int ObjectMonitor::Knob_VerifyInUse = 0;
108 int ObjectMonitor::Knob_VerifyMatch = 0;
109 int ObjectMonitor::Knob_SpinLimit = 5000; // derived by an external tool -
110
111 static int Knob_SpinBase = 0; // Floor AKA SpinMin
112 static int Knob_CASPenalty = -1; // Penalty for failed CAS
113 static int Knob_OXPenalty = -1; // Penalty for observed _owner change
114 static int Knob_SpinSetSucc = 1; // spinners set the _succ field
115 static int Knob_SpinEarly = 1;
116 static int Knob_SuccEnabled = 1; // futile wake throttling
117 static int Knob_SuccRestrict = 0; // Limit successors + spinners to at-most-one
118 static int Knob_MaxSpinners = -1; // Should be a function of # CPUs
119 static int Knob_Bonus = 100; // spin success bonus
120 static int Knob_BonusB = 100; // spin success bonus
121 static int Knob_Penalty = 200; // spin failure penalty
122 static int Knob_Poverty = 1000;
123 static int Knob_SpinAfterFutile = 1; // Spin after returning from park()
124 static int Knob_FixedSpin = 0;
125 static int Knob_OState = 3; // Spinner checks thread state of _owner
126 static int Knob_UsePause = 1;
127 static int Knob_ExitPolicy = 0;
128 static int Knob_PreSpin = 10; // 20-100 likely better
129 static int Knob_ResetEvent = 0;
130 static int BackOffMask = 0;
131
2197 NEWPERFCOUNTER(_sync_Parks);
2198 NEWPERFCOUNTER(_sync_Notifications);
2199 NEWPERFVARIABLE(_sync_MonExtant);
2200 #undef NEWPERFCOUNTER
2201 #undef NEWPERFVARIABLE
2202 }
2203 }
2204
2205 void ObjectMonitor::DeferredInitialize() {
2206 if (InitDone > 0) return;
2207 if (Atomic::cmpxchg (-1, &InitDone, 0) != 0) {
2208 while (InitDone != 1) /* empty */;
2209 return;
2210 }
2211
2212 // One-shot global initialization ...
2213 // The initialization is idempotent, so we don't need locks.
2214 // In the future consider doing this via os::init_2().
2215
2216 if (os::is_MP()) {
2217 BackOffMask = 0;
2218 } else {
2219 Knob_SpinLimit = 0;
2220 Knob_SpinBase = 0;
2221 Knob_PreSpin = 0;
2222 Knob_FixedSpin = -1;
2223 }
2224
2225 OrderAccess::fence();
2226 InitDone = 1;
2227 }
2228
|