diff -r 420ff459906f -r 9c18c9d839d3 src/hotspot/share/gc/shenandoah/shenandoahTaskqueue.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahTaskqueue.cpp Mon Dec 10 15:47:44 2018 +0100 @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2016, 2018, Red Hat, Inc. All rights reserved. + * + * 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" + +#include "gc/shenandoah/shenandoahHeap.hpp" +#include "gc/shenandoah/shenandoahTaskqueue.hpp" +#include "logging/log.hpp" +#include "logging/logStream.hpp" + +void ShenandoahObjToScanQueueSet::clear() { + uint size = GenericTaskQueueSet::size(); + for (uint index = 0; index < size; index ++) { + ShenandoahObjToScanQueue* q = queue(index); + assert(q != NULL, "Sanity"); + q->clear(); + } +} + +bool ShenandoahObjToScanQueueSet::is_empty() { + uint size = GenericTaskQueueSet::size(); + for (uint index = 0; index < size; index ++) { + ShenandoahObjToScanQueue* q = queue(index); + assert(q != NULL, "Sanity"); + if (!q->is_empty()) { + return false; + } + } + return true; +} + +class ShenandoahOWSTTerminator: public OWSTTaskTerminator { +public: + ShenandoahOWSTTerminator(uint n_threads, TaskQueueSetSuper* queue_set) : + OWSTTaskTerminator(n_threads, queue_set){ } + +protected: + bool exit_termination(size_t tasks, TerminatorTerminator* terminator); +}; + +bool ShenandoahOWSTTerminator::exit_termination(size_t tasks, TerminatorTerminator* terminator) { + ShenandoahTerminatorTerminator* t = (ShenandoahTerminatorTerminator*)terminator; + bool force = (t != NULL) && t->should_force_termination(); + if (force) { + // Force termination : continue termination, even there are remaining tasks. + return false; + } else { + return OWSTTaskTerminator::exit_termination(tasks, terminator); + } +} + +ShenandoahTaskTerminator::ShenandoahTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set) : + _terminator(new ShenandoahOWSTTerminator(n_threads, queue_set)) { } + +ShenandoahTaskTerminator::~ShenandoahTaskTerminator() { + assert(_terminator != NULL, "Invariant"); + delete _terminator; +} + +#if TASKQUEUE_STATS +void ShenandoahObjToScanQueueSet::print_taskqueue_stats_hdr(outputStream* const st) { + st->print_raw_cr("GC Task Stats"); + st->print_raw("thr "); TaskQueueStats::print_header(1, st); st->cr(); + st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr(); +} + +void ShenandoahObjToScanQueueSet::print_taskqueue_stats() const { + if (!log_develop_is_enabled(Trace, gc, task, stats)) { + return; + } + Log(gc, task, stats) log; + ResourceMark rm; + LogStream ls(log.trace()); + outputStream* st = &ls; + print_taskqueue_stats_hdr(st); + + ShenandoahObjToScanQueueSet* queues = const_cast(this); + TaskQueueStats totals; + const uint n = size(); + for (uint i = 0; i < n; ++i) { + st->print(UINT32_FORMAT_W(3), i); + queues->queue(i)->stats.print(st); + st->cr(); + totals += queues->queue(i)->stats; + } + st->print("tot "); totals.print(st); st->cr(); + DEBUG_ONLY(totals.verify()); + +} + +void ShenandoahObjToScanQueueSet::reset_taskqueue_stats() { + const uint n = size(); + for (uint i = 0; i < n; ++i) { + queue(i)->stats.reset(); + } +} +#endif // TASKQUEUE_STATS