comparison src/tests/gov/nasa/jpf/test/mc/basic/SharedPropagationTest.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
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.test.mc.basic;
20
21 import gov.nasa.jpf.util.test.TestJPF;
22 import org.junit.Test;
23
24 /**
25 * various shared object propagations that could lead to missed paths
26 */
27 public class SharedPropagationTest extends TestJPF {
28
29 static class Gotcha extends RuntimeException {
30 // nothing in here
31 }
32
33 //--- simple local ref
34
35 static class T1 extends Thread {
36
37 static class X {
38
39 boolean pass;
40 }
41 X myX; // initially not set
42
43 public static void main(String[] args) {
44 T1 t = new T1();
45 t.start();
46
47 X x = new X();
48 t.myX = x; // (0) x not shared until this GOT executed
49
50 //Thread.yield(); // this would expose the error
51 x.pass = true; // (1) need to break BEFORE assignment or no error
52 }
53
54 @Override
55 public void run() {
56 if (myX != null) {
57 if (!myX.pass) { // (2) won't fail unless main is between (0) and (1)
58 throw new Gotcha();
59 }
60 }
61 }
62 }
63
64 @Test
65 public void testLocalRef(){
66 if (verifyUnhandledException( Gotcha.class.getName(), "+vm.scheduler.sharedness.class=.vm.GlobalSharednessPolicy")){
67 T1.main(new String[0]);
68 }
69 }
70
71
72 //--- one reference level down
73
74 static class T2 extends Thread {
75
76 static class X {
77 boolean pass;
78 }
79
80 static class Y {
81 X x;
82 }
83
84 Y y;
85
86 public static void main(String[] args) {
87 T2 t = new T2();
88 Y y = new Y();
89 X x = new X();
90
91 y.x = x;
92 // neither x nor y shared at this point
93
94 t.start();
95 t.y = y; // y becomes shared, and with it x
96
97 x.pass = true;
98 }
99
100 @Override
101 public void run() {
102 if (y != null) {
103 if (!y.x.pass) {
104 throw new Gotcha();
105 }
106 }
107 }
108 }
109
110 @Test
111 public void testLevel1Ref(){
112 if (verifyUnhandledException(Gotcha.class.getName())){
113 T2.main(new String[0]);
114 }
115 }
116
117 //--- propagation via static field
118
119 static class T3 extends Thread {
120
121 static class X {
122 boolean pass;
123 }
124
125 static class Y {
126 X x;
127 }
128 static Y globalY; // initially not set
129
130
131 public static void main(String[] args) {
132 T3 t = new T3();
133 t.start();
134
135 X x = new X();
136 Y y = new Y();
137 y.x = x;
138
139 globalY = y; // (0) x not shared until this GOT executed
140
141 //Thread.yield(); // this would expose the error
142 x.pass = true; // (1) need to break BEFORE assignment or no error
143 }
144
145 @Override
146 public void run() {
147 if (globalY != null) {
148 if (!globalY.x.pass) { // (2) won't fail unless main is between (0) and (1)
149 throw new Gotcha();
150 }
151 }
152 }
153 }
154
155 @Test
156 public void testStaticFieldPropagation(){
157 if (verifyUnhandledException(Gotcha.class.getName(), "+vm.scheduler.sharedness.class=.vm.GlobalSharednessPolicy")){
158 T3.main(new String[0]);
159 }
160 }
161
162
163 //--- the infamous Hyber example
164
165 static class Hyber {
166 private static Timeout thread = new Timeout();
167
168 public static void main(String[] args) {
169 thread.start();
170 Timeout.Entry timer = thread.setTimeout(); // (0)
171 //Thread.yield(); // this forces the error
172 timer.hyber = true; // (1) we need to break here to catch the error
173 }
174 }
175
176 static class Timeout extends Thread {
177
178 static class Entry {
179 boolean hyber = false;
180 Entry next = null;
181 Entry prev = null;
182 }
183 Entry e = new Entry();
184
185 Timeout() {
186 e.next = e.prev = e;
187 }
188
189 public Entry setTimeout() {
190 Entry entry = new Entry();
191 synchronized (e) {
192 entry.next = e;
193 entry.prev = e.prev;
194 entry.prev.next = entry;
195 entry.next.prev = entry;
196 }
197
198 return entry;
199 }
200
201 @Override
202 public void run() {
203 synchronized (e) {
204 for (Entry entry = e.next; entry != e; entry = entry.next) {
205 if (!entry.hyber) { // (2) only fails if main thread between (0) and (1)
206 throw new Gotcha();
207 }
208 }
209 }
210 }
211 }
212
213 @Test
214 public void testHyber() {
215 if (verifyUnhandledException(Gotcha.class.getName(), "+vm.scheduler.sharedness.class=.vm.GlobalSharednessPolicy")){
216 Hyber.main(new String[0]);
217 }
218 }
219
220 }