annotate src/share/vm/utilities/workgroup.cpp @ 14649:f6301b007a16

6498581: ThreadInterruptTest3 produces wrong output on Windows Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set. Reviewed-by: acorn, kvn Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author minqi
date Wed, 26 Feb 2014 15:20:41 -0800
parents f9be75d21404
children 78bbf4d43a14
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
10271
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10161
diff changeset
2 * Copyright (c) 2001, 2013, 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) {
10161
746b070f5022 8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents: 10135
diff changeset
82 vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "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)) {
10161
746b070f5022 8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents: 10135
diff changeset
96 vm_exit_out_of_memory(0, OOM_MALLOC_ERROR,
746b070f5022 8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents: 10135
diff changeset
97 "Cannot create worker GC thread. Out of system resources.");
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
98 return false;
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
99 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
100 if (!DisableStartThread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
101 os::start_thread(new_worker);
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103 }
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
104 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 AbstractWorkGang::~AbstractWorkGang() {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 tty->print_cr("Destructing work gang %s", name());
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111 stop(); // stop all the workers
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
112 for (uint worker = 0; worker < total_workers(); worker += 1) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
113 delete gang_worker(worker);
a61af66fc99e Initial load
duke
parents:
diff changeset
114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
115 delete gang_workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
116 delete monitor();
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
119 GangWorker* AbstractWorkGang::gang_worker(uint i) const {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // Array index bounds checking.
a61af66fc99e Initial load
duke
parents:
diff changeset
121 GangWorker* result = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
122 assert(gang_workers() != NULL, "No workers for indexing");
a61af66fc99e Initial load
duke
parents:
diff changeset
123 assert(((i >= 0) && (i < total_workers())), "Worker index out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
124 result = _gang_workers[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
125 assert(result != NULL, "Indexing to null worker");
a61af66fc99e Initial load
duke
parents:
diff changeset
126 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 void WorkGang::run_task(AbstractGangTask* task) {
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
130 run_task(task, total_workers());
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
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
133 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
134 task->set_for_termination(no_of_parallel_workers);
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
135
0
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // This thread is executed by the VM thread which does not block
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // on ordinary MutexLocker's.
a61af66fc99e Initial load
duke
parents:
diff changeset
138 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
139 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
140 tty->print_cr("Running work gang %s task %s", name(), task->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // Tell all the workers to run a task.
a61af66fc99e Initial load
duke
parents:
diff changeset
143 assert(task != NULL, "Running a null task");
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // Initialize.
a61af66fc99e Initial load
duke
parents:
diff changeset
145 _task = task;
a61af66fc99e Initial load
duke
parents:
diff changeset
146 _sequence_number += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 _started_workers = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 _finished_workers = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // Tell the workers to get to work.
a61af66fc99e Initial load
duke
parents:
diff changeset
150 monitor()->notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // Wait for them to be finished
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
152 while (finished_workers() < no_of_parallel_workers) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
153 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
154 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
155 name(), finished_workers(), no_of_parallel_workers,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
156 _sequence_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
158 monitor()->wait(/* no_safepoint_check */ true);
a61af66fc99e Initial load
duke
parents:
diff changeset
159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
160 _task = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
161 if (TraceWorkGang) {
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
162 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
163 name(), finished_workers(), no_of_parallel_workers,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
164 _sequence_number);
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
165 Thread* me = Thread::current();
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
166 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
167 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
170 void FlexibleWorkGang::run_task(AbstractGangTask* task) {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
171 // If active_workers() is passed, _finished_workers
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
172 // 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
173 // 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
174 // task is not null).
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
175 WorkGang::run_task(task, (uint) active_workers());
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
176 }
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
177
0
a61af66fc99e Initial load
duke
parents:
diff changeset
178 void AbstractWorkGang::stop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // Tell all workers to terminate, then wait for them to become inactive.
a61af66fc99e Initial load
duke
parents:
diff changeset
180 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
181 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
182 tty->print_cr("Stopping work gang %s task %s", name(), task()->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
183 }
a61af66fc99e Initial load
duke
parents:
diff changeset
184 _task = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
185 _terminate = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
186 monitor()->notify_all();
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
187 while (finished_workers() < active_workers()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
188 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 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
190 name(), finished_workers(), active_workers());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
192 monitor()->wait(/* no_safepoint_check */ true);
a61af66fc99e Initial load
duke
parents:
diff changeset
193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
195
a61af66fc99e Initial load
duke
parents:
diff changeset
196 void AbstractWorkGang::internal_worker_poll(WorkData* data) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
197 assert(monitor()->owned_by_self(), "worker_poll is an internal method");
a61af66fc99e Initial load
duke
parents:
diff changeset
198 assert(data != NULL, "worker data is null");
a61af66fc99e Initial load
duke
parents:
diff changeset
199 data->set_terminate(terminate());
a61af66fc99e Initial load
duke
parents:
diff changeset
200 data->set_task(task());
a61af66fc99e Initial load
duke
parents:
diff changeset
201 data->set_sequence_number(sequence_number());
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204 void AbstractWorkGang::internal_note_start() {
a61af66fc99e Initial load
duke
parents:
diff changeset
205 assert(monitor()->owned_by_self(), "note_finish is an internal method");
a61af66fc99e Initial load
duke
parents:
diff changeset
206 _started_workers += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 void AbstractWorkGang::internal_note_finish() {
a61af66fc99e Initial load
duke
parents:
diff changeset
210 assert(monitor()->owned_by_self(), "note_finish is an internal method");
a61af66fc99e Initial load
duke
parents:
diff changeset
211 _finished_workers += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
213
a61af66fc99e Initial load
duke
parents:
diff changeset
214 void AbstractWorkGang::print_worker_threads_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
215 uint num_thr = total_workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
216 for (uint i = 0; i < num_thr; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
217 gang_worker(i)->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
218 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 void AbstractWorkGang::threads_do(ThreadClosure* tc) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
223 assert(tc != NULL, "Null ThreadClosure");
a61af66fc99e Initial load
duke
parents:
diff changeset
224 uint num_thr = total_workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
225 for (uint i = 0; i < num_thr; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
226 tc->do_thread(gang_worker(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
229
a61af66fc99e Initial load
duke
parents:
diff changeset
230 // GangWorker methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232 GangWorker::GangWorker(AbstractWorkGang* gang, uint id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
233 _gang = gang;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 set_id(id);
a61af66fc99e Initial load
duke
parents:
diff changeset
235 set_name("Gang worker#%d (%s)", id, gang->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
237
a61af66fc99e Initial load
duke
parents:
diff changeset
238 void GangWorker::run() {
a61af66fc99e Initial load
duke
parents:
diff changeset
239 initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
240 loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 void GangWorker::initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
244 this->initialize_thread_local_storage();
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 4728
diff changeset
245 this->record_stack_base_and_size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
246 assert(_gang != NULL, "No gang to run in");
a61af66fc99e Initial load
duke
parents:
diff changeset
247 os::set_priority(this, NearMaxPriority);
a61af66fc99e Initial load
duke
parents:
diff changeset
248 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 tty->print_cr("Running gang worker for gang %s id %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
250 gang()->name(), id());
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // The VM thread should not execute here because MutexLocker's are used
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // as (opposed to MutexLockerEx's).
a61af66fc99e Initial load
duke
parents:
diff changeset
254 assert(!Thread::current()->is_VM_thread(), "VM thread should not be part"
a61af66fc99e Initial load
duke
parents:
diff changeset
255 " of a work gang");
a61af66fc99e Initial load
duke
parents:
diff changeset
256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
257
a61af66fc99e Initial load
duke
parents:
diff changeset
258 void GangWorker::loop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
259 int previous_sequence_number = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
260 Monitor* gang_monitor = gang()->monitor();
a61af66fc99e Initial load
duke
parents:
diff changeset
261 for ( ; /* !terminate() */; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
262 WorkData data;
a61af66fc99e Initial load
duke
parents:
diff changeset
263 int part; // Initialized below.
a61af66fc99e Initial load
duke
parents:
diff changeset
264 {
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // Grab the gang mutex.
a61af66fc99e Initial load
duke
parents:
diff changeset
266 MutexLocker ml(gang_monitor);
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // Wait for something to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // Polling outside the while { wait } avoids missed notifies
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // in the outer loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
270 gang()->internal_worker_poll(&data);
a61af66fc99e Initial load
duke
parents:
diff changeset
271 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
272 tty->print("Polled outside for work in gang %s worker %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
273 gang()->name(), id());
a61af66fc99e Initial load
duke
parents:
diff changeset
274 tty->print(" terminate: %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
275 data.terminate() ? "true" : "false");
a61af66fc99e Initial load
duke
parents:
diff changeset
276 tty->print(" sequence: %d (prev: %d)",
a61af66fc99e Initial load
duke
parents:
diff changeset
277 data.sequence_number(), previous_sequence_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
278 if (data.task() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 tty->print(" task: %s", data.task()->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
280 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 tty->print(" task: NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
283 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
285 for ( ; /* break or return */; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
286 // Terminate if requested.
a61af66fc99e Initial load
duke
parents:
diff changeset
287 if (data.terminate()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 gang()->internal_note_finish();
a61af66fc99e Initial load
duke
parents:
diff changeset
289 gang_monitor->notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
290 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // Check for new work.
a61af66fc99e Initial load
duke
parents:
diff changeset
293 if ((data.task() != NULL) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
294 (data.sequence_number() != previous_sequence_number)) {
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
295 if (gang()->needs_more_workers()) {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
296 gang()->internal_note_start();
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
297 gang_monitor->notify_all();
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
298 part = gang()->started_workers() - 1;
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
299 break;
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
300 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
302 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
303 gang_monitor->wait(/* no_safepoint_check */ true);
a61af66fc99e Initial load
duke
parents:
diff changeset
304 gang()->internal_worker_poll(&data);
a61af66fc99e Initial load
duke
parents:
diff changeset
305 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
306 tty->print("Polled inside for work in gang %s worker %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
307 gang()->name(), id());
a61af66fc99e Initial load
duke
parents:
diff changeset
308 tty->print(" terminate: %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
309 data.terminate() ? "true" : "false");
a61af66fc99e Initial load
duke
parents:
diff changeset
310 tty->print(" sequence: %d (prev: %d)",
a61af66fc99e Initial load
duke
parents:
diff changeset
311 data.sequence_number(), previous_sequence_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
312 if (data.task() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
313 tty->print(" task: %s", data.task()->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
314 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 tty->print(" task: NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // Drop gang mutex.
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
323 tty->print("Work for work gang %s id %d task %s part %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
324 gang()->name(), id(), data.task()->name(), part);
a61af66fc99e Initial load
duke
parents:
diff changeset
325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
326 assert(data.task() != NULL, "Got null task");
a61af66fc99e Initial load
duke
parents:
diff changeset
327 data.task()->work(part);
a61af66fc99e Initial load
duke
parents:
diff changeset
328 {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 if (TraceWorkGang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
330 tty->print("Finish for work gang %s id %d task %s part %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
331 gang()->name(), id(), data.task()->name(), part);
a61af66fc99e Initial load
duke
parents:
diff changeset
332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // Grab the gang mutex.
a61af66fc99e Initial load
duke
parents:
diff changeset
334 MutexLocker ml(gang_monitor);
a61af66fc99e Initial load
duke
parents:
diff changeset
335 gang()->internal_note_finish();
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // Tell the gang you are done.
a61af66fc99e Initial load
duke
parents:
diff changeset
337 gang_monitor->notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // Drop the gang mutex.
a61af66fc99e Initial load
duke
parents:
diff changeset
339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
340 previous_sequence_number = data.sequence_number();
a61af66fc99e Initial load
duke
parents:
diff changeset
341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344 bool GangWorker::is_GC_task_thread() const {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
345 return gang()->are_GC_task_threads();
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
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
348 bool GangWorker::is_ConcurrentGC_thread() const {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
349 return gang()->are_ConcurrentGC_threads();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
350 }
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 void GangWorker::print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
353 st->print("\"%s\" ", name());
a61af66fc99e Initial load
duke
parents:
diff changeset
354 Thread::print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
355 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // Printing methods
a61af66fc99e Initial load
duke
parents:
diff changeset
359
a61af66fc99e Initial load
duke
parents:
diff changeset
360 const char* AbstractWorkGang::name() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
361 return _name;
a61af66fc99e Initial load
duke
parents:
diff changeset
362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
365
a61af66fc99e Initial load
duke
parents:
diff changeset
366 const char* AbstractGangTask::name() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
367 return _name;
a61af66fc99e Initial load
duke
parents:
diff changeset
368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 #endif /* PRODUCT */
a61af66fc99e Initial load
duke
parents:
diff changeset
371
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
372 // FlexibleWorkGang
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
373
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 2369
diff changeset
374
0
a61af66fc99e Initial load
duke
parents:
diff changeset
375 // *** WorkGangBarrierSync
a61af66fc99e Initial load
duke
parents:
diff changeset
376
a61af66fc99e Initial load
duke
parents:
diff changeset
377 WorkGangBarrierSync::WorkGangBarrierSync()
a61af66fc99e Initial load
duke
parents:
diff changeset
378 : _monitor(Mutex::safepoint, "work gang barrier sync", true),
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
379 _n_workers(0), _n_completed(0), _should_reset(false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
380 }
a61af66fc99e Initial load
duke
parents:
diff changeset
381
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
382 WorkGangBarrierSync::WorkGangBarrierSync(uint n_workers, const char* name)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
383 : _monitor(Mutex::safepoint, name, true),
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
384 _n_workers(n_workers), _n_completed(0), _should_reset(false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
386
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
387 void WorkGangBarrierSync::set_n_workers(uint n_workers) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
388 _n_workers = n_workers;
a61af66fc99e Initial load
duke
parents:
diff changeset
389 _n_completed = 0;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
390 _should_reset = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 void WorkGangBarrierSync::enter() {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 MutexLockerEx x(monitor(), Mutex::_no_safepoint_check_flag);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
395 if (should_reset()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
396 // 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
397 // 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
398 // effectively resets the barrier.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
399 zero_completed();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
400 set_should_reset(false);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
401 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
402 inc_completed();
a61af66fc99e Initial load
duke
parents:
diff changeset
403 if (n_completed() == n_workers()) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
404 // 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
405 // 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
406 // 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
407 // might still be waiting for n_completed() to become ==
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
408 // 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
409 // 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
410 // 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
411 // 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
412 // time a worker enters it again.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
413 set_should_reset(true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
414 monitor()->notify_all();
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
415 } else {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
416 while (n_completed() != n_workers()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
417 monitor()->wait(/* no_safepoint_check */ true);
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
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // SubTasksDone functions.
a61af66fc99e Initial load
duke
parents:
diff changeset
423
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
424 SubTasksDone::SubTasksDone(uint n) :
0
a61af66fc99e Initial load
duke
parents:
diff changeset
425 _n_tasks(n), _n_threads(1), _tasks(NULL) {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 4728
diff changeset
426 _tasks = NEW_C_HEAP_ARRAY(uint, n, mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
427 guarantee(_tasks != NULL, "alloc failure");
a61af66fc99e Initial load
duke
parents:
diff changeset
428 clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 bool SubTasksDone::valid() {
a61af66fc99e Initial load
duke
parents:
diff changeset
432 return _tasks != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
434
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
435 void SubTasksDone::set_n_threads(uint t) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
436 assert(_claimed == 0 || _threads_completed == _n_threads,
a61af66fc99e Initial load
duke
parents:
diff changeset
437 "should not be called while tasks are being processed!");
a61af66fc99e Initial load
duke
parents:
diff changeset
438 _n_threads = (t == 0 ? 1 : t);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
440
a61af66fc99e Initial load
duke
parents:
diff changeset
441 void SubTasksDone::clear() {
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
442 for (uint i = 0; i < _n_tasks; i++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
443 _tasks[i] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
445 _threads_completed = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
446 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
447 _claimed = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
448 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
450
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
451 bool SubTasksDone::is_task_claimed(uint t) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
452 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
453 uint old = _tasks[t];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
454 if (old == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
455 old = Atomic::cmpxchg(1, &_tasks[t], 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
457 assert(_tasks[t] == 1, "What else?");
a61af66fc99e Initial load
duke
parents:
diff changeset
458 bool res = old != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
459 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
460 if (!res) {
a61af66fc99e Initial load
duke
parents:
diff changeset
461 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
462 Atomic::inc((volatile jint*) &_claimed);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
464 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
465 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468 void SubTasksDone::all_tasks_completed() {
a61af66fc99e Initial load
duke
parents:
diff changeset
469 jint observed = _threads_completed;
a61af66fc99e Initial load
duke
parents:
diff changeset
470 jint old;
a61af66fc99e Initial load
duke
parents:
diff changeset
471 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
472 old = observed;
a61af66fc99e Initial load
duke
parents:
diff changeset
473 observed = Atomic::cmpxchg(old+1, &_threads_completed, old);
a61af66fc99e Initial load
duke
parents:
diff changeset
474 } while (observed != old);
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // 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
476 if (observed+1 == (jint)_n_threads) clear();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
478
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 SubTasksDone::~SubTasksDone() {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 4728
diff changeset
481 if (_tasks != NULL) FREE_C_HEAP_ARRAY(jint, _tasks, mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
483
a61af66fc99e Initial load
duke
parents:
diff changeset
484 // *** SequentialSubTasksDone
a61af66fc99e Initial load
duke
parents:
diff changeset
485
a61af66fc99e Initial load
duke
parents:
diff changeset
486 void SequentialSubTasksDone::clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
487 _n_tasks = _n_claimed = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
488 _n_threads = _n_completed = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490
a61af66fc99e Initial load
duke
parents:
diff changeset
491 bool SequentialSubTasksDone::valid() {
a61af66fc99e Initial load
duke
parents:
diff changeset
492 return _n_threads > 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
494
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
495 bool SequentialSubTasksDone::is_task_claimed(uint& t) {
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
496 uint* n_claimed_ptr = &_n_claimed;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
497 t = *n_claimed_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
498 while (t < _n_tasks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
499 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
500 if (res == (jint)t) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
501 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
503 t = *n_claimed_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
505 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
507
a61af66fc99e Initial load
duke
parents:
diff changeset
508 bool SequentialSubTasksDone::all_tasks_completed() {
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
509 uint* n_completed_ptr = &_n_completed;
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
510 uint complete = *n_completed_ptr;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
511 while (true) {
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
512 uint res = Atomic::cmpxchg(complete+1, n_completed_ptr, complete);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
513 if (res == complete) {
a61af66fc99e Initial load
duke
parents:
diff changeset
514 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
516 complete = res;
a61af66fc99e Initial load
duke
parents:
diff changeset
517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
518 if (complete+1 == _n_threads) {
a61af66fc99e Initial load
duke
parents:
diff changeset
519 clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
520 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
523 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
524
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
525 bool FreeIdSet::_stat_init = false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
526 FreeIdSet* FreeIdSet::_sets[NSets];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
527 bool FreeIdSet::_safepoint;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
528
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
529 FreeIdSet::FreeIdSet(int sz, Monitor* mon) :
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
530 _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
531 {
10271
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10161
diff changeset
532 _ids = NEW_C_HEAP_ARRAY(int, sz, mtInternal);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
533 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
534 _ids[sz-1] = end_of_list; // end of list.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
535 if (_stat_init) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
536 for (int j = 0; j < NSets; j++) _sets[j] = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
537 _stat_init = true;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
538 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
539 // 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
540 for (int j = 0; j < NSets; j++) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
541 if (_sets[j] == NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
542 _sets[j] = this;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
543 _index = j;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
544 break;
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 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
547 guarantee(_index != -1, "Too many FreeIdSets in use!");
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
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
550 FreeIdSet::~FreeIdSet() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
551 _sets[_index] = NULL;
10271
f9be75d21404 8012902: remove use of global operator new - take 2
minqi
parents: 10161
diff changeset
552 FREE_C_HEAP_ARRAY(int, _ids, mtInternal);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
553 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
554
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
555 void FreeIdSet::set_safepoint(bool b) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
556 _safepoint = b;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
557 if (b) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
558 for (int j = 0; j < NSets; j++) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
559 if (_sets[j] != NULL && _sets[j]->_waiters > 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
560 Monitor* mon = _sets[j]->_mon;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
561 mon->lock_without_safepoint_check();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
562 mon->notify_all();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
563 mon->unlock();
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 }
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 #define FID_STATS 0
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
570
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
571 int FreeIdSet::claim_par_id() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
572 #if FID_STATS
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
573 thread_t tslf = thr_self();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
574 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
575 #endif
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
576 MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
577 while (!_safepoint && _hd == end_of_list) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
578 _waiters++;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
579 #if FID_STATS
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
580 if (_waiters > 5) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
581 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
582 tslf, _waiters, _claimed);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
583 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
584 #endif
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
585 _mon->wait(Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
586 _waiters--;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
587 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
588 if (_hd == end_of_list) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
589 #if FID_STATS
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
590 tty->print("claim_par_id[%d]: returning EOL.\n", tslf);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
591 #endif
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
592 return -1;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
593 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
594 int res = _hd;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
595 _hd = _ids[res];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
596 _ids[res] = claimed; // For debugging.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
597 _claimed++;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
598 #if FID_STATS
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
599 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
600 tslf, res, _claimed);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
601 #endif
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
602 return res;
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 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
605
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
606 bool FreeIdSet::claim_perm_id(int i) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
607 assert(0 <= i && i < _sz, "Out of range.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
608 MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
609 int prev = end_of_list;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
610 int cur = _hd;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
611 while (cur != end_of_list) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
612 if (cur == i) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
613 if (prev == end_of_list) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
614 _hd = _ids[cur];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
615 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
616 _ids[prev] = _ids[cur];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
617 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
618 _ids[cur] = claimed;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
619 _claimed++;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
620 return true;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
621 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
622 prev = cur;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
623 cur = _ids[cur];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
624 }
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 return false;
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 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
629
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
630 void FreeIdSet::release_par_id(int id) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
631 MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
632 assert(_ids[id] == claimed, "Precondition.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
633 _ids[id] = _hd;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
634 _hd = id;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
635 _claimed--;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
636 #if FID_STATS
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
637 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
638 thr_self(), id, _waiters, _claimed);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
639 #endif
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
640 if (_waiters > 0)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
641 // Notify all would be safer, but this is OK, right?
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
642 _mon->notify_all();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
643 }