annotate src/share/vm/utilities/workgroup.cpp @ 8733:9def4075da6d

8008079: G1: Add nextObject routine to CMBitMapRO and replace nextWord Summary: Update the task local finger to the start of the next object when marking aborts, in order to avoid the redundant scanning of all 0's when the marking task restarts, if otherwise updating to the next word. In addition, reuse the routine nextObject() in routine iterate(). Reviewed-by: johnc, ysr Contributed-by: tamao <tao.mao@oracle.com>
author tamao
date Tue, 05 Mar 2013 15:36:56 -0800
parents b9a9ed0f8eeb
children 6f817ce50129
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
6842
b9a9ed0f8eeb 7197424: update copyright year to match last edit in jdk8 hotspot repository
mikael
parents: 6197
diff changeset
2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 342
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 342
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 342
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1833
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1833
diff changeset
26 #include "memory/allocation.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1833
diff changeset
27 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1833
diff changeset
28 #include "runtime/os.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1833
diff changeset
29 #include "utilities/workgroup.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // Definitions of WorkGang methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
32
a61af66fc99e Initial load
duke
parents:
diff changeset
33 AbstractWorkGang::AbstractWorkGang(const char* name,
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
34 bool are_GC_task_threads,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
35 bool are_ConcurrentGC_threads) :
0
a61af66fc99e Initial load
duke
parents:
diff changeset
36 _name(name),
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
37 _are_GC_task_threads(are_GC_task_threads),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
38 _are_ConcurrentGC_threads(are_ConcurrentGC_threads) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
39
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
40 assert(!(are_GC_task_threads && are_ConcurrentGC_threads),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
41 "They cannot both be STW GC and Concurrent threads" );
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
42
0
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // Other initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
44 _monitor = new Monitor(/* priority */ Mutex::leaf,
a61af66fc99e Initial load
duke
parents:
diff changeset
45 /* name */ "WorkGroup monitor",
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
46 /* allow_vm_block */ are_GC_task_threads);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
47 assert(monitor() != NULL, "Failed to allocate monitor");
a61af66fc99e Initial load
duke
parents:
diff changeset
48 _terminate = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
49 _task = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
50 _sequence_number = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
51 _started_workers = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
52 _finished_workers = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
53 }
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 WorkGang::WorkGang(const char* name,
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
56 uint workers,
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
57 bool are_GC_task_threads,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
58 bool are_ConcurrentGC_threads) :
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
59 AbstractWorkGang(name, are_GC_task_threads, are_ConcurrentGC_threads) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
60 _total_workers = workers;
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
61 }
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
62
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
63 GangWorker* WorkGang::allocate_worker(uint which) {
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
64 GangWorker* new_worker = new GangWorker(this, which);
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
65 return new_worker;
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
66 }
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
67
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
68 // The current implementation will exit if the allocation
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
69 // of any worker fails. Still, return a boolean so that
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
70 // a future implementation can possibly do a partial
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
71 // initialization of the workers and report such to the
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
72 // caller.
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
73 bool WorkGang::initialize_workers() {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
74
0
a61af66fc99e Initial load
duke
parents:
diff changeset
75 if (TraceWorkGang) {
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
76 tty->print_cr("Constructing work gang %s with %d threads",
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
77 name(),
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
78 total_workers());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
79 }
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 4728
diff changeset
80 _gang_workers = NEW_C_HEAP_ARRAY(GangWorker*, total_workers(), mtInternal);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
81 if (gang_workers() == NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
82 vm_exit_out_of_memory(0, "Cannot create GangWorker array.");
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
83 return false;
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
84 }
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
85 os::ThreadType worker_type;
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
86 if (are_ConcurrentGC_threads()) {
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
87 worker_type = os::cgc_thread;
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
88 } else {
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
89 worker_type = os::pgc_thread;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
90 }
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
91 for (uint worker = 0; worker < total_workers(); worker += 1) {
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
92 GangWorker* new_worker = allocate_worker(worker);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
93 assert(new_worker != NULL, "Failed to allocate GangWorker");
a61af66fc99e Initial load
duke
parents:
diff changeset
94 _gang_workers[worker] = new_worker;
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
95 if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
96 vm_exit_out_of_memory(0, "Cannot create worker GC thread. Out of system resources.");
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
97 return false;
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
98 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
99 if (!DisableStartThread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
100 os::start_thread(new_worker);
a61af66fc99e Initial load
duke
parents:
diff changeset
101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
103 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 AbstractWorkGang::~AbstractWorkGang() {
a61af66fc99e Initial load
duke
parents:
diff changeset
107 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 tty->print_cr("Destructing work gang %s", name());
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110 stop(); // stop all the workers
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
111 for (uint worker = 0; worker < total_workers(); worker += 1) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
112 delete gang_worker(worker);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
114 delete gang_workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
115 delete monitor();
a61af66fc99e Initial load
duke
parents:
diff changeset
116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
117
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
118 GangWorker* AbstractWorkGang::gang_worker(uint i) const {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // Array index bounds checking.
a61af66fc99e Initial load
duke
parents:
diff changeset
120 GangWorker* result = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 assert(gang_workers() != NULL, "No workers for indexing");
a61af66fc99e Initial load
duke
parents:
diff changeset
122 assert(((i >= 0) && (i < total_workers())), "Worker index out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
123 result = _gang_workers[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
124 assert(result != NULL, "Indexing to null worker");
a61af66fc99e Initial load
duke
parents:
diff changeset
125 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
127
a61af66fc99e Initial load
duke
parents:
diff changeset
128 void WorkGang::run_task(AbstractGangTask* task) {
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
129 run_task(task, total_workers());
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
130 }
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
131
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
132 void WorkGang::run_task(AbstractGangTask* task, uint no_of_parallel_workers) {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
133 task->set_for_termination(no_of_parallel_workers);
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
134
0
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // This thread is executed by the VM thread which does not block
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // on ordinary MutexLocker's.
a61af66fc99e Initial load
duke
parents:
diff changeset
137 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
138 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
139 tty->print_cr("Running work gang %s task %s", name(), task->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // Tell all the workers to run a task.
a61af66fc99e Initial load
duke
parents:
diff changeset
142 assert(task != NULL, "Running a null task");
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // Initialize.
a61af66fc99e Initial load
duke
parents:
diff changeset
144 _task = task;
a61af66fc99e Initial load
duke
parents:
diff changeset
145 _sequence_number += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
146 _started_workers = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 _finished_workers = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // Tell the workers to get to work.
a61af66fc99e Initial load
duke
parents:
diff changeset
149 monitor()->notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // Wait for them to be finished
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
151 while (finished_workers() < no_of_parallel_workers) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
152 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
153 tty->print_cr("Waiting in work gang %s: %d/%d finished sequence %d",
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
154 name(), finished_workers(), no_of_parallel_workers,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
155 _sequence_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
157 monitor()->wait(/* no_safepoint_check */ true);
a61af66fc99e Initial load
duke
parents:
diff changeset
158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
159 _task = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 if (TraceWorkGang) {
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
161 tty->print_cr("\nFinished work gang %s: %d/%d sequence %d",
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
162 name(), finished_workers(), no_of_parallel_workers,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
163 _sequence_number);
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
164 Thread* me = Thread::current();
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
165 tty->print_cr(" T: 0x%x VM_thread: %d", me, me->is_VM_thread());
2369
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 1972
diff changeset
166 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
168
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
169 void FlexibleWorkGang::run_task(AbstractGangTask* task) {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
170 // If active_workers() is passed, _finished_workers
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
171 // must only be incremented for workers that find non_null
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
172 // work (as opposed to all those that just check that the
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
173 // task is not null).
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
174 WorkGang::run_task(task, (uint) active_workers());
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
175 }
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
176
0
a61af66fc99e Initial load
duke
parents:
diff changeset
177 void AbstractWorkGang::stop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // Tell all workers to terminate, then wait for them to become inactive.
a61af66fc99e Initial load
duke
parents:
diff changeset
179 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
180 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
181 tty->print_cr("Stopping work gang %s task %s", name(), task()->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183 _task = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
184 _terminate = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
185 monitor()->notify_all();
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
186 while (finished_workers() < active_workers()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
187 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
188 tty->print_cr("Waiting in work gang %s: %d/%d finished",
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
189 name(), finished_workers(), active_workers());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
191 monitor()->wait(/* no_safepoint_check */ true);
a61af66fc99e Initial load
duke
parents:
diff changeset
192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
194
a61af66fc99e Initial load
duke
parents:
diff changeset
195 void AbstractWorkGang::internal_worker_poll(WorkData* data) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 assert(monitor()->owned_by_self(), "worker_poll is an internal method");
a61af66fc99e Initial load
duke
parents:
diff changeset
197 assert(data != NULL, "worker data is null");
a61af66fc99e Initial load
duke
parents:
diff changeset
198 data->set_terminate(terminate());
a61af66fc99e Initial load
duke
parents:
diff changeset
199 data->set_task(task());
a61af66fc99e Initial load
duke
parents:
diff changeset
200 data->set_sequence_number(sequence_number());
a61af66fc99e Initial load
duke
parents:
diff changeset
201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
202
a61af66fc99e Initial load
duke
parents:
diff changeset
203 void AbstractWorkGang::internal_note_start() {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 assert(monitor()->owned_by_self(), "note_finish is an internal method");
a61af66fc99e Initial load
duke
parents:
diff changeset
205 _started_workers += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 void AbstractWorkGang::internal_note_finish() {
a61af66fc99e Initial load
duke
parents:
diff changeset
209 assert(monitor()->owned_by_self(), "note_finish is an internal method");
a61af66fc99e Initial load
duke
parents:
diff changeset
210 _finished_workers += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 void AbstractWorkGang::print_worker_threads_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 uint num_thr = total_workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
215 for (uint i = 0; i < num_thr; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
216 gang_worker(i)->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
217 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 void AbstractWorkGang::threads_do(ThreadClosure* tc) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
222 assert(tc != NULL, "Null ThreadClosure");
a61af66fc99e Initial load
duke
parents:
diff changeset
223 uint num_thr = total_workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
224 for (uint i = 0; i < num_thr; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
225 tc->do_thread(gang_worker(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
228
a61af66fc99e Initial load
duke
parents:
diff changeset
229 // GangWorker methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
230
a61af66fc99e Initial load
duke
parents:
diff changeset
231 GangWorker::GangWorker(AbstractWorkGang* gang, uint id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
232 _gang = gang;
a61af66fc99e Initial load
duke
parents:
diff changeset
233 set_id(id);
a61af66fc99e Initial load
duke
parents:
diff changeset
234 set_name("Gang worker#%d (%s)", id, gang->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 void GangWorker::run() {
a61af66fc99e Initial load
duke
parents:
diff changeset
238 initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
239 loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
241
a61af66fc99e Initial load
duke
parents:
diff changeset
242 void GangWorker::initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
243 this->initialize_thread_local_storage();
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 4728
diff changeset
244 this->record_stack_base_and_size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
245 assert(_gang != NULL, "No gang to run in");
a61af66fc99e Initial load
duke
parents:
diff changeset
246 os::set_priority(this, NearMaxPriority);
a61af66fc99e Initial load
duke
parents:
diff changeset
247 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
248 tty->print_cr("Running gang worker for gang %s id %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
249 gang()->name(), id());
a61af66fc99e Initial load
duke
parents:
diff changeset
250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // The VM thread should not execute here because MutexLocker's are used
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // as (opposed to MutexLockerEx's).
a61af66fc99e Initial load
duke
parents:
diff changeset
253 assert(!Thread::current()->is_VM_thread(), "VM thread should not be part"
a61af66fc99e Initial load
duke
parents:
diff changeset
254 " of a work gang");
a61af66fc99e Initial load
duke
parents:
diff changeset
255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 void GangWorker::loop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
258 int previous_sequence_number = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
259 Monitor* gang_monitor = gang()->monitor();
a61af66fc99e Initial load
duke
parents:
diff changeset
260 for ( ; /* !terminate() */; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
261 WorkData data;
a61af66fc99e Initial load
duke
parents:
diff changeset
262 int part; // Initialized below.
a61af66fc99e Initial load
duke
parents:
diff changeset
263 {
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // Grab the gang mutex.
a61af66fc99e Initial load
duke
parents:
diff changeset
265 MutexLocker ml(gang_monitor);
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // Wait for something to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // Polling outside the while { wait } avoids missed notifies
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // in the outer loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
269 gang()->internal_worker_poll(&data);
a61af66fc99e Initial load
duke
parents:
diff changeset
270 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
271 tty->print("Polled outside for work in gang %s worker %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
272 gang()->name(), id());
a61af66fc99e Initial load
duke
parents:
diff changeset
273 tty->print(" terminate: %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
274 data.terminate() ? "true" : "false");
a61af66fc99e Initial load
duke
parents:
diff changeset
275 tty->print(" sequence: %d (prev: %d)",
a61af66fc99e Initial load
duke
parents:
diff changeset
276 data.sequence_number(), previous_sequence_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
277 if (data.task() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
278 tty->print(" task: %s", data.task()->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
279 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
280 tty->print(" task: NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
282 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
284 for ( ; /* break or return */; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // Terminate if requested.
a61af66fc99e Initial load
duke
parents:
diff changeset
286 if (data.terminate()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
287 gang()->internal_note_finish();
a61af66fc99e Initial load
duke
parents:
diff changeset
288 gang_monitor->notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
289 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
290 }
a61af66fc99e Initial load
duke
parents:
diff changeset
291 // Check for new work.
a61af66fc99e Initial load
duke
parents:
diff changeset
292 if ((data.task() != NULL) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
293 (data.sequence_number() != previous_sequence_number)) {
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
294 if (gang()->needs_more_workers()) {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
295 gang()->internal_note_start();
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
296 gang_monitor->notify_all();
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
297 part = gang()->started_workers() - 1;
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
298 break;
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
299 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
300 }
a61af66fc99e Initial load
duke
parents:
diff changeset
301 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
302 gang_monitor->wait(/* no_safepoint_check */ true);
a61af66fc99e Initial load
duke
parents:
diff changeset
303 gang()->internal_worker_poll(&data);
a61af66fc99e Initial load
duke
parents:
diff changeset
304 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
305 tty->print("Polled inside for work in gang %s worker %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
306 gang()->name(), id());
a61af66fc99e Initial load
duke
parents:
diff changeset
307 tty->print(" terminate: %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
308 data.terminate() ? "true" : "false");
a61af66fc99e Initial load
duke
parents:
diff changeset
309 tty->print(" sequence: %d (prev: %d)",
a61af66fc99e Initial load
duke
parents:
diff changeset
310 data.sequence_number(), previous_sequence_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
311 if (data.task() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
312 tty->print(" task: %s", data.task()->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
313 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 tty->print(" task: NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
316 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // Drop gang mutex.
a61af66fc99e Initial load
duke
parents:
diff changeset
320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
321 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
322 tty->print("Work for work gang %s id %d task %s part %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
323 gang()->name(), id(), data.task()->name(), part);
a61af66fc99e Initial load
duke
parents:
diff changeset
324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
325 assert(data.task() != NULL, "Got null task");
a61af66fc99e Initial load
duke
parents:
diff changeset
326 data.task()->work(part);
a61af66fc99e Initial load
duke
parents:
diff changeset
327 {
a61af66fc99e Initial load
duke
parents:
diff changeset
328 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 tty->print("Finish for work gang %s id %d task %s part %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
330 gang()->name(), id(), data.task()->name(), part);
a61af66fc99e Initial load
duke
parents:
diff changeset
331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
332 // Grab the gang mutex.
a61af66fc99e Initial load
duke
parents:
diff changeset
333 MutexLocker ml(gang_monitor);
a61af66fc99e Initial load
duke
parents:
diff changeset
334 gang()->internal_note_finish();
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // Tell the gang you are done.
a61af66fc99e Initial load
duke
parents:
diff changeset
336 gang_monitor->notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // Drop the gang mutex.
a61af66fc99e Initial load
duke
parents:
diff changeset
338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
339 previous_sequence_number = data.sequence_number();
a61af66fc99e Initial load
duke
parents:
diff changeset
340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
342
a61af66fc99e Initial load
duke
parents:
diff changeset
343 bool GangWorker::is_GC_task_thread() const {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
344 return gang()->are_GC_task_threads();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
345 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
346
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
347 bool GangWorker::is_ConcurrentGC_thread() const {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
348 return gang()->are_ConcurrentGC_threads();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
350
a61af66fc99e Initial load
duke
parents:
diff changeset
351 void GangWorker::print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
352 st->print("\"%s\" ", name());
a61af66fc99e Initial load
duke
parents:
diff changeset
353 Thread::print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
355 }
a61af66fc99e Initial load
duke
parents:
diff changeset
356
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // Printing methods
a61af66fc99e Initial load
duke
parents:
diff changeset
358
a61af66fc99e Initial load
duke
parents:
diff changeset
359 const char* AbstractWorkGang::name() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 return _name;
a61af66fc99e Initial load
duke
parents:
diff changeset
361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
362
a61af66fc99e Initial load
duke
parents:
diff changeset
363 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
364
a61af66fc99e Initial load
duke
parents:
diff changeset
365 const char* AbstractGangTask::name() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
366 return _name;
a61af66fc99e Initial load
duke
parents:
diff changeset
367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
368
a61af66fc99e Initial load
duke
parents:
diff changeset
369 #endif /* PRODUCT */
a61af66fc99e Initial load
duke
parents:
diff changeset
370
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
371 // FlexibleWorkGang
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
372
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
373
0
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // *** WorkGangBarrierSync
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 WorkGangBarrierSync::WorkGangBarrierSync()
a61af66fc99e Initial load
duke
parents:
diff changeset
377 : _monitor(Mutex::safepoint, "work gang barrier sync", true),
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
378 _n_workers(0), _n_completed(0), _should_reset(false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
379 }
a61af66fc99e Initial load
duke
parents:
diff changeset
380
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
381 WorkGangBarrierSync::WorkGangBarrierSync(uint n_workers, const char* name)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
382 : _monitor(Mutex::safepoint, name, true),
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
383 _n_workers(n_workers), _n_completed(0), _should_reset(false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
385
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
386 void WorkGangBarrierSync::set_n_workers(uint n_workers) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
387 _n_workers = n_workers;
a61af66fc99e Initial load
duke
parents:
diff changeset
388 _n_completed = 0;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
389 _should_reset = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
390 }
a61af66fc99e Initial load
duke
parents:
diff changeset
391
a61af66fc99e Initial load
duke
parents:
diff changeset
392 void WorkGangBarrierSync::enter() {
a61af66fc99e Initial load
duke
parents:
diff changeset
393 MutexLockerEx x(monitor(), Mutex::_no_safepoint_check_flag);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
394 if (should_reset()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
395 // The should_reset() was set and we are the first worker to enter
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
396 // the sync barrier. We will zero the n_completed() count which
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
397 // effectively resets the barrier.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
398 zero_completed();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
399 set_should_reset(false);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
400 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
401 inc_completed();
a61af66fc99e Initial load
duke
parents:
diff changeset
402 if (n_completed() == n_workers()) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
403 // At this point we would like to reset the barrier to be ready in
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
404 // case it is used again. However, we cannot set n_completed() to
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
405 // 0, even after the notify_all(), given that some other workers
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
406 // might still be waiting for n_completed() to become ==
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
407 // n_workers(). So, if we set n_completed() to 0, those workers
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
408 // will get stuck (as they will wake up, see that n_completed() !=
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
409 // n_workers() and go back to sleep). Instead, we raise the
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
410 // should_reset() flag and the barrier will be reset the first
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
411 // time a worker enters it again.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
412 set_should_reset(true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
413 monitor()->notify_all();
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
414 } else {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
415 while (n_completed() != n_workers()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
416 monitor()->wait(/* no_safepoint_check */ true);
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
420
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // SubTasksDone functions.
a61af66fc99e Initial load
duke
parents:
diff changeset
422
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
423 SubTasksDone::SubTasksDone(uint n) :
0
a61af66fc99e Initial load
duke
parents:
diff changeset
424 _n_tasks(n), _n_threads(1), _tasks(NULL) {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 4728
diff changeset
425 _tasks = NEW_C_HEAP_ARRAY(uint, n, mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
426 guarantee(_tasks != NULL, "alloc failure");
a61af66fc99e Initial load
duke
parents:
diff changeset
427 clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 bool SubTasksDone::valid() {
a61af66fc99e Initial load
duke
parents:
diff changeset
431 return _tasks != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
433
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
434 void SubTasksDone::set_n_threads(uint t) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
435 assert(_claimed == 0 || _threads_completed == _n_threads,
a61af66fc99e Initial load
duke
parents:
diff changeset
436 "should not be called while tasks are being processed!");
a61af66fc99e Initial load
duke
parents:
diff changeset
437 _n_threads = (t == 0 ? 1 : t);
a61af66fc99e Initial load
duke
parents:
diff changeset
438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
439
a61af66fc99e Initial load
duke
parents:
diff changeset
440 void SubTasksDone::clear() {
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
441 for (uint i = 0; i < _n_tasks; i++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
442 _tasks[i] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
444 _threads_completed = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
445 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
446 _claimed = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
447 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
449
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
450 bool SubTasksDone::is_task_claimed(uint t) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
451 assert(0 <= t && t < _n_tasks, "bad task id.");
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
452 uint old = _tasks[t];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
453 if (old == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
454 old = Atomic::cmpxchg(1, &_tasks[t], 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
455 }
a61af66fc99e Initial load
duke
parents:
diff changeset
456 assert(_tasks[t] == 1, "What else?");
a61af66fc99e Initial load
duke
parents:
diff changeset
457 bool res = old != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
458 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
459 if (!res) {
a61af66fc99e Initial load
duke
parents:
diff changeset
460 assert(_claimed < _n_tasks, "Too many tasks claimed; missing clear?");
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
461 Atomic::inc((volatile jint*) &_claimed);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
463 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
464 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
466
a61af66fc99e Initial load
duke
parents:
diff changeset
467 void SubTasksDone::all_tasks_completed() {
a61af66fc99e Initial load
duke
parents:
diff changeset
468 jint observed = _threads_completed;
a61af66fc99e Initial load
duke
parents:
diff changeset
469 jint old;
a61af66fc99e Initial load
duke
parents:
diff changeset
470 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
471 old = observed;
a61af66fc99e Initial load
duke
parents:
diff changeset
472 observed = Atomic::cmpxchg(old+1, &_threads_completed, old);
a61af66fc99e Initial load
duke
parents:
diff changeset
473 } while (observed != old);
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // If this was the last thread checking in, clear the tasks.
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
475 if (observed+1 == (jint)_n_threads) clear();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
477
a61af66fc99e Initial load
duke
parents:
diff changeset
478
a61af66fc99e Initial load
duke
parents:
diff changeset
479 SubTasksDone::~SubTasksDone() {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 4728
diff changeset
480 if (_tasks != NULL) FREE_C_HEAP_ARRAY(jint, _tasks, mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // *** SequentialSubTasksDone
a61af66fc99e Initial load
duke
parents:
diff changeset
484
a61af66fc99e Initial load
duke
parents:
diff changeset
485 void SequentialSubTasksDone::clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
486 _n_tasks = _n_claimed = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
487 _n_threads = _n_completed = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
489
a61af66fc99e Initial load
duke
parents:
diff changeset
490 bool SequentialSubTasksDone::valid() {
a61af66fc99e Initial load
duke
parents:
diff changeset
491 return _n_threads > 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
492 }
a61af66fc99e Initial load
duke
parents:
diff changeset
493
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
494 bool SequentialSubTasksDone::is_task_claimed(uint& t) {
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
495 uint* n_claimed_ptr = &_n_claimed;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
496 t = *n_claimed_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
497 while (t < _n_tasks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
498 jint res = Atomic::cmpxchg(t+1, n_claimed_ptr, t);
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
499 if (res == (jint)t) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
500 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
502 t = *n_claimed_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
503 }
a61af66fc99e Initial load
duke
parents:
diff changeset
504 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 bool SequentialSubTasksDone::all_tasks_completed() {
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
508 uint* n_completed_ptr = &_n_completed;
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
509 uint complete = *n_completed_ptr;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
510 while (true) {
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
511 uint res = Atomic::cmpxchg(complete+1, n_completed_ptr, complete);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
512 if (res == complete) {
a61af66fc99e Initial load
duke
parents:
diff changeset
513 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
515 complete = res;
a61af66fc99e Initial load
duke
parents:
diff changeset
516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
517 if (complete+1 == _n_threads) {
a61af66fc99e Initial load
duke
parents:
diff changeset
518 clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
519 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
521 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
522 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
523
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
524 bool FreeIdSet::_stat_init = false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
525 FreeIdSet* FreeIdSet::_sets[NSets];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
526 bool FreeIdSet::_safepoint;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
527
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
528 FreeIdSet::FreeIdSet(int sz, Monitor* mon) :
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
529 _sz(sz), _mon(mon), _hd(0), _waiters(0), _index(-1), _claimed(0)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
530 {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
531 _ids = new int[sz];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
532 for (int i = 0; i < sz; i++) _ids[i] = i+1;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
533 _ids[sz-1] = end_of_list; // end of list.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
534 if (_stat_init) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
535 for (int j = 0; j < NSets; j++) _sets[j] = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
536 _stat_init = true;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
537 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
538 // Add to sets. (This should happen while the system is still single-threaded.)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
539 for (int j = 0; j < NSets; j++) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
540 if (_sets[j] == NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
541 _sets[j] = this;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
542 _index = j;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
543 break;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
544 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
545 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
546 guarantee(_index != -1, "Too many FreeIdSets in use!");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
547 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
548
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
549 FreeIdSet::~FreeIdSet() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
550 _sets[_index] = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
551 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
552
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
553 void FreeIdSet::set_safepoint(bool b) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
554 _safepoint = b;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
555 if (b) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
556 for (int j = 0; j < NSets; j++) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
557 if (_sets[j] != NULL && _sets[j]->_waiters > 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
558 Monitor* mon = _sets[j]->_mon;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
559 mon->lock_without_safepoint_check();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
560 mon->notify_all();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
561 mon->unlock();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
562 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
563 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
564 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
565 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
566
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
567 #define FID_STATS 0
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
568
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
569 int FreeIdSet::claim_par_id() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
570 #if FID_STATS
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
571 thread_t tslf = thr_self();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
572 tty->print("claim_par_id[%d]: sz = %d, claimed = %d\n", tslf, _sz, _claimed);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
573 #endif
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
574 MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
575 while (!_safepoint && _hd == end_of_list) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
576 _waiters++;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
577 #if FID_STATS
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
578 if (_waiters > 5) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
579 tty->print("claim_par_id waiting[%d]: %d waiters, %d claimed.\n",
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
580 tslf, _waiters, _claimed);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
581 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
582 #endif
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
583 _mon->wait(Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
584 _waiters--;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
585 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
586 if (_hd == end_of_list) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
587 #if FID_STATS
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
588 tty->print("claim_par_id[%d]: returning EOL.\n", tslf);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
589 #endif
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
590 return -1;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
591 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
592 int res = _hd;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
593 _hd = _ids[res];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
594 _ids[res] = claimed; // For debugging.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
595 _claimed++;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
596 #if FID_STATS
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
597 tty->print("claim_par_id[%d]: returning %d, claimed = %d.\n",
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
598 tslf, res, _claimed);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
599 #endif
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
600 return res;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
601 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
602 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
603
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
604 bool FreeIdSet::claim_perm_id(int i) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
605 assert(0 <= i && i < _sz, "Out of range.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
606 MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
607 int prev = end_of_list;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
608 int cur = _hd;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
609 while (cur != end_of_list) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
610 if (cur == i) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
611 if (prev == end_of_list) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
612 _hd = _ids[cur];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
613 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
614 _ids[prev] = _ids[cur];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
615 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
616 _ids[cur] = claimed;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
617 _claimed++;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
618 return true;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
619 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
620 prev = cur;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
621 cur = _ids[cur];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
622 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
623 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
624 return false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
625
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
626 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
627
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
628 void FreeIdSet::release_par_id(int id) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
629 MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
630 assert(_ids[id] == claimed, "Precondition.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
631 _ids[id] = _hd;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
632 _hd = id;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
633 _claimed--;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
634 #if FID_STATS
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
635 tty->print("[%d] release_par_id(%d), waiters =%d, claimed = %d.\n",
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
636 thr_self(), id, _waiters, _claimed);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
637 #endif
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
638 if (_waiters > 0)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
639 // Notify all would be safer, but this is OK, right?
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
640 _mon->notify_all();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
641 }