src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp

Wed, 27 Apr 2016 01:25:04 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:25:04 +0800
changeset 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/
changeset: 6782:28b50d07f6f8
tag: jdk8u25-b17

aoqi@0 1
aoqi@0 2 /*
aoqi@0 3 * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
aoqi@0 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 5 *
aoqi@0 6 * This code is free software; you can redistribute it and/or modify it
aoqi@0 7 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 8 * published by the Free Software Foundation.
aoqi@0 9 *
aoqi@0 10 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 13 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 14 * accompanied this code).
aoqi@0 15 *
aoqi@0 16 * You should have received a copy of the GNU General Public License version
aoqi@0 17 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 19 *
aoqi@0 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 21 * or visit www.oracle.com if you need additional information or have any
aoqi@0 22 * questions.
aoqi@0 23 *
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 #include "precompiled.hpp"
aoqi@0 27 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
aoqi@0 28 #include "gc_implementation/parallelScavenge/gcTaskThread.hpp"
aoqi@0 29 #include "memory/allocation.hpp"
aoqi@0 30 #include "memory/allocation.inline.hpp"
aoqi@0 31 #include "memory/resourceArea.hpp"
aoqi@0 32 #include "runtime/handles.hpp"
aoqi@0 33 #include "runtime/handles.inline.hpp"
aoqi@0 34 #include "runtime/os.hpp"
aoqi@0 35 #include "runtime/thread.hpp"
aoqi@0 36
aoqi@0 37 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
aoqi@0 38
aoqi@0 39 GCTaskThread::GCTaskThread(GCTaskManager* manager,
aoqi@0 40 uint which,
aoqi@0 41 uint processor_id) :
aoqi@0 42 _manager(manager),
aoqi@0 43 _processor_id(processor_id),
aoqi@0 44 _time_stamps(NULL),
aoqi@0 45 _time_stamp_index(0)
aoqi@0 46 {
aoqi@0 47 if (!os::create_thread(this, os::pgc_thread))
aoqi@0 48 vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create GC thread. Out of system resources.");
aoqi@0 49
aoqi@0 50 if (PrintGCTaskTimeStamps) {
aoqi@0 51 _time_stamps = NEW_C_HEAP_ARRAY(GCTaskTimeStamp, GCTaskTimeStampEntries, mtGC);
aoqi@0 52
aoqi@0 53 guarantee(_time_stamps != NULL, "Sanity");
aoqi@0 54 }
aoqi@0 55 set_id(which);
aoqi@0 56 set_name("GC task thread#%d (ParallelGC)", which);
aoqi@0 57 }
aoqi@0 58
aoqi@0 59 GCTaskThread::~GCTaskThread() {
aoqi@0 60 if (_time_stamps != NULL) {
aoqi@0 61 FREE_C_HEAP_ARRAY(GCTaskTimeStamp, _time_stamps, mtGC);
aoqi@0 62 }
aoqi@0 63 }
aoqi@0 64
aoqi@0 65 void GCTaskThread::start() {
aoqi@0 66 os::start_thread(this);
aoqi@0 67 }
aoqi@0 68
aoqi@0 69 GCTaskTimeStamp* GCTaskThread::time_stamp_at(uint index) {
aoqi@0 70 guarantee(index < GCTaskTimeStampEntries, "increase GCTaskTimeStampEntries");
aoqi@0 71
aoqi@0 72 return &(_time_stamps[index]);
aoqi@0 73 }
aoqi@0 74
aoqi@0 75 void GCTaskThread::print_task_time_stamps() {
aoqi@0 76 assert(PrintGCTaskTimeStamps, "Sanity");
aoqi@0 77 assert(_time_stamps != NULL, "Sanity (Probably set PrintGCTaskTimeStamps late)");
aoqi@0 78
aoqi@0 79 tty->print_cr("GC-Thread %u entries: %d", id(), _time_stamp_index);
aoqi@0 80 for(uint i=0; i<_time_stamp_index; i++) {
aoqi@0 81 GCTaskTimeStamp* time_stamp = time_stamp_at(i);
aoqi@0 82 tty->print_cr("\t[ %s " INT64_FORMAT " " INT64_FORMAT " ]",
aoqi@0 83 time_stamp->name(),
aoqi@0 84 time_stamp->entry_time(),
aoqi@0 85 time_stamp->exit_time());
aoqi@0 86 }
aoqi@0 87
aoqi@0 88 // Reset after dumping the data
aoqi@0 89 _time_stamp_index = 0;
aoqi@0 90 }
aoqi@0 91
aoqi@0 92 void GCTaskThread::print_on(outputStream* st) const {
aoqi@0 93 st->print("\"%s\" ", name());
aoqi@0 94 Thread::print_on(st);
aoqi@0 95 st->cr();
aoqi@0 96 }
aoqi@0 97
aoqi@0 98 // GC workers get tasks from the GCTaskManager and execute
aoqi@0 99 // them in this method. If there are no tasks to execute,
aoqi@0 100 // the GC workers wait in the GCTaskManager's get_task()
aoqi@0 101 // for tasks to be enqueued for execution.
aoqi@0 102
aoqi@0 103 void GCTaskThread::run() {
aoqi@0 104 // Set up the thread for stack overflow support
aoqi@0 105 this->record_stack_base_and_size();
aoqi@0 106 this->initialize_thread_local_storage();
aoqi@0 107 // Bind yourself to your processor.
aoqi@0 108 if (processor_id() != GCTaskManager::sentinel_worker()) {
aoqi@0 109 if (TraceGCTaskThread) {
aoqi@0 110 tty->print_cr("GCTaskThread::run: "
aoqi@0 111 " binding to processor %u", processor_id());
aoqi@0 112 }
aoqi@0 113 if (!os::bind_to_processor(processor_id())) {
aoqi@0 114 DEBUG_ONLY(
aoqi@0 115 warning("Couldn't bind GCTaskThread %u to processor %u",
aoqi@0 116 which(), processor_id());
aoqi@0 117 )
aoqi@0 118 }
aoqi@0 119 }
aoqi@0 120 // Part of thread setup.
aoqi@0 121 // ??? Are these set up once here to make subsequent ones fast?
aoqi@0 122 HandleMark hm_outer;
aoqi@0 123 ResourceMark rm_outer;
aoqi@0 124
aoqi@0 125 TimeStamp timer;
aoqi@0 126
aoqi@0 127 for (;/* ever */;) {
aoqi@0 128 // These are so we can flush the resources allocated in the inner loop.
aoqi@0 129 HandleMark hm_inner;
aoqi@0 130 ResourceMark rm_inner;
aoqi@0 131 for (; /* break */; ) {
aoqi@0 132 // This will block until there is a task to be gotten.
aoqi@0 133 GCTask* task = manager()->get_task(which());
aoqi@0 134 // Record if this is an idle task for later use.
aoqi@0 135 bool is_idle_task = task->is_idle_task();
aoqi@0 136 // In case the update is costly
aoqi@0 137 if (PrintGCTaskTimeStamps) {
aoqi@0 138 timer.update();
aoqi@0 139 }
aoqi@0 140
aoqi@0 141 jlong entry_time = timer.ticks();
aoqi@0 142 char* name = task->name();
aoqi@0 143
aoqi@0 144 // If this is the barrier task, it can be destroyed
aoqi@0 145 // by the GC task manager once the do_it() executes.
aoqi@0 146 task->do_it(manager(), which());
aoqi@0 147
aoqi@0 148 // Use the saved value of is_idle_task because references
aoqi@0 149 // using "task" are not reliable for the barrier task.
aoqi@0 150 if (!is_idle_task) {
aoqi@0 151 manager()->note_completion(which());
aoqi@0 152
aoqi@0 153 if (PrintGCTaskTimeStamps) {
aoqi@0 154 assert(_time_stamps != NULL,
aoqi@0 155 "Sanity (PrintGCTaskTimeStamps set late?)");
aoqi@0 156
aoqi@0 157 timer.update();
aoqi@0 158
aoqi@0 159 GCTaskTimeStamp* time_stamp = time_stamp_at(_time_stamp_index++);
aoqi@0 160
aoqi@0 161 time_stamp->set_name(name);
aoqi@0 162 time_stamp->set_entry_time(entry_time);
aoqi@0 163 time_stamp->set_exit_time(timer.ticks());
aoqi@0 164 }
aoqi@0 165 } else {
aoqi@0 166 // idle tasks complete outside the normal accounting
aoqi@0 167 // so that a task can complete without waiting for idle tasks.
aoqi@0 168 // They have to be terminated separately.
aoqi@0 169 IdleGCTask::destroy((IdleGCTask*)task);
aoqi@0 170 set_is_working(true);
aoqi@0 171 }
aoqi@0 172
aoqi@0 173 // Check if we should release our inner resources.
aoqi@0 174 if (manager()->should_release_resources(which())) {
aoqi@0 175 manager()->note_release(which());
aoqi@0 176 break;
aoqi@0 177 }
aoqi@0 178 }
aoqi@0 179 }
aoqi@0 180 }

mercurial