76 SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized; |
76 SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized; |
77 volatile int SafepointSynchronize::_waiting_to_block = 0; |
77 volatile int SafepointSynchronize::_waiting_to_block = 0; |
78 volatile int SafepointSynchronize::_safepoint_counter = 0; |
78 volatile int SafepointSynchronize::_safepoint_counter = 0; |
79 int SafepointSynchronize::_current_jni_active_count = 0; |
79 int SafepointSynchronize::_current_jni_active_count = 0; |
80 long SafepointSynchronize::_end_of_last_safepoint = 0; |
80 long SafepointSynchronize::_end_of_last_safepoint = 0; |
|
81 int SafepointSynchronize::_defer_thr_suspend_loop_count = 4000; |
|
82 static const int safepoint_spin_before_yield = 2000; |
81 static volatile int PageArmed = 0 ; // safepoint polling page is RO|RW vs PROT_NONE |
83 static volatile int PageArmed = 0 ; // safepoint polling page is RO|RW vs PROT_NONE |
82 static volatile int TryingToBlock = 0 ; // proximate value -- for advisory use only |
84 static volatile int TryingToBlock = 0 ; // proximate value -- for advisory use only |
83 static bool timeout_error_printed = false; |
85 static bool timeout_error_printed = false; |
84 |
86 |
85 // Roll all threads forward to a safepoint and suspend them all |
87 // Roll all threads forward to a safepoint and suspend them all |
189 |
191 |
190 if (SafepointMechanism::uses_global_page_poll()) { |
192 if (SafepointMechanism::uses_global_page_poll()) { |
191 // Make interpreter safepoint aware |
193 // Make interpreter safepoint aware |
192 Interpreter::notice_safepoints(); |
194 Interpreter::notice_safepoints(); |
193 |
195 |
194 if (DeferPollingPageLoopCount < 0) { |
196 // Make polling safepoint aware |
195 // Make polling safepoint aware |
197 guarantee (PageArmed == 0, "invariant") ; |
196 guarantee (PageArmed == 0, "invariant") ; |
198 PageArmed = 1 ; |
197 PageArmed = 1 ; |
199 os::make_polling_page_unreadable(); |
198 os::make_polling_page_unreadable(); |
|
199 } |
|
200 } |
200 } |
201 |
201 |
202 // Consider using active_processor_count() ... but that call is expensive. |
202 // Consider using active_processor_count() ... but that call is expensive. |
203 int ncpus = os::processor_count() ; |
203 int ncpus = os::processor_count() ; |
204 unsigned int iterations = 0; |
204 unsigned int iterations = 0; |
307 // Alternately, instead of counting iterations of the outer loop |
307 // Alternately, instead of counting iterations of the outer loop |
308 // we could count the # of threads visited in the inner loop, above. |
308 // we could count the # of threads visited in the inner loop, above. |
309 // 9. On windows consider using the return value from SwitchThreadTo() |
309 // 9. On windows consider using the return value from SwitchThreadTo() |
310 // to drive subsequent spin/SwitchThreadTo()/Sleep(N) decisions. |
310 // to drive subsequent spin/SwitchThreadTo()/Sleep(N) decisions. |
311 |
311 |
312 if (SafepointMechanism::uses_global_page_poll() && int(iterations) == DeferPollingPageLoopCount) { |
312 if (int(iterations) == -1) { // overflow - something is wrong. |
313 guarantee (PageArmed == 0, "invariant") ; |
313 // We can only overflow here when we are using global |
314 PageArmed = 1 ; |
314 // polling pages. We keep this guarantee in its original |
315 os::make_polling_page_unreadable(); |
315 // form so that searches of the bug database for this |
|
316 // failure mode find the right bugs. |
|
317 guarantee (PageArmed == 0, "invariant"); |
316 } |
318 } |
317 |
319 |
318 // Instead of (ncpus > 1) consider either (still_running < (ncpus + EPSILON)) or |
320 // Instead of (ncpus > 1) consider either (still_running < (ncpus + EPSILON)) or |
319 // ((still_running + _waiting_to_block - TryingToBlock)) < ncpus) |
321 // ((still_running + _waiting_to_block - TryingToBlock)) < ncpus) |
320 ++steps ; |
322 ++steps ; |
321 if (ncpus > 1 && steps < SafepointSpinBeforeYield) { |
323 if (ncpus > 1 && steps < safepoint_spin_before_yield) { |
322 SpinPause() ; // MP-Polite spin |
324 SpinPause() ; // MP-Polite spin |
323 } else |
325 } else |
324 if (steps < DeferThrSuspendLoopCount) { |
326 if (steps < _defer_thr_suspend_loop_count) { |
325 os::naked_yield() ; |
327 os::naked_yield() ; |
326 } else { |
328 } else { |
327 os::naked_short_sleep(1); |
329 os::naked_short_sleep(1); |
328 } |
330 } |
329 |
331 |
1188 jlong SafepointSynchronize::_max_sync_time = 0; |
1190 jlong SafepointSynchronize::_max_sync_time = 0; |
1189 jlong SafepointSynchronize::_max_vmop_time = 0; |
1191 jlong SafepointSynchronize::_max_vmop_time = 0; |
1190 float SafepointSynchronize::_ts_of_current_safepoint = 0.0f; |
1192 float SafepointSynchronize::_ts_of_current_safepoint = 0.0f; |
1191 |
1193 |
1192 static jlong cleanup_end_time = 0; |
1194 static jlong cleanup_end_time = 0; |
1193 static bool need_to_track_page_armed_status = false; |
|
1194 static bool init_done = false; |
1195 static bool init_done = false; |
1195 |
1196 |
1196 // Helper method to print the header. |
1197 // Helper method to print the header. |
1197 static void print_header() { |
1198 static void print_header() { |
1198 // The number of spaces is significant here, and should match the format |
1199 // The number of spaces is significant here, and should match the format |
1199 // specifiers in print_statistics(). |
1200 // specifiers in print_statistics(). |
1200 |
1201 |
1201 tty->print(" vmop " |
1202 tty->print(" vmop " |
1202 "[ threads: total initially_running wait_to_block ]" |
1203 "[ threads: total initially_running wait_to_block ]" |
1203 "[ time: spin block sync cleanup vmop ] "); |
1204 "[ time: spin block sync cleanup vmop ] "); |
1204 |
|
1205 // no page armed status printed out if it is always armed. |
|
1206 if (need_to_track_page_armed_status) { |
|
1207 tty->print("page_armed "); |
|
1208 } |
|
1209 |
1205 |
1210 tty->print_cr("page_trap_count"); |
1206 tty->print_cr("page_trap_count"); |
1211 } |
1207 } |
1212 |
1208 |
1213 void SafepointSynchronize::deferred_initialize_stat() { |
1209 void SafepointSynchronize::deferred_initialize_stat() { |
1227 _safepoint_stats = (SafepointStats*)os::malloc(stats_array_size |
1223 _safepoint_stats = (SafepointStats*)os::malloc(stats_array_size |
1228 * sizeof(SafepointStats), mtInternal); |
1224 * sizeof(SafepointStats), mtInternal); |
1229 guarantee(_safepoint_stats != NULL, |
1225 guarantee(_safepoint_stats != NULL, |
1230 "not enough memory for safepoint instrumentation data"); |
1226 "not enough memory for safepoint instrumentation data"); |
1231 |
1227 |
1232 if (DeferPollingPageLoopCount >= 0) { |
|
1233 need_to_track_page_armed_status = true; |
|
1234 } |
|
1235 init_done = true; |
1228 init_done = true; |
1236 } |
1229 } |
1237 |
1230 |
1238 void SafepointSynchronize::begin_statistics(int nof_threads, int nof_running) { |
1231 void SafepointSynchronize::begin_statistics(int nof_threads, int nof_running) { |
1239 assert(init_done, "safepoint statistics array hasn't been initialized"); |
1232 assert(init_done, "safepoint statistics array hasn't been initialized"); |
1267 jlong cur_time = os::javaTimeNanos(); |
1260 jlong cur_time = os::javaTimeNanos(); |
1268 |
1261 |
1269 spstat->_nof_threads_wait_to_block = _waiting_to_block; |
1262 spstat->_nof_threads_wait_to_block = _waiting_to_block; |
1270 if (spstat->_nof_initial_running_threads != 0) { |
1263 if (spstat->_nof_initial_running_threads != 0) { |
1271 spstat->_time_to_spin = cur_time - spstat->_time_to_spin; |
1264 spstat->_time_to_spin = cur_time - spstat->_time_to_spin; |
1272 } |
|
1273 |
|
1274 if (need_to_track_page_armed_status) { |
|
1275 spstat->_page_armed = (PageArmed == 1); |
|
1276 } |
1265 } |
1277 |
1266 |
1278 // Records the start time of waiting for to block. Updated when block is done. |
1267 // Records the start time of waiting for to block. Updated when block is done. |
1279 if (_waiting_to_block != 0) { |
1268 if (_waiting_to_block != 0) { |
1280 spstat->_time_to_wait_to_block = cur_time; |
1269 spstat->_time_to_wait_to_block = cur_time; |
1361 (int64_t)(sstats->_time_to_wait_to_block / MICROUNITS), |
1350 (int64_t)(sstats->_time_to_wait_to_block / MICROUNITS), |
1362 (int64_t)(sstats->_time_to_sync / MICROUNITS), |
1351 (int64_t)(sstats->_time_to_sync / MICROUNITS), |
1363 (int64_t)(sstats->_time_to_do_cleanups / MICROUNITS), |
1352 (int64_t)(sstats->_time_to_do_cleanups / MICROUNITS), |
1364 (int64_t)(sstats->_time_to_exec_vmop / MICROUNITS)); |
1353 (int64_t)(sstats->_time_to_exec_vmop / MICROUNITS)); |
1365 |
1354 |
1366 if (need_to_track_page_armed_status) { |
|
1367 tty->print(INT32_FORMAT_W(10) " ", sstats->_page_armed); |
|
1368 } |
|
1369 tty->print_cr(INT32_FORMAT_W(15) " ", sstats->_nof_threads_hit_page_trap); |
1355 tty->print_cr(INT32_FORMAT_W(15) " ", sstats->_nof_threads_hit_page_trap); |
1370 } |
1356 } |
1371 } |
1357 } |
1372 |
1358 |
1373 // This method will be called when VM exits. It will first call |
1359 // This method will be called when VM exits. It will first call |
1390 print_statistics(); |
1376 print_statistics(); |
1391 } |
1377 } |
1392 tty->cr(); |
1378 tty->cr(); |
1393 |
1379 |
1394 // Print out polling page sampling status. |
1380 // Print out polling page sampling status. |
1395 if (!need_to_track_page_armed_status) { |
1381 tty->print_cr("Polling page always armed"); |
1396 tty->print_cr("Polling page always armed"); |
|
1397 } else { |
|
1398 tty->print_cr("Defer polling page loop count = " INTX_FORMAT "\n", |
|
1399 DeferPollingPageLoopCount); |
|
1400 } |
|
1401 |
1382 |
1402 for (int index = 0; index < VM_Operation::VMOp_Terminating; index++) { |
1383 for (int index = 0; index < VM_Operation::VMOp_Terminating; index++) { |
1403 if (_safepoint_reasons[index] != 0) { |
1384 if (_safepoint_reasons[index] != 0) { |
1404 tty->print_cr("%-26s" UINT64_FORMAT_W(10), VM_Operation::name(index), |
1385 tty->print_cr("%-26s" UINT64_FORMAT_W(10), VM_Operation::name(index), |
1405 _safepoint_reasons[index]); |
1386 _safepoint_reasons[index]); |