1 8 9 package com.sleepycat.je.latch; 10 11 import junit.framework.TestCase; 12 13 import com.sleepycat.je.DatabaseException; 14 import com.sleepycat.je.junit.JUnitThread; 15 16 public class LatchTest extends TestCase { 17 private Latch latch1 = null; 18 private Latch latch2 = null; 19 private JUnitThread tester1 = null; 20 private JUnitThread tester2 = null; 21 22 static private final boolean DEBUG = false; 23 24 private void debugMsg(String message) { 25 if (DEBUG) { 26 System.out.println(Thread.currentThread().toString() 27 + " " + message); 28 } 29 } 30 31 public void setUp() { 32 } 33 34 private void initExclusiveLatches() { 35 latch1 = LatchSupport.makeLatch("LatchTest-latch1", null); 36 latch2 = LatchSupport.makeLatch("LatchTest-latch2", null); 37 } 38 39 public void tearDown() { 40 latch1 = null; 41 latch2 = null; 42 } 43 44 public void testAcquireAndReacquire() 45 throws Throwable { 46 47 initExclusiveLatches(); 48 JUnitThread tester = 49 new JUnitThread("testAcquireAndReacquire") { 50 public void testBody() { 51 52 try { 53 latch1.acquire(); 54 } catch (DatabaseException LE) { 55 fail("caught DatabaseException"); 56 } 57 58 59 try { 60 latch1.acquire(); 61 fail("didn't catch LatchException"); 62 } catch (LatchException LE) { 63 assertTrue 64 (latch1.getLatchStats().nAcquiresSelfOwned == 1); 65 } catch (DatabaseException DE) { 66 fail("didn't catch LatchException-caught DE instead"); 67 } 68 69 70 try { 71 latch1.release(); 72 } catch (LatchNotHeldException LNHE) { 73 fail("unexpected LatchNotHeldException"); 74 } 75 76 77 try { 78 latch1.release(); 79 fail("didn't catch LatchNotHeldException"); 80 } catch (LatchNotHeldException LNHE) { 81 } 82 } 83 }; 84 85 tester.doTest(); 86 } 87 88 public void testAcquireAndReacquireShared() 89 throws Throwable { 90 91 final SharedLatch latch = 92 LatchSupport.makeSharedLatch("LatchTest-latch2", null); 93 94 JUnitThread tester = 95 new JUnitThread("testAcquireAndReacquireShared") { 96 public void testBody() { 97 98 try { 99 latch.acquireShared(); 100 } catch (DatabaseException LE) { 101 fail("caught DatabaseException"); 102 } 103 104 assert latch.isOwner(); 105 106 107 try { 108 latch.acquireShared(); 109 } catch (LatchException LE) { 110 fail("didn't catch LatchException"); 111 } catch (DatabaseException DE) { 112 fail("didn't catch LatchException-caught DE instead"); 113 } 114 115 assert latch.isOwner(); 116 117 118 try { 119 latch.release(); 120 } catch (LatchNotHeldException LNHE) { 121 fail("unexpected LatchNotHeldException"); 122 } 123 124 125 try { 126 latch.release(); 127 } catch (LatchNotHeldException LNHE) { 128 fail("didn't catch LatchNotHeldException"); 129 } 130 131 132 try { 133 latch.release(); 134 fail("didn't catch LatchNotHeldException"); 135 } catch (LatchNotHeldException LNHE) { 136 } 137 } 138 }; 139 140 tester.doTest(); 141 } 142 143 147 public void testAcquireReleasePerformance() 148 throws Throwable { 149 150 initExclusiveLatches(); 151 JUnitThread tester = 152 new JUnitThread("testAcquireReleasePerformance") { 153 public void testBody() { 154 final int N_PERF_TESTS = 1000000; 155 for (int i = 0; i < N_PERF_TESTS; i++) { 156 157 try { 158 latch1.acquire(); 159 } catch (DatabaseException LE) { 160 fail("caught DatabaseException"); 161 } 162 163 164 try { 165 latch1.release(); 166 } catch (LatchNotHeldException LNHE) { 167 fail("unexpected LatchNotHeldException"); 168 } 169 } 170 LatchStats stats = latch1.getLatchStats(); 171 assertTrue(stats.nAcquiresNoWaiters == N_PERF_TESTS); 172 assertTrue(stats.nReleases == N_PERF_TESTS); 173 } 174 }; 175 176 tester.doTest(); 177 } 178 179 180 181 public void testWait() 182 throws Throwable { 183 184 initExclusiveLatches(); 185 for (int i = 0; i < 10; i++) { 186 doTestWait(); 187 } 188 } 189 190 private int nAcquiresWithContention = 0; 191 192 public void doTestWait() 193 throws Throwable { 194 195 tester1 = 196 new JUnitThread("testWait-Thread1") { 197 public void testBody() { 198 199 try { 200 latch1.acquire(); 201 } catch (DatabaseException LE) { 202 fail("caught DatabaseException"); 203 } 204 205 206 while (latch1.nWaiters() == 0) { 207 Thread.yield(); 208 } 209 210 try { 211 latch1.release(); 212 } catch (LatchNotHeldException LNHE) { 213 fail("unexpected LatchNotHeldException"); 214 } 215 } 216 }; 217 218 tester2 = 219 new JUnitThread("testWait-Thread2") { 220 public void testBody() { 221 222 223 while (latch1.owner() != tester1) { 224 Thread.yield(); 225 } 226 227 228 try { 229 latch1.acquire(); 230 } catch (DatabaseException LE) { 231 fail("caught DatabaseException"); 232 } 233 234 assertTrue(latch1.getLatchStats().nAcquiresWithContention 235 == ++nAcquiresWithContention); 236 237 238 try { 239 latch1.release(); 240 } catch (LatchNotHeldException LNHE) { 241 fail("unexpected LatchNotHeldException"); 242 } 243 } 244 }; 245 246 tester1.start(); 247 tester2.start(); 248 tester1.finishTest(); 249 tester2.finishTest(); 250 } 251 252 253 254 private volatile boolean attemptedAcquireNoWait; 255 256 public void testAcquireNoWait() 257 throws Throwable { 258 259 initExclusiveLatches(); 260 tester1 = 261 new JUnitThread("testWait-Thread1") { 262 public void testBody() { 263 debugMsg("Acquiring Latch"); 264 265 try { 266 latch1.acquire(); 267 } catch (DatabaseException LE) { 268 fail("caught DatabaseException"); 269 } 270 271 272 273 debugMsg("Waiting for other thread"); 274 while (!attemptedAcquireNoWait) { 275 Thread.yield(); 276 } 277 278 debugMsg("Releasing the latch"); 279 try { 280 latch1.release(); 281 } catch (LatchNotHeldException LNHE) { 282 fail("unexpected LatchNotHeldException"); 283 } 284 } 285 }; 286 287 tester2 = 288 new JUnitThread("testWait-Thread2") { 289 public void testBody() { 290 291 292 debugMsg("Waiting for T1 to acquire latch"); 293 while (latch1.owner() != tester1) { 294 Thread.yield(); 295 } 296 297 301 debugMsg("Acquiring no wait"); 302 try { 303 assertFalse(latch1.acquireNoWait()); 304 assertTrue(latch1.getLatchStats(). 305 nAcquireNoWaitUnsuccessful == 1); 306 } catch (DatabaseException LE) { 307 fail("caught DatabaseException"); 308 } 309 310 attemptedAcquireNoWait = true; 311 312 debugMsg("Waiting for T1 to release latch"); 313 while (latch1.owner() != null) { 314 Thread.yield(); 315 } 316 317 321 debugMsg("Acquiring no wait - 2"); 322 try { 323 assertTrue(latch1.acquireNoWait()); 324 assertTrue(latch1.getLatchStats(). 325 nAcquireNoWaitSuccessful == 1); 326 } catch (DatabaseException LE) { 327 fail("caught DatabaseException"); 328 } 329 330 334 debugMsg("Acquiring no wait - 3"); 335 try { 336 latch1.acquireNoWait(); 337 fail("didn't throw LatchException"); 338 } catch (LatchException LE) { 339 } catch (Exception e) { 341 fail("caught Exception"); 342 } 343 344 345 debugMsg("releasing the latch"); 346 try { 347 latch1.release(); 348 } catch (LatchNotHeldException LNHE) { 349 fail("unexpected LatchNotHeldException"); 350 } 351 } 352 }; 353 354 tester1.start(); 355 tester2.start(); 356 tester1.finishTest(); 357 tester2.finishTest(); 358 } 359 360 361 private final int N_WAITERS = 5; 362 363 364 private class MultiWaiterTestThread extends JUnitThread { 365 private int waiterNumber; 366 public MultiWaiterTestThread(String name, int waiterNumber) { 367 super(name); 368 this.waiterNumber = waiterNumber; 369 } 370 } 371 372 public void testMultipleWaiters() 373 throws Throwable { 374 375 initExclusiveLatches(); 376 JUnitThread[] waiterThreads = 377 new JUnitThread[N_WAITERS]; 378 379 tester1 = 380 new JUnitThread("testWait-Thread1") { 381 public void testBody() { 382 383 debugMsg("About to acquire latch"); 384 385 386 try { 387 latch1.acquire(); 388 } catch (DatabaseException LE) { 389 fail("caught DatabaseException"); 390 } 391 392 debugMsg("acquired latch"); 393 394 397 while (latch1.nWaiters() < N_WAITERS) { 398 Thread.yield(); 399 } 400 401 debugMsg("About to release latch"); 402 403 try { 404 latch1.release(); 405 } catch (LatchNotHeldException LNHE) { 406 fail("unexpected LatchNotHeldException"); 407 } 408 } 409 }; 410 411 for (int i = 0; i < N_WAITERS; i++) { 412 waiterThreads[i] = 413 new MultiWaiterTestThread("testWait-Waiter" + i, i) { 414 public void testBody() { 415 416 int waiterNumber = 417 ((MultiWaiterTestThread) 418 Thread.currentThread()).waiterNumber; 419 420 421 debugMsg("Waiting for main to acquire latch"); 422 423 while (latch1.owner() != tester1) { 424 Thread.yield(); 425 } 426 427 431 debugMsg("Waiting for our turn to acquire latch"); 432 while (latch1.nWaiters() < waiterNumber) { 433 Thread.yield(); 434 } 435 436 debugMsg("About to acquire latch"); 437 438 try { 439 latch1.acquire(); 440 } catch (DatabaseException LE) { 441 fail("caught DatabaseException"); 442 } 443 444 debugMsg("nWaiters: " + latch1.nWaiters()); 445 assertTrue(latch1.nWaiters() == 446 (N_WAITERS - waiterNumber - 1)); 447 448 debugMsg("About to release latch"); 449 450 try { 451 latch1.release(); 452 } catch (LatchNotHeldException LNHE) { 453 fail("unexpected LatchNotHeldException"); 454 } 455 } 456 }; 457 } 458 459 tester1.start(); 460 461 for (int i = 0; i < N_WAITERS; i++) { 462 waiterThreads[i].start(); 463 } 464 465 tester1.finishTest(); 466 for (int i = 0; i < N_WAITERS; i++) { 467 waiterThreads[i].finishTest(); 468 } 469 } 470 } 471 | Popular Tags |