annotate src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp @ 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 a252e688abcf
children de6a9e811145
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2365
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
2 * Copyright (c) 2001, 2011, 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: 0
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
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: 0
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: 1887
diff changeset
25 #ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPTHREAD_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
26 #define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPTHREAD_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
27
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
28 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
29 #include "gc_implementation/shared/concurrentGCThread.hpp"
7180
f34d701e952e 8003935: Simplify the needed includes for using Thread::current()
stefank
parents: 3960
diff changeset
30 #include "runtime/thread.inline.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
31
0
a61af66fc99e Initial load
duke
parents:
diff changeset
32 class ConcurrentMarkSweepGeneration;
a61af66fc99e Initial load
duke
parents:
diff changeset
33 class CMSCollector;
a61af66fc99e Initial load
duke
parents:
diff changeset
34
2365
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
35 // The Concurrent Mark Sweep GC Thread
0
a61af66fc99e Initial load
duke
parents:
diff changeset
36 class ConcurrentMarkSweepThread: public ConcurrentGCThread {
a61af66fc99e Initial load
duke
parents:
diff changeset
37 friend class VMStructs;
a61af66fc99e Initial load
duke
parents:
diff changeset
38 friend class ConcurrentMarkSweepGeneration; // XXX should remove friendship
a61af66fc99e Initial load
duke
parents:
diff changeset
39 friend class CMSCollector;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
41 virtual void run();
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
44 static ConcurrentMarkSweepThread* _cmst;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 static CMSCollector* _collector;
a61af66fc99e Initial load
duke
parents:
diff changeset
46 static SurrogateLockerThread* _slt;
a61af66fc99e Initial load
duke
parents:
diff changeset
47 static SurrogateLockerThread::SLT_msg_type _sltBuffer;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 static Monitor* _sltMonitor;
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 static bool _should_terminate;
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 enum CMS_flag_type {
a61af66fc99e Initial load
duke
parents:
diff changeset
53 CMS_nil = NoBits,
a61af66fc99e Initial load
duke
parents:
diff changeset
54 CMS_cms_wants_token = nth_bit(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
55 CMS_cms_has_token = nth_bit(1),
a61af66fc99e Initial load
duke
parents:
diff changeset
56 CMS_vm_wants_token = nth_bit(2),
a61af66fc99e Initial load
duke
parents:
diff changeset
57 CMS_vm_has_token = nth_bit(3)
a61af66fc99e Initial load
duke
parents:
diff changeset
58 };
a61af66fc99e Initial load
duke
parents:
diff changeset
59
a61af66fc99e Initial load
duke
parents:
diff changeset
60 static int _CMS_flag;
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 static bool CMS_flag_is_set(int b) { return (_CMS_flag & b) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
63 static bool set_CMS_flag(int b) { return (_CMS_flag |= b) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
64 static bool clear_CMS_flag(int b) { return (_CMS_flag &= ~b) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
65 void sleepBeforeNextCycle();
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 // CMS thread should yield for a young gen collection, direct allocation,
a61af66fc99e Initial load
duke
parents:
diff changeset
68 // and iCMS activity.
a61af66fc99e Initial load
duke
parents:
diff changeset
69 static char _pad_1[64 - sizeof(jint)]; // prevent cache-line sharing
a61af66fc99e Initial load
duke
parents:
diff changeset
70 static volatile jint _pending_yields;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 static volatile jint _pending_decrements; // decrements to _pending_yields
a61af66fc99e Initial load
duke
parents:
diff changeset
72 static char _pad_2[64 - sizeof(jint)]; // prevent cache-line sharing
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // Tracing messages, enabled by CMSTraceThreadState.
a61af66fc99e Initial load
duke
parents:
diff changeset
75 static inline void trace_state(const char* desc);
a61af66fc99e Initial load
duke
parents:
diff changeset
76
2365
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
77 static volatile int _icms_disabled; // a counter to track #iCMS disable & enable
0
a61af66fc99e Initial load
duke
parents:
diff changeset
78 static volatile bool _should_run; // iCMS may run
a61af66fc99e Initial load
duke
parents:
diff changeset
79 static volatile bool _should_stop; // iCMS should stop
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
82 void verify_ok_to_terminate() const PRODUCT_RETURN;
a61af66fc99e Initial load
duke
parents:
diff changeset
83
a61af66fc99e Initial load
duke
parents:
diff changeset
84 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // Constructor
a61af66fc99e Initial load
duke
parents:
diff changeset
86 ConcurrentMarkSweepThread(CMSCollector* collector);
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 static void makeSurrogateLockerThread(TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
89 static SurrogateLockerThread* slt() { return _slt; }
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 // Tester
a61af66fc99e Initial load
duke
parents:
diff changeset
92 bool is_ConcurrentGC_thread() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 static void threads_do(ThreadClosure* tc);
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // Printing
a61af66fc99e Initial load
duke
parents:
diff changeset
97 void print_on(outputStream* st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
98 void print() const { print_on(tty); }
a61af66fc99e Initial load
duke
parents:
diff changeset
99 static void print_all_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
100 static void print_all() { print_all_on(tty); }
a61af66fc99e Initial load
duke
parents:
diff changeset
101
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // Returns the CMS Thread
a61af66fc99e Initial load
duke
parents:
diff changeset
103 static ConcurrentMarkSweepThread* cmst() { return _cmst; }
a61af66fc99e Initial load
duke
parents:
diff changeset
104 static CMSCollector* collector() { return _collector; }
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // Create and start the CMS Thread, or stop it on shutdown
a61af66fc99e Initial load
duke
parents:
diff changeset
107 static ConcurrentMarkSweepThread* start(CMSCollector* collector);
a61af66fc99e Initial load
duke
parents:
diff changeset
108 static void stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
109 static bool should_terminate() { return _should_terminate; }
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // Synchronization using CMS token
a61af66fc99e Initial load
duke
parents:
diff changeset
112 static void synchronize(bool is_cms_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 static void desynchronize(bool is_cms_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
114 static bool vm_thread_has_cms_token() {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 return CMS_flag_is_set(CMS_vm_has_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
117 static bool cms_thread_has_cms_token() {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 return CMS_flag_is_set(CMS_cms_has_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120 static bool vm_thread_wants_cms_token() {
a61af66fc99e Initial load
duke
parents:
diff changeset
121 return CMS_flag_is_set(CMS_vm_wants_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
123 static bool cms_thread_wants_cms_token() {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 return CMS_flag_is_set(CMS_cms_wants_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
126
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // Wait on CMS lock until the next synchronous GC
1887
cd3ef3fd20dd 6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents: 1837
diff changeset
128 // or given timeout, whichever is earlier. A timeout value
cd3ef3fd20dd 6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents: 1837
diff changeset
129 // of 0 indicates that there is no upper bound on the wait time.
cd3ef3fd20dd 6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents: 1837
diff changeset
130 // A concurrent full gc request terminates the wait.
cd3ef3fd20dd 6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents: 1837
diff changeset
131 void wait_on_cms_lock(long t_millis);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
132
8679
a252e688abcf 7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents: 7180
diff changeset
133 // Wait on CMS lock until the next synchronous GC
a252e688abcf 7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents: 7180
diff changeset
134 // or given timeout, whichever is earlier. A timeout value
a252e688abcf 7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents: 7180
diff changeset
135 // of 0 indicates that there is no upper bound on the wait time.
a252e688abcf 7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents: 7180
diff changeset
136 // A concurrent full gc request terminates the wait.
a252e688abcf 7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents: 7180
diff changeset
137 void wait_on_cms_lock_for_scavenge(long t_millis);
a252e688abcf 7189971: Implement CMSWaitDuration for non-incremental mode of CMS
jmasa
parents: 7180
diff changeset
138
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
139 // The CMS thread will yield during the work portion of its cycle
0
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // only when requested to. Both synchronous and asychronous requests
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
141 // are provided:
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
142 // (1) A synchronous request is used for young gen collections and
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
143 // for direct allocations. The requesting thread increments
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
144 // _pending_yields at the beginning of an operation, and decrements
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
145 // _pending_yields when that operation is completed.
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
146 // In turn, the CMS thread yields when _pending_yields is positive,
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
147 // and continues to yield until the value reverts to 0.
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
148 // (2) An asynchronous request, on the other hand, is used by iCMS
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
149 // for the stop_icms() operation. A single yield satisfies all of
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
150 // the outstanding asynch yield requests, of which there may
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
151 // occasionally be several in close succession. To accomplish
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
152 // this, an asynch-requesting thread atomically increments both
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
153 // _pending_yields and _pending_decrements. An asynchr requesting
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
154 // thread does not wait and "acknowledge" completion of an operation
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
155 // and deregister the request, like the synchronous version described
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
156 // above does. In turn, after yielding, the CMS thread decrements both
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
157 // _pending_yields and _pending_decrements by the value seen in
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
158 // _pending_decrements before the decrement.
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
159 // NOTE: The above scheme is isomorphic to having two request counters,
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
160 // one for async requests and one for sync requests, and for the CMS thread
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
161 // to check the sum of the two counters to decide whether it should yield
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
162 // and to clear only the async counter when it yields. However, it turns out
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
163 // to be more efficient for CMS code to just check a single counter
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
164 // _pending_yields that holds the sum (of both sync and async requests), and
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
165 // a second counter _pending_decrements that only holds the async requests,
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
166 // for greater efficiency, since in a typical CMS run, there are many more
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
167 // pontential (i.e. static) yield points than there are actual
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
168 // (i.e. dynamic) yields because of requests, which are few and far between.
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
169 //
0
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // Note that, while "_pending_yields >= _pending_decrements" is an invariant,
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // we cannot easily test that invariant, since the counters are manipulated via
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // atomic instructions without explicit locking and we cannot read
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // the two counters atomically together: one suggestion is to
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // use (for example) 16-bit counters so as to be able to read the
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // two counters atomically even on 32-bit platforms. Notice that
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
176 // the second assert in acknowledge_yield_request() below does indeed
0
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // check a form of the above invariant, albeit indirectly.
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 static void increment_pending_yields() {
a61af66fc99e Initial load
duke
parents:
diff changeset
180 Atomic::inc(&_pending_yields);
a61af66fc99e Initial load
duke
parents:
diff changeset
181 assert(_pending_yields >= 0, "can't be negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183 static void decrement_pending_yields() {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 Atomic::dec(&_pending_yields);
a61af66fc99e Initial load
duke
parents:
diff changeset
185 assert(_pending_yields >= 0, "can't be negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
187 static void asynchronous_yield_request() {
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
188 assert(CMSIncrementalMode, "Currently only used w/iCMS");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
189 increment_pending_yields();
a61af66fc99e Initial load
duke
parents:
diff changeset
190 Atomic::inc(&_pending_decrements);
a61af66fc99e Initial load
duke
parents:
diff changeset
191 assert(_pending_decrements >= 0, "can't be negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
193 static void acknowledge_yield_request() {
a61af66fc99e Initial load
duke
parents:
diff changeset
194 jint decrement = _pending_decrements;
a61af66fc99e Initial load
duke
parents:
diff changeset
195 if (decrement > 0) {
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
196 assert(CMSIncrementalMode, "Currently only used w/iCMS");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // Order important to preserve: _pending_yields >= _pending_decrements
a61af66fc99e Initial load
duke
parents:
diff changeset
198 Atomic::add(-decrement, &_pending_decrements);
a61af66fc99e Initial load
duke
parents:
diff changeset
199 Atomic::add(-decrement, &_pending_yields);
a61af66fc99e Initial load
duke
parents:
diff changeset
200 assert(_pending_decrements >= 0, "can't be negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
201 assert(_pending_yields >= 0, "can't be negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204 static bool should_yield() { return _pending_yields > 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // CMS incremental mode.
a61af66fc99e Initial load
duke
parents:
diff changeset
207 static void start_icms(); // notify thread to start a quantum of work
a61af66fc99e Initial load
duke
parents:
diff changeset
208 static void stop_icms(); // request thread to stop working
a61af66fc99e Initial load
duke
parents:
diff changeset
209 void icms_wait(); // if asked to stop, wait until notified to start
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // Incremental mode is enabled globally by the flag CMSIncrementalMode. It
a61af66fc99e Initial load
duke
parents:
diff changeset
212 // must also be enabled/disabled dynamically to allow foreground collections.
2365
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
213 #define ICMS_ENABLING_ASSERT \
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
214 assert((CMSIncrementalMode && _icms_disabled >= 0) || \
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
215 (!CMSIncrementalMode && _icms_disabled <= 0), "Error")
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
216
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
217 static inline void enable_icms() {
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
218 ICMS_ENABLING_ASSERT;
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
219 Atomic::dec(&_icms_disabled);
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
220 }
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
221 static inline void disable_icms() {
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
222 ICMS_ENABLING_ASSERT;
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
223 Atomic::inc(&_icms_disabled);
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
224 }
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
225 static inline bool icms_is_disabled() {
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
226 ICMS_ENABLING_ASSERT;
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
227 return _icms_disabled > 0;
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
228 }
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
229 static inline bool icms_is_enabled() {
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
230 return !icms_is_disabled();
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
231 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
232 };
a61af66fc99e Initial load
duke
parents:
diff changeset
233
a61af66fc99e Initial load
duke
parents:
diff changeset
234 inline void ConcurrentMarkSweepThread::trace_state(const char* desc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
235 if (CMSTraceThreadState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
236 char buf[128];
a61af66fc99e Initial load
duke
parents:
diff changeset
237 TimeStamp& ts = gclog_or_tty->time_stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
238 if (!ts.is_updated()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
239 ts.update();
a61af66fc99e Initial load
duke
parents:
diff changeset
240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
241 jio_snprintf(buf, sizeof(buf), " [%.3f: CMSThread %s] ",
a61af66fc99e Initial load
duke
parents:
diff changeset
242 ts.seconds(), desc);
a61af66fc99e Initial load
duke
parents:
diff changeset
243 buf[sizeof(buf) - 1] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
244 gclog_or_tty->print(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
247
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
248 // For scoped increment/decrement of (synchronous) yield requests
0
a61af66fc99e Initial load
duke
parents:
diff changeset
249 class CMSSynchronousYieldRequest: public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
250 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
251 CMSSynchronousYieldRequest() {
a61af66fc99e Initial load
duke
parents:
diff changeset
252 ConcurrentMarkSweepThread::increment_pending_yields();
a61af66fc99e Initial load
duke
parents:
diff changeset
253 }
a61af66fc99e Initial load
duke
parents:
diff changeset
254 ~CMSSynchronousYieldRequest() {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 ConcurrentMarkSweepThread::decrement_pending_yields();
a61af66fc99e Initial load
duke
parents:
diff changeset
256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
257 };
a61af66fc99e Initial load
duke
parents:
diff changeset
258
a61af66fc99e Initial load
duke
parents:
diff changeset
259 // Used to emit a warning in case of unexpectedly excessive
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // looping (in "apparently endless loops") in CMS code.
a61af66fc99e Initial load
duke
parents:
diff changeset
261 class CMSLoopCountWarn: public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
262 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
263 const char* _src;
a61af66fc99e Initial load
duke
parents:
diff changeset
264 const char* _msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
265 const intx _threshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
266 intx _ticks;
a61af66fc99e Initial load
duke
parents:
diff changeset
267
a61af66fc99e Initial load
duke
parents:
diff changeset
268 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
269 inline CMSLoopCountWarn(const char* src, const char* msg,
a61af66fc99e Initial load
duke
parents:
diff changeset
270 const intx threshold) :
a61af66fc99e Initial load
duke
parents:
diff changeset
271 _src(src), _msg(msg), _threshold(threshold), _ticks(0) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
272
a61af66fc99e Initial load
duke
parents:
diff changeset
273 inline void tick() {
a61af66fc99e Initial load
duke
parents:
diff changeset
274 _ticks++;
a61af66fc99e Initial load
duke
parents:
diff changeset
275 if (CMSLoopWarn && _ticks % _threshold == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
276 warning("%s has looped %d times %s", _src, _ticks, _msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
279 };
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
280
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
281 #endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPTHREAD_HPP