annotate src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp @ 6862:8a5ea0a9ccc4

7127708: G1: change task num types from int to uint in concurrent mark Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich. Reviewed-by: johnc Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author johnc
date Sat, 06 Oct 2012 01:17:44 -0700
parents f08d439fab8c
children f34d701e952e
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"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
30 #ifdef TARGET_OS_FAMILY_linux
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
31 # include "thread_linux.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
32 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
33 #ifdef TARGET_OS_FAMILY_solaris
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
34 # include "thread_solaris.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
35 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
36 #ifdef TARGET_OS_FAMILY_windows
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
37 # include "thread_windows.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
38 #endif
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents: 2365
diff changeset
39 #ifdef TARGET_OS_FAMILY_bsd
f08d439fab8c 7089790: integrate bsd-port changes
never
parents: 2365
diff changeset
40 # include "thread_bsd.inline.hpp"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents: 2365
diff changeset
41 #endif
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
42
0
a61af66fc99e Initial load
duke
parents:
diff changeset
43 class ConcurrentMarkSweepGeneration;
a61af66fc99e Initial load
duke
parents:
diff changeset
44 class CMSCollector;
a61af66fc99e Initial load
duke
parents:
diff changeset
45
2365
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
46 // The Concurrent Mark Sweep GC Thread
0
a61af66fc99e Initial load
duke
parents:
diff changeset
47 class ConcurrentMarkSweepThread: public ConcurrentGCThread {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 friend class VMStructs;
a61af66fc99e Initial load
duke
parents:
diff changeset
49 friend class ConcurrentMarkSweepGeneration; // XXX should remove friendship
a61af66fc99e Initial load
duke
parents:
diff changeset
50 friend class CMSCollector;
a61af66fc99e Initial load
duke
parents:
diff changeset
51 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
52 virtual void run();
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
55 static ConcurrentMarkSweepThread* _cmst;
a61af66fc99e Initial load
duke
parents:
diff changeset
56 static CMSCollector* _collector;
a61af66fc99e Initial load
duke
parents:
diff changeset
57 static SurrogateLockerThread* _slt;
a61af66fc99e Initial load
duke
parents:
diff changeset
58 static SurrogateLockerThread::SLT_msg_type _sltBuffer;
a61af66fc99e Initial load
duke
parents:
diff changeset
59 static Monitor* _sltMonitor;
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 static bool _should_terminate;
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63 enum CMS_flag_type {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 CMS_nil = NoBits,
a61af66fc99e Initial load
duke
parents:
diff changeset
65 CMS_cms_wants_token = nth_bit(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
66 CMS_cms_has_token = nth_bit(1),
a61af66fc99e Initial load
duke
parents:
diff changeset
67 CMS_vm_wants_token = nth_bit(2),
a61af66fc99e Initial load
duke
parents:
diff changeset
68 CMS_vm_has_token = nth_bit(3)
a61af66fc99e Initial load
duke
parents:
diff changeset
69 };
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 static int _CMS_flag;
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 static bool CMS_flag_is_set(int b) { return (_CMS_flag & b) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
74 static bool set_CMS_flag(int b) { return (_CMS_flag |= b) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
75 static bool clear_CMS_flag(int b) { return (_CMS_flag &= ~b) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
76 void sleepBeforeNextCycle();
a61af66fc99e Initial load
duke
parents:
diff changeset
77
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // CMS thread should yield for a young gen collection, direct allocation,
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // and iCMS activity.
a61af66fc99e Initial load
duke
parents:
diff changeset
80 static char _pad_1[64 - sizeof(jint)]; // prevent cache-line sharing
a61af66fc99e Initial load
duke
parents:
diff changeset
81 static volatile jint _pending_yields;
a61af66fc99e Initial load
duke
parents:
diff changeset
82 static volatile jint _pending_decrements; // decrements to _pending_yields
a61af66fc99e Initial load
duke
parents:
diff changeset
83 static char _pad_2[64 - sizeof(jint)]; // prevent cache-line sharing
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // Tracing messages, enabled by CMSTraceThreadState.
a61af66fc99e Initial load
duke
parents:
diff changeset
86 static inline void trace_state(const char* desc);
a61af66fc99e Initial load
duke
parents:
diff changeset
87
2365
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
88 static volatile int _icms_disabled; // a counter to track #iCMS disable & enable
0
a61af66fc99e Initial load
duke
parents:
diff changeset
89 static volatile bool _should_run; // iCMS may run
a61af66fc99e Initial load
duke
parents:
diff changeset
90 static volatile bool _should_stop; // iCMS should stop
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
93 void verify_ok_to_terminate() const PRODUCT_RETURN;
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // Constructor
a61af66fc99e Initial load
duke
parents:
diff changeset
97 ConcurrentMarkSweepThread(CMSCollector* collector);
a61af66fc99e Initial load
duke
parents:
diff changeset
98
a61af66fc99e Initial load
duke
parents:
diff changeset
99 static void makeSurrogateLockerThread(TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
100 static SurrogateLockerThread* slt() { return _slt; }
a61af66fc99e Initial load
duke
parents:
diff changeset
101
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // Tester
a61af66fc99e Initial load
duke
parents:
diff changeset
103 bool is_ConcurrentGC_thread() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
104
a61af66fc99e Initial load
duke
parents:
diff changeset
105 static void threads_do(ThreadClosure* tc);
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 // Printing
a61af66fc99e Initial load
duke
parents:
diff changeset
108 void print_on(outputStream* st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
109 void print() const { print_on(tty); }
a61af66fc99e Initial load
duke
parents:
diff changeset
110 static void print_all_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
111 static void print_all() { print_all_on(tty); }
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // Returns the CMS Thread
a61af66fc99e Initial load
duke
parents:
diff changeset
114 static ConcurrentMarkSweepThread* cmst() { return _cmst; }
a61af66fc99e Initial load
duke
parents:
diff changeset
115 static CMSCollector* collector() { return _collector; }
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // Create and start the CMS Thread, or stop it on shutdown
a61af66fc99e Initial load
duke
parents:
diff changeset
118 static ConcurrentMarkSweepThread* start(CMSCollector* collector);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 static void stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
120 static bool should_terminate() { return _should_terminate; }
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // Synchronization using CMS token
a61af66fc99e Initial load
duke
parents:
diff changeset
123 static void synchronize(bool is_cms_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
124 static void desynchronize(bool is_cms_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
125 static bool vm_thread_has_cms_token() {
a61af66fc99e Initial load
duke
parents:
diff changeset
126 return CMS_flag_is_set(CMS_vm_has_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128 static bool cms_thread_has_cms_token() {
a61af66fc99e Initial load
duke
parents:
diff changeset
129 return CMS_flag_is_set(CMS_cms_has_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
131 static bool vm_thread_wants_cms_token() {
a61af66fc99e Initial load
duke
parents:
diff changeset
132 return CMS_flag_is_set(CMS_vm_wants_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
134 static bool cms_thread_wants_cms_token() {
a61af66fc99e Initial load
duke
parents:
diff changeset
135 return CMS_flag_is_set(CMS_cms_wants_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // Wait on CMS lock until the next synchronous GC
1887
cd3ef3fd20dd 6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents: 1837
diff changeset
139 // or given timeout, whichever is earlier. A timeout value
cd3ef3fd20dd 6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents: 1837
diff changeset
140 // 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
141 // A concurrent full gc request terminates the wait.
cd3ef3fd20dd 6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents: 1837
diff changeset
142 void wait_on_cms_lock(long t_millis);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
143
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
144 // The CMS thread will yield during the work portion of its cycle
0
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // 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
146 // 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
147 // (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
148 // 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
149 // _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
150 // _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
151 // 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
152 // 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
153 // (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
154 // 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
155 // 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
156 // 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
157 // 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
158 // _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
159 // 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
160 // 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
161 // 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
162 // _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
163 // _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
164 // 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
165 // 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
166 // 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
167 // 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
168 // 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
169 // _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
170 // 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
171 // 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
172 // 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
173 // (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
174 //
0
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // Note that, while "_pending_yields >= _pending_decrements" is an invariant,
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // we cannot easily test that invariant, since the counters are manipulated via
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // atomic instructions without explicit locking and we cannot read
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // the two counters atomically together: one suggestion is to
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // use (for example) 16-bit counters so as to be able to read the
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // 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
181 // the second assert in acknowledge_yield_request() below does indeed
0
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // check a form of the above invariant, albeit indirectly.
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 static void increment_pending_yields() {
a61af66fc99e Initial load
duke
parents:
diff changeset
185 Atomic::inc(&_pending_yields);
a61af66fc99e Initial load
duke
parents:
diff changeset
186 assert(_pending_yields >= 0, "can't be negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
188 static void decrement_pending_yields() {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 Atomic::dec(&_pending_yields);
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 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
193 assert(CMSIncrementalMode, "Currently only used w/iCMS");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
194 increment_pending_yields();
a61af66fc99e Initial load
duke
parents:
diff changeset
195 Atomic::inc(&_pending_decrements);
a61af66fc99e Initial load
duke
parents:
diff changeset
196 assert(_pending_decrements >= 0, "can't be negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
198 static void acknowledge_yield_request() {
a61af66fc99e Initial load
duke
parents:
diff changeset
199 jint decrement = _pending_decrements;
a61af66fc99e Initial load
duke
parents:
diff changeset
200 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
201 assert(CMSIncrementalMode, "Currently only used w/iCMS");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // Order important to preserve: _pending_yields >= _pending_decrements
a61af66fc99e Initial load
duke
parents:
diff changeset
203 Atomic::add(-decrement, &_pending_decrements);
a61af66fc99e Initial load
duke
parents:
diff changeset
204 Atomic::add(-decrement, &_pending_yields);
a61af66fc99e Initial load
duke
parents:
diff changeset
205 assert(_pending_decrements >= 0, "can't be negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
206 assert(_pending_yields >= 0, "can't be negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
209 static bool should_yield() { return _pending_yields > 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // CMS incremental mode.
a61af66fc99e Initial load
duke
parents:
diff changeset
212 static void start_icms(); // notify thread to start a quantum of work
a61af66fc99e Initial load
duke
parents:
diff changeset
213 static void stop_icms(); // request thread to stop working
a61af66fc99e Initial load
duke
parents:
diff changeset
214 void icms_wait(); // if asked to stop, wait until notified to start
a61af66fc99e Initial load
duke
parents:
diff changeset
215
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // Incremental mode is enabled globally by the flag CMSIncrementalMode. It
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // 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
218 #define ICMS_ENABLING_ASSERT \
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
219 assert((CMSIncrementalMode && _icms_disabled >= 0) || \
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
220 (!CMSIncrementalMode && _icms_disabled <= 0), "Error")
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
221
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
222 static inline void enable_icms() {
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
223 ICMS_ENABLING_ASSERT;
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
224 Atomic::dec(&_icms_disabled);
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
225 }
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
226 static inline void disable_icms() {
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
227 ICMS_ENABLING_ASSERT;
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
228 Atomic::inc(&_icms_disabled);
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
229 }
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
230 static inline bool icms_is_disabled() {
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
231 ICMS_ENABLING_ASSERT;
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
232 return _icms_disabled > 0;
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
233 }
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
234 static inline bool icms_is_enabled() {
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
235 return !icms_is_disabled();
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
236 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
237 };
a61af66fc99e Initial load
duke
parents:
diff changeset
238
a61af66fc99e Initial load
duke
parents:
diff changeset
239 inline void ConcurrentMarkSweepThread::trace_state(const char* desc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 if (CMSTraceThreadState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
241 char buf[128];
a61af66fc99e Initial load
duke
parents:
diff changeset
242 TimeStamp& ts = gclog_or_tty->time_stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
243 if (!ts.is_updated()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
244 ts.update();
a61af66fc99e Initial load
duke
parents:
diff changeset
245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
246 jio_snprintf(buf, sizeof(buf), " [%.3f: CMSThread %s] ",
a61af66fc99e Initial load
duke
parents:
diff changeset
247 ts.seconds(), desc);
a61af66fc99e Initial load
duke
parents:
diff changeset
248 buf[sizeof(buf) - 1] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
249 gclog_or_tty->print(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1552
diff changeset
253 // For scoped increment/decrement of (synchronous) yield requests
0
a61af66fc99e Initial load
duke
parents:
diff changeset
254 class CMSSynchronousYieldRequest: public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
256 CMSSynchronousYieldRequest() {
a61af66fc99e Initial load
duke
parents:
diff changeset
257 ConcurrentMarkSweepThread::increment_pending_yields();
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259 ~CMSSynchronousYieldRequest() {
a61af66fc99e Initial load
duke
parents:
diff changeset
260 ConcurrentMarkSweepThread::decrement_pending_yields();
a61af66fc99e Initial load
duke
parents:
diff changeset
261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
262 };
a61af66fc99e Initial load
duke
parents:
diff changeset
263
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // Used to emit a warning in case of unexpectedly excessive
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // looping (in "apparently endless loops") in CMS code.
a61af66fc99e Initial load
duke
parents:
diff changeset
266 class CMSLoopCountWarn: public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
267 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
268 const char* _src;
a61af66fc99e Initial load
duke
parents:
diff changeset
269 const char* _msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
270 const intx _threshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
271 intx _ticks;
a61af66fc99e Initial load
duke
parents:
diff changeset
272
a61af66fc99e Initial load
duke
parents:
diff changeset
273 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
274 inline CMSLoopCountWarn(const char* src, const char* msg,
a61af66fc99e Initial load
duke
parents:
diff changeset
275 const intx threshold) :
a61af66fc99e Initial load
duke
parents:
diff changeset
276 _src(src), _msg(msg), _threshold(threshold), _ticks(0) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 inline void tick() {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 _ticks++;
a61af66fc99e Initial load
duke
parents:
diff changeset
280 if (CMSLoopWarn && _ticks % _threshold == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 warning("%s has looped %d times %s", _src, _ticks, _msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
284 };
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
285
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1887
diff changeset
286 #endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPTHREAD_HPP