annotate src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp @ 1951:899bbbdcb6ea

6997298: fatal error: must own lock CMS_markBitMap_lock during heap dump Summary: Since we are at a stop-world pause, the existing CMS-phase checks are sufficient for safety, and the locking check can be safely elided. Elaborated documentation comment to the case where class unloading and verification are disabled, and the query happens when we aren't in the sweeping phase, where the answer "false" would be (almost everywhere) too pessimistic. Reviewed-by: jmasa, johnc, tonyp
author ysr
date Fri, 05 Nov 2010 13:20:37 -0700
parents cd3ef3fd20dd
children f95d63e2154a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
2 * Copyright (c) 2001, 2010, 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
a61af66fc99e Initial load
duke
parents:
diff changeset
25 class ConcurrentMarkSweepGeneration;
a61af66fc99e Initial load
duke
parents:
diff changeset
26 class CMSCollector;
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 // The Concurrent Mark Sweep GC Thread (could be several in the future).
a61af66fc99e Initial load
duke
parents:
diff changeset
29 class ConcurrentMarkSweepThread: public ConcurrentGCThread {
a61af66fc99e Initial load
duke
parents:
diff changeset
30 friend class VMStructs;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 friend class ConcurrentMarkSweepGeneration; // XXX should remove friendship
a61af66fc99e Initial load
duke
parents:
diff changeset
32 friend class CMSCollector;
a61af66fc99e Initial load
duke
parents:
diff changeset
33 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
34 virtual void run();
a61af66fc99e Initial load
duke
parents:
diff changeset
35
a61af66fc99e Initial load
duke
parents:
diff changeset
36 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
37 static ConcurrentMarkSweepThread* _cmst;
a61af66fc99e Initial load
duke
parents:
diff changeset
38 static CMSCollector* _collector;
a61af66fc99e Initial load
duke
parents:
diff changeset
39 static SurrogateLockerThread* _slt;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 static SurrogateLockerThread::SLT_msg_type _sltBuffer;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 static Monitor* _sltMonitor;
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 ConcurrentMarkSweepThread* _next;
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45 static bool _should_terminate;
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 enum CMS_flag_type {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 CMS_nil = NoBits,
a61af66fc99e Initial load
duke
parents:
diff changeset
49 CMS_cms_wants_token = nth_bit(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
50 CMS_cms_has_token = nth_bit(1),
a61af66fc99e Initial load
duke
parents:
diff changeset
51 CMS_vm_wants_token = nth_bit(2),
a61af66fc99e Initial load
duke
parents:
diff changeset
52 CMS_vm_has_token = nth_bit(3)
a61af66fc99e Initial load
duke
parents:
diff changeset
53 };
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 static int _CMS_flag;
a61af66fc99e Initial load
duke
parents:
diff changeset
56
a61af66fc99e Initial load
duke
parents:
diff changeset
57 static bool CMS_flag_is_set(int b) { return (_CMS_flag & b) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
58 static bool set_CMS_flag(int b) { return (_CMS_flag |= b) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
59 static bool clear_CMS_flag(int b) { return (_CMS_flag &= ~b) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
60 void sleepBeforeNextCycle();
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // CMS thread should yield for a young gen collection, direct allocation,
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // and iCMS activity.
a61af66fc99e Initial load
duke
parents:
diff changeset
64 static char _pad_1[64 - sizeof(jint)]; // prevent cache-line sharing
a61af66fc99e Initial load
duke
parents:
diff changeset
65 static volatile jint _pending_yields;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 static volatile jint _pending_decrements; // decrements to _pending_yields
a61af66fc99e Initial load
duke
parents:
diff changeset
67 static char _pad_2[64 - sizeof(jint)]; // prevent cache-line sharing
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // Tracing messages, enabled by CMSTraceThreadState.
a61af66fc99e Initial load
duke
parents:
diff changeset
70 static inline void trace_state(const char* desc);
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 static volatile bool _icms_enabled; // iCMS enabled?
a61af66fc99e Initial load
duke
parents:
diff changeset
73 static volatile bool _should_run; // iCMS may run
a61af66fc99e Initial load
duke
parents:
diff changeset
74 static volatile bool _should_stop; // iCMS should stop
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
77 void verify_ok_to_terminate() const PRODUCT_RETURN;
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // Constructor
a61af66fc99e Initial load
duke
parents:
diff changeset
81 ConcurrentMarkSweepThread(CMSCollector* collector);
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 static void makeSurrogateLockerThread(TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
84 static SurrogateLockerThread* slt() { return _slt; }
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // Tester
a61af66fc99e Initial load
duke
parents:
diff changeset
87 bool is_ConcurrentGC_thread() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
88
a61af66fc99e Initial load
duke
parents:
diff changeset
89 static void threads_do(ThreadClosure* tc);
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 // Printing
a61af66fc99e Initial load
duke
parents:
diff changeset
92 void print_on(outputStream* st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
93 void print() const { print_on(tty); }
a61af66fc99e Initial load
duke
parents:
diff changeset
94 static void print_all_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
95 static void print_all() { print_all_on(tty); }
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // Returns the CMS Thread
a61af66fc99e Initial load
duke
parents:
diff changeset
98 static ConcurrentMarkSweepThread* cmst() { return _cmst; }
a61af66fc99e Initial load
duke
parents:
diff changeset
99 static CMSCollector* collector() { return _collector; }
a61af66fc99e Initial load
duke
parents:
diff changeset
100
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // Create and start the CMS Thread, or stop it on shutdown
a61af66fc99e Initial load
duke
parents:
diff changeset
102 static ConcurrentMarkSweepThread* start(CMSCollector* collector);
a61af66fc99e Initial load
duke
parents:
diff changeset
103 static void stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
104 static bool should_terminate() { return _should_terminate; }
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // Synchronization using CMS token
a61af66fc99e Initial load
duke
parents:
diff changeset
107 static void synchronize(bool is_cms_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
108 static void desynchronize(bool is_cms_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
109 static bool vm_thread_has_cms_token() {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 return CMS_flag_is_set(CMS_vm_has_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
112 static bool cms_thread_has_cms_token() {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 return CMS_flag_is_set(CMS_cms_has_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
115 static bool vm_thread_wants_cms_token() {
a61af66fc99e Initial load
duke
parents:
diff changeset
116 return CMS_flag_is_set(CMS_vm_wants_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118 static bool cms_thread_wants_cms_token() {
a61af66fc99e Initial load
duke
parents:
diff changeset
119 return CMS_flag_is_set(CMS_cms_wants_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // Wait on CMS lock until the next synchronous GC
1887
cd3ef3fd20dd 6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents: 1837
diff changeset
123 // or given timeout, whichever is earlier. A timeout value
cd3ef3fd20dd 6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents: 1837
diff changeset
124 // 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
125 // A concurrent full gc request terminates the wait.
cd3ef3fd20dd 6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents: 1837
diff changeset
126 void wait_on_cms_lock(long t_millis);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
127
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
128 // The CMS thread will yield during the work portion of its cycle
0
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // 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
130 // 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
131 // (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
132 // 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
133 // _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
134 // _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
135 // 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
136 // 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
137 // (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
138 // 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
139 // 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
140 // 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
141 // 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
142 // _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
143 // 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
144 // 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
145 // 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
146 // _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
147 // _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
148 // 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
149 // 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
150 // 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
151 // 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
152 // 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
153 // _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
154 // 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
155 // 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
156 // 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
157 // (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
158 //
0
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // Note that, while "_pending_yields >= _pending_decrements" is an invariant,
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // we cannot easily test that invariant, since the counters are manipulated via
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // atomic instructions without explicit locking and we cannot read
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // the two counters atomically together: one suggestion is to
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // use (for example) 16-bit counters so as to be able to read the
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // 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
165 // the second assert in acknowledge_yield_request() below does indeed
0
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // check a form of the above invariant, albeit indirectly.
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 static void increment_pending_yields() {
a61af66fc99e Initial load
duke
parents:
diff changeset
169 Atomic::inc(&_pending_yields);
a61af66fc99e Initial load
duke
parents:
diff changeset
170 assert(_pending_yields >= 0, "can't be negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
172 static void decrement_pending_yields() {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 Atomic::dec(&_pending_yields);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 assert(_pending_yields >= 0, "can't be negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
176 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
177 assert(CMSIncrementalMode, "Currently only used w/iCMS");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
178 increment_pending_yields();
a61af66fc99e Initial load
duke
parents:
diff changeset
179 Atomic::inc(&_pending_decrements);
a61af66fc99e Initial load
duke
parents:
diff changeset
180 assert(_pending_decrements >= 0, "can't be negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
182 static void acknowledge_yield_request() {
a61af66fc99e Initial load
duke
parents:
diff changeset
183 jint decrement = _pending_decrements;
a61af66fc99e Initial load
duke
parents:
diff changeset
184 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
185 assert(CMSIncrementalMode, "Currently only used w/iCMS");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // Order important to preserve: _pending_yields >= _pending_decrements
a61af66fc99e Initial load
duke
parents:
diff changeset
187 Atomic::add(-decrement, &_pending_decrements);
a61af66fc99e Initial load
duke
parents:
diff changeset
188 Atomic::add(-decrement, &_pending_yields);
a61af66fc99e Initial load
duke
parents:
diff changeset
189 assert(_pending_decrements >= 0, "can't be negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
190 assert(_pending_yields >= 0, "can't be negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
193 static bool should_yield() { return _pending_yields > 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
194
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // CMS incremental mode.
a61af66fc99e Initial load
duke
parents:
diff changeset
196 static void start_icms(); // notify thread to start a quantum of work
a61af66fc99e Initial load
duke
parents:
diff changeset
197 static void stop_icms(); // request thread to stop working
a61af66fc99e Initial load
duke
parents:
diff changeset
198 void icms_wait(); // if asked to stop, wait until notified to start
a61af66fc99e Initial load
duke
parents:
diff changeset
199
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // Incremental mode is enabled globally by the flag CMSIncrementalMode. It
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // must also be enabled/disabled dynamically to allow foreground collections.
a61af66fc99e Initial load
duke
parents:
diff changeset
202 static inline void enable_icms() { _icms_enabled = true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
203 static inline void disable_icms() { _icms_enabled = false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
204 static inline void set_icms_enabled(bool val) { _icms_enabled = val; }
a61af66fc99e Initial load
duke
parents:
diff changeset
205 static inline bool icms_enabled() { return _icms_enabled; }
a61af66fc99e Initial load
duke
parents:
diff changeset
206 };
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 inline void ConcurrentMarkSweepThread::trace_state(const char* desc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
209 if (CMSTraceThreadState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
210 char buf[128];
a61af66fc99e Initial load
duke
parents:
diff changeset
211 TimeStamp& ts = gclog_or_tty->time_stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
212 if (!ts.is_updated()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 ts.update();
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215 jio_snprintf(buf, sizeof(buf), " [%.3f: CMSThread %s] ",
a61af66fc99e Initial load
duke
parents:
diff changeset
216 ts.seconds(), desc);
a61af66fc99e Initial load
duke
parents:
diff changeset
217 buf[sizeof(buf) - 1] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
218 gclog_or_tty->print(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
222 // For scoped increment/decrement of (synchronous) yield requests
0
a61af66fc99e Initial load
duke
parents:
diff changeset
223 class CMSSynchronousYieldRequest: public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
224 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
225 CMSSynchronousYieldRequest() {
a61af66fc99e Initial load
duke
parents:
diff changeset
226 ConcurrentMarkSweepThread::increment_pending_yields();
a61af66fc99e Initial load
duke
parents:
diff changeset
227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
228 ~CMSSynchronousYieldRequest() {
a61af66fc99e Initial load
duke
parents:
diff changeset
229 ConcurrentMarkSweepThread::decrement_pending_yields();
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231 };
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 // Used to emit a warning in case of unexpectedly excessive
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // looping (in "apparently endless loops") in CMS code.
a61af66fc99e Initial load
duke
parents:
diff changeset
235 class CMSLoopCountWarn: public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
236 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
237 const char* _src;
a61af66fc99e Initial load
duke
parents:
diff changeset
238 const char* _msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
239 const intx _threshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
240 intx _ticks;
a61af66fc99e Initial load
duke
parents:
diff changeset
241
a61af66fc99e Initial load
duke
parents:
diff changeset
242 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
243 inline CMSLoopCountWarn(const char* src, const char* msg,
a61af66fc99e Initial load
duke
parents:
diff changeset
244 const intx threshold) :
a61af66fc99e Initial load
duke
parents:
diff changeset
245 _src(src), _msg(msg), _threshold(threshold), _ticks(0) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 inline void tick() {
a61af66fc99e Initial load
duke
parents:
diff changeset
248 _ticks++;
a61af66fc99e Initial load
duke
parents:
diff changeset
249 if (CMSLoopWarn && _ticks % _threshold == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
250 warning("%s has looped %d times %s", _src, _ticks, _msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
253 };