< prev index next >

src/hotspot/share/gc/shared/taskqueue.cpp

Print this page
rev 57895 : [mq]: 8215297-remove-ptt

*** 1,7 **** /* ! * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 31,46 **** #include "runtime/os.hpp" #include "runtime/thread.inline.hpp" #include "utilities/debug.hpp" #include "utilities/stack.inline.hpp" - #ifdef TRACESPINNING - uint ParallelTaskTerminator::_total_yields = 0; - uint ParallelTaskTerminator::_total_spins = 0; - uint ParallelTaskTerminator::_total_peeks = 0; - #endif - #if TASKQUEUE_STATS const char * const TaskQueueStats::_names[last_stat_id] = { "qpush", "qpop", "qpop-s", "qattempt", "qsteal", "opush", "omax" }; --- 31,40 ----
*** 110,282 **** get(overflow_max_len), get(overflow)); } #endif // ASSERT #endif // TASKQUEUE_STATS - ParallelTaskTerminator:: - ParallelTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set) : - _n_threads(n_threads), - _queue_set(queue_set), - _offered_termination(0) {} - - ParallelTaskTerminator::~ParallelTaskTerminator() { - assert(_offered_termination == 0 || !peek_in_queue_set(), "Precondition"); - assert(_offered_termination == 0 || _offered_termination == _n_threads, "Terminated or aborted" ); - } - - bool ParallelTaskTerminator::peek_in_queue_set() { - return _queue_set->peek(); - } - - void ParallelTaskTerminator::yield() { - assert(_offered_termination <= _n_threads, "Invariant"); - os::naked_yield(); - } - - void ParallelTaskTerminator::sleep(uint millis) { - assert(_offered_termination <= _n_threads, "Invariant"); - os::naked_sleep(millis); - } - - bool - ParallelTaskTerminator::offer_termination(TerminatorTerminator* terminator) { - assert(_n_threads > 0, "Initialization is incorrect"); - assert(_offered_termination < _n_threads, "Invariant"); - Atomic::inc(&_offered_termination); - - uint yield_count = 0; - // Number of hard spin loops done since last yield - uint hard_spin_count = 0; - // Number of iterations in the hard spin loop. - uint hard_spin_limit = WorkStealingHardSpins; - - // If WorkStealingSpinToYieldRatio is 0, no hard spinning is done. - // If it is greater than 0, then start with a small number - // of spins and increase number with each turn at spinning until - // the count of hard spins exceeds WorkStealingSpinToYieldRatio. - // Then do a yield() call and start spinning afresh. - if (WorkStealingSpinToYieldRatio > 0) { - hard_spin_limit = WorkStealingHardSpins >> WorkStealingSpinToYieldRatio; - hard_spin_limit = MAX2(hard_spin_limit, 1U); - } - // Remember the initial spin limit. - uint hard_spin_start = hard_spin_limit; - - // Loop waiting for all threads to offer termination or - // more work. - while (true) { - assert(_offered_termination <= _n_threads, "Invariant"); - // Are all threads offering termination? - if (_offered_termination == _n_threads) { - assert(!peek_in_queue_set(), "Precondition"); - return true; - } else { - // Look for more work. - // Periodically sleep() instead of yield() to give threads - // waiting on the cores the chance to grab this code - if (yield_count <= WorkStealingYieldsBeforeSleep) { - // Do a yield or hardspin. For purposes of deciding whether - // to sleep, count this as a yield. - yield_count++; - - // Periodically call yield() instead spinning - // After WorkStealingSpinToYieldRatio spins, do a yield() call - // and reset the counts and starting limit. - if (hard_spin_count > WorkStealingSpinToYieldRatio) { - yield(); - hard_spin_count = 0; - hard_spin_limit = hard_spin_start; - #ifdef TRACESPINNING - _total_yields++; - #endif - } else { - // Hard spin this time - // Increase the hard spinning period but only up to a limit. - hard_spin_limit = MIN2(2*hard_spin_limit, - (uint) WorkStealingHardSpins); - for (uint j = 0; j < hard_spin_limit; j++) { - SpinPause(); - } - hard_spin_count++; - #ifdef TRACESPINNING - _total_spins++; - #endif - } - } else { - log_develop_trace(gc, task)("ParallelTaskTerminator::offer_termination() thread " PTR_FORMAT " sleeps after %u yields", - p2i(Thread::current()), yield_count); - yield_count = 0; - // A sleep will cause this processor to seek work on another processor's - // runqueue, if it has nothing else to run (as opposed to the yield - // which may only move the thread to the end of the this processor's - // runqueue). - sleep(WorkStealingSleepMillis); - } - - #ifdef TRACESPINNING - _total_peeks++; - #endif - if (peek_in_queue_set() || - (terminator != NULL && terminator->should_exit_termination())) { - return complete_or_exit_termination(); - } - } - } - } - - #ifdef TRACESPINNING - void ParallelTaskTerminator::print_termination_counts() { - log_trace(gc, task)("ParallelTaskTerminator Total yields: %u" - " Total spins: %u Total peeks: %u", - total_yields(), - total_spins(), - total_peeks()); - } - #endif - - bool ParallelTaskTerminator::complete_or_exit_termination() { - // If termination is ever reached, terminator should stay in such state, - // so that all threads see the same state - uint current_offered = _offered_termination; - uint expected_value; - do { - if (current_offered == _n_threads) { - assert(!peek_in_queue_set(), "Precondition"); - return true; - } - expected_value = current_offered; - } while ((current_offered = Atomic::cmpxchg(&_offered_termination, current_offered, current_offered - 1)) != expected_value); - - assert(_offered_termination < _n_threads, "Invariant"); - return false; - } - - void ParallelTaskTerminator::reset_for_reuse() { - if (_offered_termination != 0) { - assert(_offered_termination == _n_threads, - "Terminator may still be in use"); - _offered_termination = 0; - } - } - #ifdef ASSERT bool ObjArrayTask::is_valid() const { return _obj != NULL && _obj->is_objArray() && _index >= 0 && _index < objArrayOop(_obj)->length(); } #endif // ASSERT - - void ParallelTaskTerminator::reset_for_reuse(uint n_threads) { - reset_for_reuse(); - _n_threads = n_threads; - } - - TaskTerminator::TaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set) : - _terminator(UseOWSTTaskTerminator ? new OWSTTaskTerminator(n_threads, queue_set) - : new ParallelTaskTerminator(n_threads, queue_set)) { - } - - TaskTerminator::~TaskTerminator() { - if (_terminator != NULL) { - delete _terminator; - } - } --- 104,114 ----
< prev index next >