comparison src/main/gov/nasa/jpf/vm/AllRunnablesSyncPolicy.java @ 0:61d41facf527

initial v8 import (history reset)
author Peter Mehlitz <Peter.C.Mehlitz@nasa.gov>
date Fri, 23 Jan 2015 10:14:01 -0800
parents
children 87e9c7544a06
comparison
equal deleted inserted replaced
-1:000000000000 0:61d41facf527
1 /*
2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
4 * All rights reserved.
5 *
6 * The Java Pathfinder core (jpf-core) platform is licensed under the
7 * Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0.
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package gov.nasa.jpf.vm;
20
21 import gov.nasa.jpf.Config;
22 import gov.nasa.jpf.vm.choice.ThreadChoiceFromSet;
23
24 /**
25 * a Scheduler implementation base class that allows filtering of runnable threads and
26 * implements SyncPolicy without backtracking or empty transitions, i.e. choice sets that
27 * include all runnable threads
28 */
29 public class AllRunnablesSyncPolicy implements SyncPolicy {
30
31 protected VM vm;
32 protected boolean breakSingleChoice;
33 protected boolean breakLockRelease;
34 protected boolean breakNotify;
35 protected boolean breakSleep;
36 protected boolean breakYield;
37 protected boolean breakPriority;
38
39 public AllRunnablesSyncPolicy (Config config){
40 breakSingleChoice = config.getBoolean("cg.break_single_choice", false);
41 breakLockRelease = config.getBoolean("cg.break_lock_release", true);
42 breakNotify = config.getBoolean("cg.break_notify", true);
43 breakSleep = config.getBoolean("cg.break_sleep", true);
44 breakYield = config.getBoolean("cg.break_yield", true);
45 breakPriority = config.getBoolean("cg.break_priority", true);
46 }
47
48
49 //--- internal methods
50
51 /**
52 * this is the main policy method that can be overridden by subclasses, e.g. by filtering
53 * out the highest priority runnables, or by ordering according to priority
54 *
55 * Default behavior is to first try to find runnables within the provided ApplicationContext,
56 * and fall back to any runnable if there are none in this context
57 *
58 * this includes threads that are in operations that can timeout
59 */
60 protected ThreadInfo[] getTimeoutRunnables (ApplicationContext appCtx){
61 ThreadList tlist = vm.getThreadList();
62
63 if (tlist.hasProcessTimeoutRunnables(appCtx)){
64 return tlist.getProcessTimeoutRunnables(appCtx);
65 } else {
66 return tlist.getTimeoutRunnables();
67 }
68 }
69
70
71 protected ChoiceGenerator<ThreadInfo> getRunnableCG (String id, ThreadInfo tiCurrent){
72 ThreadInfo[] choices = getTimeoutRunnables(tiCurrent.getApplicationContext());
73
74 if (choices.length == 0){
75 return null;
76 }
77
78 if ((choices.length == 1) && (choices[0] == tiCurrent) && !tiCurrent.isTimeoutWaiting()){ // no context switch
79 if (!breakSingleChoice){
80 return null;
81 }
82 }
83
84 return new ThreadChoiceFromSet( id, choices, true);
85 }
86
87 protected boolean setNextChoiceGenerator (ChoiceGenerator<ThreadInfo> cg){
88 if (cg != null){
89 return vm.getSystemState().setNextChoiceGenerator(cg); // listeners could still remove CGs
90 } else {
91 return false;
92 }
93 }
94
95 /**
96 * set a runnable CG that is optional if we are in a atomic section
97 */
98 protected boolean setNonBlockingCG (String id, ThreadInfo tiCurrent){
99 if (!tiCurrent.isFirstStepInsn() || tiCurrent.isEmptyTransitionEnabled()) {
100 if (vm.getSystemState().isAtomic()) {
101 return false;
102 } else {
103 return setNextChoiceGenerator(getRunnableCG(id, tiCurrent));
104 }
105
106 } else {
107 return false; // no empty transitions
108 }
109 }
110
111 protected static ChoiceGenerator<ThreadInfo> blockedWithoutChoice =
112 new ThreadChoiceFromSet("BLOCKED_NO_CHOICE", new ThreadInfo[0], true);
113
114 /**
115 * set a runnable CG that would break a atomic section because it requires
116 * a context switch
117 */
118 protected boolean setBlockingCG (String id, ThreadInfo tiCurrent){
119 if (!tiCurrent.isFirstStepInsn() || tiCurrent.isEmptyTransitionEnabled()) {
120 if (vm.getSystemState().isAtomic()) {
121 vm.getSystemState().setBlockedInAtomicSection();
122 }
123
124 ChoiceGenerator<ThreadInfo> cg = getRunnableCG(id, tiCurrent);
125 if (cg == null){ // make sure we don't mask a deadlock
126 if (vm.getThreadList().hasLiveThreads()){
127 cg = blockedWithoutChoice;
128 }
129 }
130
131 return setNextChoiceGenerator(cg);
132
133 } else {
134 return false; // no empty transitions
135 }
136 }
137
138 /**
139 * set a runnable CG that only breaks a atomic section if the blocking thread
140 * is the currently executing one
141 */
142 protected boolean setMaybeBlockingCG (String id, ThreadInfo tiCurrent, ThreadInfo tiBlock){
143 if (tiCurrent == tiBlock){
144 return setBlockingCG( id, tiCurrent);
145 } else {
146 return setNonBlockingCG( id, tiCurrent);
147 }
148 }
149
150
151 //--- SyncPolicy interface
152
153 //--- initialization
154 @Override
155 public void initializeSyncPolicy (VM vm, ApplicationContext appCtx){
156 this.vm = vm;
157 }
158
159 @Override
160 public void initializeThreadSync (ThreadInfo tiCurrent, ThreadInfo tiNew){
161 }
162
163 //--- locks
164 @Override
165 public boolean setsBlockedThreadCG (ThreadInfo ti, ElementInfo ei){
166 return setBlockingCG( BLOCK, ti);
167 }
168
169 @Override
170 public boolean setsLockAcquisitionCG (ThreadInfo ti, ElementInfo ei){
171 return setNonBlockingCG( LOCK, ti);
172 }
173
174 @Override
175 public boolean setsLockReleaseCG (ThreadInfo ti, ElementInfo ei, boolean didUnblock){
176 if (breakLockRelease){
177 if (didUnblock){
178 return setNonBlockingCG( RELEASE, ti);
179 }
180 }
181
182 return false;
183 }
184
185 //--- thread termination
186 @Override
187 public boolean setsTerminationCG (ThreadInfo ti){
188 return setBlockingCG( TERMINATE, ti);
189 }
190
191 //--- java.lang.Object APIs
192 @Override
193 public boolean setsWaitCG (ThreadInfo ti, long timeout){
194 return setBlockingCG( WAIT, ti);
195 }
196
197 @Override
198 public boolean setsNotifyCG (ThreadInfo ti, boolean didNotify){
199 if (breakNotify){
200 if (didNotify){
201 return setNonBlockingCG( NOTIFY, ti);
202 }
203 }
204
205 return false;
206 }
207
208 @Override
209 public boolean setsNotifyAllCG (ThreadInfo ti, boolean didNotify){
210 if (breakNotify){
211 if (didNotify){
212 return setNonBlockingCG( NOTIFYALL, ti);
213 }
214 }
215
216 return false;
217 }
218
219
220 //--- the java.lang.Thread APIs
221 @Override
222 public boolean setsStartCG (ThreadInfo tiCurrent, ThreadInfo tiStarted){
223 return setNonBlockingCG( START, tiCurrent);
224 }
225
226 @Override
227 public boolean setsYieldCG (ThreadInfo ti){
228 if (breakYield){
229 return setNonBlockingCG( YIELD, ti);
230 } else {
231 return false;
232 }
233 }
234
235 @Override
236 public boolean setsPriorityCG (ThreadInfo ti){
237 if (breakPriority){
238 return setNonBlockingCG( PRIORITY, ti);
239 } else {
240 return false;
241 }
242 }
243
244 @Override
245 public boolean setsSleepCG (ThreadInfo ti, long millis, int nanos){
246 if (breakSleep){
247 return setNonBlockingCG( SLEEP, ti);
248 } else {
249 return false;
250 }
251 }
252
253 @Override
254 public boolean setsSuspendCG (ThreadInfo tiCurrent, ThreadInfo tiSuspended){
255 return setMaybeBlockingCG( SUSPEND, tiCurrent, tiSuspended);
256 }
257
258 @Override
259 public boolean setsResumeCG (ThreadInfo tiCurrent, ThreadInfo tiResumed){
260 return setNonBlockingCG( RESUME, tiCurrent);
261 }
262
263 @Override
264 public boolean setsJoinCG (ThreadInfo tiCurrent, ThreadInfo tiJoin, long timeout){
265 return setBlockingCG( JOIN, tiCurrent);
266 }
267
268 @Override
269 public boolean setsStopCG (ThreadInfo tiCurrent, ThreadInfo tiStopped){
270 return setMaybeBlockingCG( STOP, tiCurrent, tiStopped);
271 }
272
273 @Override
274 public boolean setsInterruptCG (ThreadInfo tiCurrent, ThreadInfo tiInterrupted){
275 if (tiInterrupted.isWaiting()){
276 return setNonBlockingCG( INTERRUPT, tiCurrent);
277 } else {
278 return false;
279 }
280 }
281
282
283 //--- sun.misc.Unsafe
284 @Override
285 public boolean setsParkCG (ThreadInfo ti, boolean isAbsTime, long timeout){
286 return setBlockingCG( PARK, ti);
287 }
288
289 @Override
290 public boolean setsUnparkCG (ThreadInfo tiCurrent, ThreadInfo tiUnparked){
291 // if the unparked thread is not blocked there is no point
292 if (tiUnparked.isBlocked()){
293 return setNonBlockingCG( UNPARK, tiCurrent);
294 } else {
295 return false;
296 }
297 }
298
299
300 //--- system scheduling events
301
302 /**
303 * this one has to be guaranteed to set a CG
304 */
305 @Override
306 public void setRootCG (){
307 ThreadInfo[] runnables = vm.getThreadList().getTimeoutRunnables();
308 ChoiceGenerator<ThreadInfo> cg = new ThreadChoiceFromSet( ROOT, runnables, true);
309 vm.getSystemState().setMandatoryNextChoiceGenerator( cg, "no ROOT choice generator");
310 }
311
312
313 //--- gov.nasa.jpf.vm.Verify
314 @Override
315 public boolean setsBeginAtomicCG (ThreadInfo ti){
316 return setNonBlockingCG( BEGIN_ATOMIC, ti);
317 }
318
319 @Override
320 public boolean setsEndAtomicCG (ThreadInfo ti){
321 return setNonBlockingCG( END_ATOMIC, ti);
322 }
323
324 //--- ThreadInfo reschedule request
325 @Override
326 public boolean setsRescheduleCG (ThreadInfo ti, String reason){
327 return setNonBlockingCG( reason, ti);
328 }
329
330 //--- FinalizerThread
331 @Override
332 public boolean setsPostFinalizeCG (ThreadInfo tiFinalizer){
333 // the finalizer is already waiting at this point, i.e. it's not runnable anymore
334 return setBlockingCG( POST_FINALIZE, tiFinalizer);
335 }
336
337
338 }