annotate src/share/vm/runtime/park.cpp @ 6972:bd7a7ce2e264

6830717: replay of compilations would help with debugging Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method. Reviewed-by: kvn, twisti, sspitsyn Contributed-by: yumin.qi@oracle.com
author minqi
date Mon, 12 Nov 2012 14:03:53 -0800
parents b9a9ed0f8eeb
children 9758d9f36299
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
1 /*
6842
b9a9ed0f8eeb 7197424: update copyright year to match last edit in jdk8 hotspot repository
mikael
parents: 6197
diff changeset
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
4 *
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
7 * published by the Free Software Foundation.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
8 *
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
13 * accompanied this code).
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
14 *
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
18 *
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
21 * questions.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
22 *
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
23 */
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1878
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1878
diff changeset
26 #include "runtime/thread.hpp"
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
27
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
28
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
29
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
30 // Lifecycle management for TSM ParkEvents.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
31 // ParkEvents are type-stable (TSM).
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
32 // In our particular implementation they happen to be immortal.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
33 //
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
34 // We manage concurrency on the FreeList with a CAS-based
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
35 // detach-modify-reattach idiom that avoids the ABA problems
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
36 // that would otherwise be present in a simple CAS-based
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
37 // push-pop implementation. (push-one and pop-all)
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
38 //
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
39 // Caveat: Allocate() and Release() may be called from threads
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
40 // other than the thread associated with the Event!
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
41 // If we need to call Allocate() when running as the thread in
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
42 // question then look for the PD calls to initialize native TLS.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
43 // Native TLS (Win32/Linux/Solaris) can only be initialized or
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
44 // accessed by the associated thread.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
45 // See also pd_initialize().
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
46 //
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
47 // Note that we could defer associating a ParkEvent with a thread
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
48 // until the 1st time the thread calls park(). unpark() calls to
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
49 // an unprovisioned thread would be ignored. The first park() call
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
50 // for a thread would allocate and associate a ParkEvent and return
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
51 // immediately.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
52
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
53 volatile int ParkEvent::ListLock = 0 ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
54 ParkEvent * volatile ParkEvent::FreeList = NULL ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
55
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
56 ParkEvent * ParkEvent::Allocate (Thread * t) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
57 // In rare cases -- JVM_RawMonitor* operations -- we can find t == null.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
58 ParkEvent * ev ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
59
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
60 // Start by trying to recycle an existing but unassociated
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
61 // ParkEvent from the global free list.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
62 for (;;) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
63 ev = FreeList ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
64 if (ev == NULL) break ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
65 // 1: Detach - sequester or privatize the list
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
66 // Tantamount to ev = Swap (&FreeList, NULL)
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
67 if (Atomic::cmpxchg_ptr (NULL, &FreeList, ev) != ev) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
68 continue ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
69 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
70
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
71 // We've detached the list. The list in-hand is now
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
72 // local to this thread. This thread can operate on the
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
73 // list without risk of interference from other threads.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
74 // 2: Extract -- pop the 1st element from the list.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
75 ParkEvent * List = ev->FreeNext ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
76 if (List == NULL) break ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
77 for (;;) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
78 // 3: Try to reattach the residual list
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
79 guarantee (List != NULL, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
80 ParkEvent * Arv = (ParkEvent *) Atomic::cmpxchg_ptr (List, &FreeList, NULL) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
81 if (Arv == NULL) break ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
82
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
83 // New nodes arrived. Try to detach the recent arrivals.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
84 if (Atomic::cmpxchg_ptr (NULL, &FreeList, Arv) != Arv) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
85 continue ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
86 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
87 guarantee (Arv != NULL, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
88 // 4: Merge Arv into List
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
89 ParkEvent * Tail = List ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
90 while (Tail->FreeNext != NULL) Tail = Tail->FreeNext ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
91 Tail->FreeNext = Arv ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
92 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
93 break ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
94 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
95
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
96 if (ev != NULL) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
97 guarantee (ev->AssociatedWith == NULL, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
98 } else {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
99 // Do this the hard way -- materialize a new ParkEvent.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
100 // In rare cases an allocating thread might detach a long list --
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
101 // installing null into FreeList -- and then stall or be obstructed.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
102 // A 2nd thread calling Allocate() would see FreeList == null.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
103 // The list held privately by the 1st thread is unavailable to the 2nd thread.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
104 // In that case the 2nd thread would have to materialize a new ParkEvent,
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
105 // even though free ParkEvents existed in the system. In this case we end up
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
106 // with more ParkEvents in circulation than we need, but the race is
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
107 // rare and the outcome is benign. Ideally, the # of extant ParkEvents
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
108 // is equal to the maximum # of threads that existed at any one time.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
109 // Because of the race mentioned above, segments of the freelist
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
110 // can be transiently inaccessible. At worst we may end up with the
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
111 // # of ParkEvents in circulation slightly above the ideal.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
112 // Note that if we didn't have the TSM/immortal constraint, then
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
113 // when reattaching, above, we could trim the list.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
114 ev = new ParkEvent () ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
115 guarantee ((intptr_t(ev) & 0xFF) == 0, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
116 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
117 ev->reset() ; // courtesy to caller
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
118 ev->AssociatedWith = t ; // Associate ev with t
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
119 ev->FreeNext = NULL ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
120 return ev ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
121 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
122
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
123 void ParkEvent::Release (ParkEvent * ev) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
124 if (ev == NULL) return ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
125 guarantee (ev->FreeNext == NULL , "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
126 ev->AssociatedWith = NULL ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
127 for (;;) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
128 // Push ev onto FreeList
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
129 // The mechanism is "half" lock-free.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
130 ParkEvent * List = FreeList ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
131 ev->FreeNext = List ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
132 if (Atomic::cmpxchg_ptr (ev, &FreeList, List) == List) break ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
133 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
134 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
135
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
136 // Override operator new and delete so we can ensure that the
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
137 // least significant byte of ParkEvent addresses is 0.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
138 // Beware that excessive address alignment is undesirable
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
139 // as it can result in D$ index usage imbalance as
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
140 // well as bank access imbalance on Niagara-like platforms,
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
141 // although Niagara's hash function should help.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
142
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
143 void * ParkEvent::operator new (size_t sz) {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 1972
diff changeset
144 return (void *) ((intptr_t (AllocateHeap(sz + 256, mtInternal, CALLER_PC)) + 256) & -256) ;
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
145 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
146
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
147 void ParkEvent::operator delete (void * a) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
148 // ParkEvents are type-stable and immortal ...
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
149 ShouldNotReachHere();
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
150 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
151
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
152
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
153 // 6399321 As a temporary measure we copied & modified the ParkEvent::
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
154 // allocate() and release() code for use by Parkers. The Parker:: forms
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
155 // will eventually be removed as we consolide and shift over to ParkEvents
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
156 // for both builtin synchronization and JSR166 operations.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
157
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
158 volatile int Parker::ListLock = 0 ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
159 Parker * volatile Parker::FreeList = NULL ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
160
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
161 Parker * Parker::Allocate (JavaThread * t) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
162 guarantee (t != NULL, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
163 Parker * p ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
164
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
165 // Start by trying to recycle an existing but unassociated
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
166 // Parker from the global free list.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
167 for (;;) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
168 p = FreeList ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
169 if (p == NULL) break ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
170 // 1: Detach
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
171 // Tantamount to p = Swap (&FreeList, NULL)
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
172 if (Atomic::cmpxchg_ptr (NULL, &FreeList, p) != p) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
173 continue ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
174 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
175
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
176 // We've detached the list. The list in-hand is now
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
177 // local to this thread. This thread can operate on the
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
178 // list without risk of interference from other threads.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
179 // 2: Extract -- pop the 1st element from the list.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
180 Parker * List = p->FreeNext ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
181 if (List == NULL) break ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
182 for (;;) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
183 // 3: Try to reattach the residual list
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
184 guarantee (List != NULL, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
185 Parker * Arv = (Parker *) Atomic::cmpxchg_ptr (List, &FreeList, NULL) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
186 if (Arv == NULL) break ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
187
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
188 // New nodes arrived. Try to detach the recent arrivals.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
189 if (Atomic::cmpxchg_ptr (NULL, &FreeList, Arv) != Arv) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
190 continue ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
191 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
192 guarantee (Arv != NULL, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
193 // 4: Merge Arv into List
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
194 Parker * Tail = List ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
195 while (Tail->FreeNext != NULL) Tail = Tail->FreeNext ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
196 Tail->FreeNext = Arv ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
197 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
198 break ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
199 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
200
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
201 if (p != NULL) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
202 guarantee (p->AssociatedWith == NULL, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
203 } else {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
204 // Do this the hard way -- materialize a new Parker..
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
205 // In rare cases an allocating thread might detach
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
206 // a long list -- installing null into FreeList --and
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
207 // then stall. Another thread calling Allocate() would see
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
208 // FreeList == null and then invoke the ctor. In this case we
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
209 // end up with more Parkers in circulation than we need, but
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
210 // the race is rare and the outcome is benign.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
211 // Ideally, the # of extant Parkers is equal to the
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
212 // maximum # of threads that existed at any one time.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
213 // Because of the race mentioned above, segments of the
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
214 // freelist can be transiently inaccessible. At worst
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
215 // we may end up with the # of Parkers in circulation
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
216 // slightly above the ideal.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
217 p = new Parker() ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
218 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
219 p->AssociatedWith = t ; // Associate p with t
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
220 p->FreeNext = NULL ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
221 return p ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
222 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
223
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
224
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
225 void Parker::Release (Parker * p) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
226 if (p == NULL) return ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
227 guarantee (p->AssociatedWith != NULL, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
228 guarantee (p->FreeNext == NULL , "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
229 p->AssociatedWith = NULL ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
230 for (;;) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
231 // Push p onto FreeList
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
232 Parker * List = FreeList ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
233 p->FreeNext = List ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
234 if (Atomic::cmpxchg_ptr (p, &FreeList, List) == List) break ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
235 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
236 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
237