Mercurial > hg > truffle
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 } |