comparison src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp @ 8679:a252e688abcf

7189971: Implement CMSWaitDuration for non-incremental mode of CMS Reviewed-by: jmasa, johnc, ysr Contributed-by: michal@frajt.eu
author jmasa
date Fri, 01 Feb 2013 17:02:36 -0800
parents a7509aff1b06
children f2110083203d
comparison
equal deleted inserted replaced
8666:7f482030ff64 8679:a252e688abcf
298 assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token), 298 assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token),
299 "Should have been cleared"); 299 "Should have been cleared");
300 } 300 }
301 } 301 }
302 302
303 // Wait until the next synchronous GC, a concurrent full gc request, 303 // Wait until any cms_lock event
304 // or a timeout, whichever is earlier.
305 void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) { 304 void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) {
306 MutexLockerEx x(CGC_lock, 305 MutexLockerEx x(CGC_lock,
307 Mutex::_no_safepoint_check_flag); 306 Mutex::_no_safepoint_check_flag);
308 if (_should_terminate || _collector->_full_gc_requested) { 307 if (_should_terminate || _collector->_full_gc_requested) {
309 return; 308 return;
313 clear_CMS_flag(CMS_cms_wants_token); 312 clear_CMS_flag(CMS_cms_wants_token);
314 assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token), 313 assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token),
315 "Should not be set"); 314 "Should not be set");
316 } 315 }
317 316
317 // Wait until the next synchronous GC, a concurrent full gc request,
318 // or a timeout, whichever is earlier.
319 void ConcurrentMarkSweepThread::wait_on_cms_lock_for_scavenge(long t_millis) {
320 // Wait time in millis or 0 value representing infinite wait for a scavenge
321 assert(t_millis >= 0, "Wait time for scavenge should be 0 or positive");
322
323 GenCollectedHeap* gch = GenCollectedHeap::heap();
324 double start_time_secs = os::elapsedTime();
325 double end_time_secs = start_time_secs + (t_millis / ((double) MILLIUNITS));
326
327 // Total collections count before waiting loop
328 unsigned int before_count;
329 {
330 MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag);
331 before_count = gch->total_collections();
332 }
333
334 unsigned int loop_count = 0;
335
336 while(!_should_terminate) {
337 double now_time = os::elapsedTime();
338 long wait_time_millis;
339
340 if(t_millis != 0) {
341 // New wait limit
342 wait_time_millis = (long) ((end_time_secs - now_time) * MILLIUNITS);
343 if(wait_time_millis <= 0) {
344 // Wait time is over
345 break;
346 }
347 } else {
348 // No wait limit, wait if necessary forever
349 wait_time_millis = 0;
350 }
351
352 // Wait until the next event or the remaining timeout
353 {
354 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
355
356 if (_should_terminate || _collector->_full_gc_requested) {
357 return;
358 }
359 set_CMS_flag(CMS_cms_wants_token); // to provoke notifies
360 assert(t_millis == 0 || wait_time_millis > 0, "Sanity");
361 CGC_lock->wait(Mutex::_no_safepoint_check_flag, wait_time_millis);
362 clear_CMS_flag(CMS_cms_wants_token);
363 assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token),
364 "Should not be set");
365 }
366
367 // Extra wait time check before entering the heap lock to get the collection count
368 if(t_millis != 0 && os::elapsedTime() >= end_time_secs) {
369 // Wait time is over
370 break;
371 }
372
373 // Total collections count after the event
374 unsigned int after_count;
375 {
376 MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag);
377 after_count = gch->total_collections();
378 }
379
380 if(before_count != after_count) {
381 // There was a collection - success
382 break;
383 }
384
385 // Too many loops warning
386 if(++loop_count == 0) {
387 warning("wait_on_cms_lock_for_scavenge() has looped %u times", loop_count - 1);
388 }
389 }
390 }
391
318 void ConcurrentMarkSweepThread::sleepBeforeNextCycle() { 392 void ConcurrentMarkSweepThread::sleepBeforeNextCycle() {
319 while (!_should_terminate) { 393 while (!_should_terminate) {
320 if (CMSIncrementalMode) { 394 if (CMSIncrementalMode) {
321 icms_wait(); 395 icms_wait();
396 if(CMSWaitDuration >= 0) {
397 // Wait until the next synchronous GC, a concurrent full gc
398 // request or a timeout, whichever is earlier.
399 wait_on_cms_lock_for_scavenge(CMSWaitDuration);
400 }
322 return; 401 return;
323 } else { 402 } else {
324 // Wait until the next synchronous GC, a concurrent full gc 403 if(CMSWaitDuration >= 0) {
325 // request or a timeout, whichever is earlier. 404 // Wait until the next synchronous GC, a concurrent full gc
326 wait_on_cms_lock(CMSWaitDuration); 405 // request or a timeout, whichever is earlier.
406 wait_on_cms_lock_for_scavenge(CMSWaitDuration);
407 } else {
408 // Wait until any cms_lock event or check interval not to call shouldConcurrentCollect permanently
409 wait_on_cms_lock(CMSCheckInterval);
410 }
327 } 411 }
328 // Check if we should start a CMS collection cycle 412 // Check if we should start a CMS collection cycle
329 if (_collector->shouldConcurrentCollect()) { 413 if (_collector->shouldConcurrentCollect()) {
330 return; 414 return;
331 } 415 }