0001: /*
0002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
0003: * notice. All rights reserved.
0004: */
0005: package com.tctest;
0006:
0007: import com.tc.exception.TCObjectNotSharableException;
0008: import com.tc.exception.TCRuntimeException;
0009: import com.tc.object.bytecode.ManagerUtil;
0010: import com.tc.object.config.ConfigVisitor;
0011: import com.tc.object.config.DSOClientConfigHelper;
0012: import com.tc.object.config.TransparencyClassSpec;
0013: import com.tc.object.util.ReadOnlyException;
0014: import com.tc.simulator.app.ApplicationConfig;
0015: import com.tc.simulator.listener.ListenerProvider;
0016: import com.tc.util.Assert;
0017: import com.tc.util.DebugUtil;
0018: import com.tc.util.runtime.Vm;
0019: import com.tctest.runner.AbstractTransparentApp;
0020:
0021: import java.util.Date;
0022: import java.util.HashMap;
0023: import java.util.LinkedList;
0024: import java.util.List;
0025: import java.util.Map;
0026: import java.util.Random;
0027: import java.util.concurrent.CyclicBarrier;
0028: import java.util.concurrent.TimeUnit;
0029: import java.util.concurrent.locks.Condition;
0030: import java.util.concurrent.locks.Lock;
0031: import java.util.concurrent.locks.ReentrantReadWriteLock;
0032: import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
0033: import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
0034:
0035: public class ReentrantReadWriteLockTestApp extends
0036: AbstractTransparentApp {
0037: public final static String CRASH_TEST = "CRASH_TEST";
0038: private final static int NUM_OF_PUTS = 500;
0039:
0040: private final CyclicBarrier barrier, barrier2, barrier3, barrier4,
0041: barrier5;
0042: private final DataRoot dataRoot = new DataRoot();
0043:
0044: private final ReentrantReadWriteLock nonFairReadWriteLockRoot = new ReentrantReadWriteLock();
0045: private final ReentrantReadWriteLock fairReadWriteLockRoot = new ReentrantReadWriteLock(
0046: true);
0047: private final Condition nonFairCondition = nonFairReadWriteLockRoot
0048: .writeLock().newCondition();
0049: private final Condition fairCondition = fairReadWriteLockRoot
0050: .writeLock().newCondition();
0051:
0052: private final List queue = new LinkedList();
0053: private final Random random;
0054:
0055: private int numOfPutters = 1;
0056: private int numOfGetters;
0057: private final boolean isCrashTest;
0058:
0059: public ReentrantReadWriteLockTestApp(String appId,
0060: ApplicationConfig cfg, ListenerProvider listenerProvider) {
0061: super (appId, cfg, listenerProvider);
0062: barrier = new CyclicBarrier(getParticipantCount());
0063: barrier2 = new CyclicBarrier(getParticipantCount());
0064: barrier3 = new CyclicBarrier(getParticipantCount());
0065: barrier4 = new CyclicBarrier(2);
0066: barrier5 = new CyclicBarrier(3);
0067:
0068: random = new Random(new Random(System.currentTimeMillis()
0069: + getApplicationId().hashCode()).nextLong());
0070: numOfGetters = getParticipantCount() - numOfPutters;
0071:
0072: isCrashTest = "true".equals(cfg.getAttribute(CRASH_TEST)) ? true
0073: : false;
0074: }
0075:
0076: public void run() {
0077: try {
0078: int index = barrier.await();
0079: if (index == 0) {
0080: DebugUtil.DEBUG = true;
0081: }
0082: barrier.await();
0083:
0084: unsharedToSharedTest(index, new ReentrantReadWriteLock());
0085:
0086: readWriteLockTest(index, nonFairReadWriteLockRoot,
0087: nonFairCondition);
0088: ReentrantReadWriteLock localLock = new ReentrantReadWriteLock();
0089: singleNodeConditionVariableTesting(index, localLock
0090: .writeLock(), localLock.writeLock().newCondition());
0091:
0092: readWriteLockTest(index, fairReadWriteLockRoot,
0093: fairCondition);
0094: localLock = new ReentrantReadWriteLock(true);
0095: singleNodeConditionVariableTesting(index, localLock
0096: .writeLock(), localLock.writeLock().newCondition());
0097:
0098: if (index == 0) {
0099: DebugUtil.DEBUG = false;
0100: }
0101: barrier.await();
0102:
0103: } catch (Throwable t) {
0104: notifyError(t);
0105: }
0106: }
0107:
0108: private void tryLockTest(int index, ReentrantReadWriteLock lock)
0109: throws Exception {
0110: printTimeStamp(index, "tryLockTest");
0111:
0112: final ReadLock readLock = lock.readLock();
0113: final WriteLock writeLock = lock.writeLock();
0114:
0115: if (index == 0) {
0116: writeLock.lock();
0117: barrier2.await();
0118: try {
0119: Thread.sleep(10000);
0120: } finally {
0121: writeLock.unlock();
0122: }
0123: barrier2.await();
0124: } else {
0125: barrier2.await();
0126: int count = 0;
0127: for (int i = 0; i < 10; i++) {
0128: if (!readLock.tryLock()) {
0129: if (lock.isWriteLocked()) {
0130: count++;
0131: }
0132: }
0133: }
0134: Assert.assertEquals(10, count);
0135: barrier2.await();
0136: count = 0;
0137: for (int i = 0; i < 10; i++) {
0138: if (!readLock.tryLock()) {
0139: if (lock.isWriteLocked()) {
0140: count++;
0141: }
0142: }
0143: }
0144: Assert.assertEquals(10, count);
0145: }
0146: barrier.await();
0147: }
0148:
0149: private void readWriteLockTest(int index,
0150: ReentrantReadWriteLock readWriteLock, Condition condition)
0151: throws Exception {
0152: basicTryReadLockTest(index, readWriteLock);
0153: basicTryReadWriteLockTest(index, readWriteLock);
0154: basicTryWriteReadLockTest(index, readWriteLock);
0155: basicTryWriteLockTimeoutTest(index, readWriteLock);
0156: tryReadLockMultiNodeTest(index, readWriteLock);
0157: tryWriteLockMultiNodeTest(index, readWriteLock);
0158: tryReadWriteLockSingleNodeTest(index, readWriteLock);
0159: if (!Vm.isIBM()) {
0160: tryReadWriteLockSingleNodeTest(index,
0161: new ReentrantReadWriteLock());
0162: }
0163:
0164: basicSingleNodeReadThenWriteLockingTest(index, readWriteLock);
0165: basicSingleNodeReadThenWriteLockingTest(index,
0166: new ReentrantReadWriteLock());
0167: basicMultiNodesReadThenWriteLockingTest(index, readWriteLock);
0168: modifyDataUsingReadLockTest(index, readWriteLock);
0169: modifyDataTest(index, readWriteLock);
0170: lockDownGradeTest(index, readWriteLock);
0171: reentrantReadLockWithWriteTest(index, readWriteLock);
0172: basicAPITest(index, readWriteLock);
0173: basicConditionVariableTesting(index, readWriteLock.writeLock(),
0174: condition);
0175: basicConditionVariableWaitTesting(index, readWriteLock,
0176: condition);
0177: singleNodeConditionVariableTesting(index, readWriteLock
0178: .writeLock(), condition);
0179:
0180: tryLockTest(index, readWriteLock);
0181: }
0182:
0183: private void unsharedToSharedTest(int index,
0184: ReentrantReadWriteLock lock) throws Exception {
0185: printTimeStamp(index, "unsharedToSharedTest");
0186:
0187: if (index == 1) {
0188: ReadLock readLock = lock.readLock();
0189: readLock.lock();
0190: try {
0191: dataRoot.setLock(lock);
0192: throw new AssertionError(
0193: "Should have expected a TCObjectNotSharableException.");
0194: } catch (TCObjectNotSharableException e) {
0195: // expected
0196: } finally {
0197: readLock.unlock();
0198: }
0199: Assert.assertFalse(ManagerUtil.isManaged(lock));
0200: }
0201:
0202: barrier.await();
0203:
0204: if (index == 0) {
0205: WriteLock writeLock = lock.writeLock();
0206: writeLock.lock();
0207: try {
0208: dataRoot.setLock(lock);
0209: throw new AssertionError(
0210: "Should have expected a TCObjectNotSharableException.");
0211: } catch (TCObjectNotSharableException e) {
0212: // expected
0213: } finally {
0214: writeLock.unlock();
0215: }
0216: Assert.assertFalse(ManagerUtil.isManaged(lock));
0217: }
0218:
0219: barrier.await();
0220: }
0221:
0222: private void tryReadWriteLockSingleNodeTest(int index,
0223: ReentrantReadWriteLock lock) throws Exception {
0224: printTimeStamp(index, "tryReadWriteLockSingleNodeTest");
0225:
0226: final ReadLock readLock = lock.readLock();
0227: final WriteLock writeLock = lock.writeLock();
0228:
0229: if (index == 0) {
0230: final CyclicBarrier localBarrier = new CyclicBarrier(3);
0231: Thread t1 = new Thread(new Runnable() {
0232: public void run() {
0233: boolean isLocked = false;
0234: try {
0235: localBarrier.await();
0236: isLocked = readLock
0237: .tryLock(2, TimeUnit.SECONDS);
0238: assertTryLockResult(!isLocked);
0239: } catch (Exception e) {
0240: throw new AssertionError(e);
0241: } finally {
0242: unLockIfLocked(readLock, isLocked);
0243: }
0244: try {
0245: localBarrier.await();
0246: } catch (Exception e) {
0247: throw new AssertionError(e);
0248: }
0249: }
0250: });
0251:
0252: Thread t2 = new Thread(new Runnable() {
0253: public void run() {
0254: try {
0255: localBarrier.await();
0256: boolean isLocked = writeLock.tryLock(8,
0257: TimeUnit.SECONDS);
0258: assertTryLockResult(isLocked);
0259: unLockIfLocked(writeLock, isLocked);
0260: } catch (Exception e) {
0261: throw new AssertionError(e);
0262: }
0263: try {
0264: localBarrier.await();
0265: } catch (Exception e) {
0266: throw new AssertionError(e);
0267: }
0268: }
0269: });
0270:
0271: t1.start();
0272: t2.start();
0273: writeLock.lock();
0274: localBarrier.await();
0275: Thread.sleep(4000);
0276: writeLock.unlock();
0277: localBarrier.await();
0278: }
0279:
0280: barrier.await();
0281:
0282: if (index == 0) {
0283: final CyclicBarrier localBarrier = new CyclicBarrier(3);
0284: Thread t1 = new Thread(new Runnable() {
0285: public void run() {
0286: try {
0287: localBarrier.await();
0288: boolean isLocked = readLock.tryLock(4,
0289: TimeUnit.SECONDS);
0290: assertTryLockResult(isLocked);
0291: unLockIfLocked(readLock, isLocked);
0292: } catch (Exception e) {
0293: throw new AssertionError(e);
0294: }
0295: }
0296: });
0297:
0298: Thread t2 = new Thread(new Runnable() {
0299: public void run() {
0300: try {
0301: localBarrier.await();
0302: boolean isLocked = writeLock.tryLock(8,
0303: TimeUnit.SECONDS);
0304: assertTryLockResult(isLocked);
0305: unLockIfLocked(writeLock, isLocked);
0306: } catch (Exception e) {
0307: throw new AssertionError(e);
0308: }
0309: }
0310: });
0311:
0312: t1.start();
0313: t2.start();
0314: writeLock.lock();
0315: localBarrier.await();
0316: Thread.sleep(2000);
0317: writeLock.unlock();
0318: }
0319:
0320: barrier.await();
0321: }
0322:
0323: private void tryWriteLockMultiNodeTest(int index,
0324: ReentrantReadWriteLock lock) throws Exception {
0325: printTimeStamp(index, "tryWriteLockMultiNodeTest first test");
0326:
0327: final ReadLock readLock = lock.readLock();
0328: final WriteLock writeLock = lock.writeLock();
0329:
0330: if (index == 0) {
0331: final CyclicBarrier localBarrier = new CyclicBarrier(3);
0332: Thread t1 = new Thread(new Runnable() {
0333: public void run() {
0334: try {
0335: localBarrier.await();
0336: barrier5.await();
0337: boolean isLocked = writeLock.tryLock(20,
0338: TimeUnit.SECONDS);
0339: assertTryLockResult(isLocked);
0340: Thread.sleep(2000);
0341: unLockIfLocked(writeLock, isLocked);
0342: localBarrier.await();
0343: } catch (Exception e) {
0344: throw new AssertionError(e);
0345: }
0346: }
0347: });
0348: Thread t2 = new Thread(new Runnable() {
0349: public void run() {
0350: try {
0351: localBarrier.await();
0352: barrier5.await();
0353: boolean isLocked = writeLock.tryLock(21,
0354: TimeUnit.SECONDS);
0355: assertTryLockResult(isLocked);
0356: Thread.sleep(2000);
0357: unLockIfLocked(writeLock, isLocked);
0358: localBarrier.await();
0359: } catch (Exception e) {
0360: throw new AssertionError(e);
0361: }
0362: }
0363: });
0364: t1.start();
0365: t2.start();
0366: writeLock.lock();
0367: localBarrier.await();
0368: barrier4.await();
0369: Thread.sleep(2000);
0370: writeLock.unlock();
0371: localBarrier.await();
0372: barrier4.await();
0373: } else if (index == 1) {
0374: barrier4.await();
0375: boolean isLocked = writeLock.tryLock(9, TimeUnit.SECONDS);
0376: barrier5.await();
0377: Thread.sleep(2000);
0378: assertTryLockResult(isLocked);
0379: unLockIfLocked(writeLock, isLocked);
0380: barrier4.await();
0381: writeLock.lock();
0382: Thread.sleep(2000);
0383: writeLock.unlock();
0384: }
0385:
0386: barrier.await();
0387: printTimeStamp(index, "tryWriteLockMultiNodeTest second test");
0388:
0389: if (index == 0) {
0390: final CyclicBarrier localBarrier = new CyclicBarrier(4);
0391: Thread t1 = new Thread(new Runnable() {
0392: public void run() {
0393: try {
0394: localBarrier.await();
0395: boolean isLocked = writeLock.tryLock(8,
0396: TimeUnit.SECONDS);
0397: assertTryLockResult(isLocked);
0398: unLockIfLocked(writeLock, isLocked);
0399: localBarrier.await();
0400: } catch (Exception e) {
0401: throw new AssertionError(e);
0402: }
0403: }
0404: });
0405: Thread t2 = new Thread(new Runnable() {
0406: public void run() {
0407: try {
0408: localBarrier.await();
0409: boolean isLocked = writeLock.tryLock(9001,
0410: TimeUnit.MILLISECONDS);
0411: assertTryLockResult(isLocked);
0412: unLockIfLocked(writeLock, isLocked);
0413: localBarrier.await();
0414: } catch (Exception e) {
0415: throw new AssertionError(e);
0416: }
0417: }
0418: });
0419: Thread t3 = new Thread(new Runnable() {
0420: public void run() {
0421: try {
0422: localBarrier.await();
0423: boolean isLocked = writeLock.tryLock(10,
0424: TimeUnit.SECONDS);
0425: assertTryLockResult(isLocked);
0426: unLockIfLocked(writeLock, isLocked);
0427: localBarrier.await();
0428: } catch (Exception e) {
0429: throw new AssertionError(e);
0430: }
0431: }
0432: });
0433: t1.start();
0434: t2.start();
0435: t3.start();
0436: writeLock.lock();
0437: localBarrier.await();
0438: barrier4.await();
0439: Thread.sleep(2000);
0440: writeLock.unlock();
0441: localBarrier.await();
0442: } else if (index == 1) {
0443: barrier4.await();
0444: boolean isLocked = writeLock.tryLock(11, TimeUnit.SECONDS);
0445: assertTryLockResult(isLocked);
0446: unLockIfLocked(writeLock, isLocked);
0447: }
0448: barrier.await();
0449: printTimeStamp(index, "tryWriteLockMultiNodeTest third test");
0450:
0451: if (index == 0) {
0452: final CyclicBarrier localBarrier = new CyclicBarrier(3);
0453: Thread t1 = new Thread(new Runnable() {
0454: public void run() {
0455: try {
0456: localBarrier.await();
0457: boolean isLocked = readLock.tryLock(4,
0458: TimeUnit.SECONDS);
0459: assertTryLockResult(isLocked);
0460: unLockIfLocked(readLock, isLocked);
0461: localBarrier.await();
0462: } catch (Exception e) {
0463: throw new AssertionError(e);
0464: }
0465: }
0466: });
0467:
0468: Thread t2 = new Thread(new Runnable() {
0469: public void run() {
0470: try {
0471: localBarrier.await();
0472: boolean isLocked = readLock.tryLock(8002,
0473: TimeUnit.MILLISECONDS);
0474: assertTryLockResult(isLocked);
0475: unLockIfLocked(readLock, isLocked);
0476: localBarrier.await();
0477: } catch (Exception e) {
0478: throw new AssertionError(e);
0479: }
0480: }
0481: });
0482:
0483: t1.start();
0484: t2.start();
0485: writeLock.lock();
0486: localBarrier.await();
0487: barrier4.await();
0488: Thread.sleep(2000);
0489: writeLock.unlock();
0490: localBarrier.await();
0491: } else if (index == 1) {
0492: barrier4.await();
0493: boolean isLocked = writeLock.tryLock(10002,
0494: TimeUnit.MILLISECONDS);
0495: assertTryLockResult(isLocked);
0496: unLockIfLocked(writeLock, isLocked);
0497: }
0498:
0499: barrier.await();
0500: printTimeStamp(index, "tryWriteLockMultiNodeTest fourth test");
0501:
0502: if (index == 0) {
0503: final CyclicBarrier localBarrier = new CyclicBarrier(2);
0504: Thread t1 = new Thread(new Runnable() {
0505: public void run() {
0506: try {
0507: localBarrier.await();
0508: boolean isLocked = writeLock.tryLock(4001,
0509: TimeUnit.MILLISECONDS);
0510: assertTryLockResult(isLocked);
0511: unLockIfLocked(writeLock, isLocked);
0512: localBarrier.await();
0513: } catch (Exception e) {
0514: throw new AssertionError(e);
0515: }
0516:
0517: }
0518: });
0519:
0520: t1.start();
0521: writeLock.lock();
0522: barrier4.await();
0523: Thread.sleep(1000);
0524: localBarrier.await();
0525: Thread.sleep(2000);
0526: writeLock.unlock();
0527: localBarrier.await();
0528: } else if (index == 1) {
0529: barrier4.await();
0530: boolean isLocked = writeLock.tryLock(10003,
0531: TimeUnit.MILLISECONDS);
0532: assertTryLockResult(isLocked);
0533: unLockIfLocked(writeLock, isLocked);
0534: }
0535:
0536: barrier.await();
0537: printTimeStamp(index, "tryWriteLockMultiNodeTest fifth test");
0538:
0539: if (index == 0) {
0540: final CyclicBarrier localBarrier = new CyclicBarrier(2);
0541: Thread t1 = new Thread(new Runnable() {
0542: public void run() {
0543: try {
0544: localBarrier.await();
0545: boolean isLocked = readLock.tryLock(4003,
0546: TimeUnit.MILLISECONDS);
0547: assertTryLockResult(isLocked);
0548: unLockIfLocked(readLock, isLocked);
0549: localBarrier.await();
0550: } catch (Exception e) {
0551: throw new AssertionError(e);
0552: }
0553:
0554: }
0555: });
0556:
0557: t1.start();
0558: writeLock.lock();
0559: barrier4.await();
0560: Thread.sleep(1000);
0561: localBarrier.await();
0562: Thread.sleep(2000);
0563: writeLock.unlock();
0564: localBarrier.await();
0565: } else if (index == 1) {
0566: barrier4.await();
0567: boolean isLocked = writeLock.tryLock(10004,
0568: TimeUnit.MILLISECONDS);
0569: assertTryLockResult(isLocked);
0570: unLockIfLocked(writeLock, isLocked);
0571: }
0572:
0573: barrier.await();
0574: printTimeStamp(index, "tryWriteLockMultiNodeTest sixth test");
0575:
0576: if (index == 0) {
0577: final CyclicBarrier localBarrier = new CyclicBarrier(2);
0578: Thread t1 = new Thread(new Runnable() {
0579: public void run() {
0580: try {
0581: localBarrier.await();
0582: boolean isLocked = readLock.tryLock(4004,
0583: TimeUnit.MILLISECONDS);
0584: assertTryLockResult(isLocked);
0585: unLockIfLocked(readLock, isLocked);
0586: localBarrier.await();
0587: } catch (Exception e) {
0588: throw new AssertionError(e);
0589: }
0590:
0591: }
0592: });
0593:
0594: t1.start();
0595: writeLock.lock();
0596: localBarrier.await();
0597: Thread.sleep(1000);
0598: barrier4.await();
0599: Thread.sleep(2000);
0600: writeLock.unlock();
0601: localBarrier.await();
0602: } else if (index == 1) {
0603: barrier4.await();
0604: boolean isLocked = writeLock.tryLock(10005,
0605: TimeUnit.MILLISECONDS);
0606: assertTryLockResult(isLocked);
0607: unLockIfLocked(writeLock, isLocked);
0608: }
0609:
0610: barrier.await();
0611: printTimeStamp(index, "tryWriteLockMultiNodeTest finish");
0612:
0613: }
0614:
0615: private void tryReadLockMultiNodeTest(int index,
0616: ReentrantReadWriteLock lock) throws Exception {
0617: printTimeStamp(index, "tryReadLockMultiNodeTest");
0618:
0619: final ReadLock readLock = lock.readLock();
0620: final WriteLock writeLock = lock.writeLock();
0621:
0622: if (index == 0) {
0623: final CyclicBarrier localBarrier = new CyclicBarrier(2);
0624: Thread t1 = new Thread(new Runnable() {
0625: public void run() {
0626: try {
0627: localBarrier.await();
0628: boolean isLocked = readLock.tryLock(4,
0629: TimeUnit.SECONDS);
0630: assertTryLockResult(isLocked);
0631: unLockIfLocked(readLock, isLocked);
0632: localBarrier.await();
0633: } catch (Exception e) {
0634: throw new AssertionError(e);
0635: }
0636:
0637: }
0638: });
0639:
0640: t1.start();
0641: writeLock.lock();
0642: localBarrier.await();
0643: Thread.sleep(1000);
0644: barrier2.await();
0645: Thread.sleep(2000);
0646: writeLock.unlock();
0647: localBarrier.await();
0648: } else {
0649: barrier2.await();
0650: writeLock.lock();
0651: writeLock.unlock();
0652: }
0653:
0654: barrier.await();
0655:
0656: if (index == 0) {
0657: final CyclicBarrier localBarrier = new CyclicBarrier(2);
0658: Thread t1 = new Thread(new Runnable() {
0659: public void run() {
0660: try {
0661: localBarrier.await();
0662: writeLock.lock();
0663: Thread.sleep(2001);
0664: writeLock.unlock();
0665: localBarrier.await();
0666: } catch (Exception e) {
0667: throw new AssertionError(e);
0668: }
0669:
0670: }
0671: });
0672:
0673: t1.start();
0674: writeLock.lock();
0675: localBarrier.await();
0676: Thread.sleep(1000);
0677: barrier2.await();
0678: Thread.sleep(2000);
0679: writeLock.unlock();
0680: localBarrier.await();
0681: } else {
0682: barrier2.await();
0683: boolean isLocked = readLock.tryLock(10, TimeUnit.SECONDS);
0684: assertTryLockResult(isLocked);
0685: unLockIfLocked(readLock, isLocked);
0686: }
0687:
0688: barrier.await();
0689:
0690: if (index == 0) {
0691: readLock.lock();
0692: try {
0693: barrier2.await();
0694: barrier2.await();
0695: } finally {
0696: readLock.unlock();
0697: }
0698: } else {
0699: barrier2.await();
0700: boolean isLocked = readLock.tryLock(1000,
0701: TimeUnit.MILLISECONDS); // We cannot use tryLock() here due to greedy
0702: // lock problem for tryLock().
0703: try {
0704: barrier2.await();
0705: assertTryLockResult(isLocked);
0706: } finally {
0707: unLockIfLocked(readLock, isLocked);
0708: }
0709: }
0710: barrier.await();
0711:
0712: if (DebugUtil.DEBUG) {
0713: System.err.println("Client id: "
0714: + ManagerUtil.getClientID() + ", index: " + index);
0715: }
0716:
0717: if (index == 0) {
0718: writeLock.lock();
0719: try {
0720: barrier2.await();
0721: barrier2.await();
0722: } finally {
0723: writeLock.unlock();
0724: }
0725: } else {
0726: barrier2.await();
0727: boolean isLocked = readLock.tryLock();
0728: barrier2.await();
0729: assertTryLockResult(!isLocked);
0730: unLockIfLocked(readLock, isLocked);
0731: }
0732:
0733: barrier.await();
0734:
0735: if (index == 0) {
0736: writeLock.lock();
0737: try {
0738: barrier2.await();
0739: Thread.sleep(2000);
0740: } finally {
0741: writeLock.unlock();
0742: }
0743: } else {
0744: barrier2.await();
0745: boolean isLocked = readLock.tryLock(4, TimeUnit.SECONDS);
0746: try {
0747: assertTryLockResult(isLocked);
0748: } finally {
0749: unLockIfLocked(readLock, isLocked);
0750: }
0751: }
0752: barrier.await();
0753:
0754: if (index == 0) {
0755: writeLock.lock();
0756: try {
0757: barrier2.await();
0758: Thread.sleep(4000);
0759: } finally {
0760: writeLock.unlock();
0761: }
0762: } else {
0763: barrier2.await();
0764: boolean isLocked = readLock.tryLock(1, TimeUnit.SECONDS);
0765: assertTryLockResult(!isLocked);
0766: unLockIfLocked(readLock, isLocked);
0767: if (DebugUtil.DEBUG) {
0768: System.err
0769: .println("Client "
0770: + ManagerUtil.getClientID()
0771: + " in tryReadLockMultiNodeTest last test, isLocked: "
0772: + isLocked);
0773: }
0774: }
0775: barrier.await();
0776: }
0777:
0778: private void basicConditionVariableWaitTesting(int index,
0779: ReentrantReadWriteLock lock, Condition condition)
0780: throws Exception {
0781: printTimeStamp(index, "basicConditionVariableWaitTesting");
0782:
0783: WriteLock writeLock = lock.writeLock();
0784:
0785: if (index == 0) {
0786: Thread thread = new Thread(new TestRunnable1(writeLock,
0787: condition));
0788: thread.start();
0789: }
0790:
0791: barrier.await();
0792:
0793: if (index == 0) {
0794: Thread.sleep(2000); // Sleep so that the TestRunnable1 thread can pick up.
0795: Assert.assertEquals(1, lock.getWaitQueueLength(condition));
0796: Assert.assertTrue(lock.hasWaiters(condition));
0797: }
0798:
0799: barrier.await();
0800:
0801: if (index == 0) {
0802: writeLock.lock();
0803: try {
0804: condition.signalAll();
0805: } finally {
0806: writeLock.unlock();
0807: }
0808: }
0809:
0810: barrier.await();
0811:
0812: if (index == 0) {
0813: Assert.assertEquals(0, lock.getWaitQueueLength(condition));
0814: }
0815:
0816: barrier.await();
0817: }
0818:
0819: private void singleNodeConditionVariableTesting(int index,
0820: final WriteLock lock, final Condition condition)
0821: throws Exception {
0822: printTimeStamp(index, "singleNodeConditionVariableTesting");
0823:
0824: if (index == 0) {
0825: final CyclicBarrier localBarrier = new CyclicBarrier(3);
0826: final List queue = new LinkedList();
0827:
0828: Thread t1 = new Thread(new Runnable() {
0829: public void run() {
0830: try {
0831: doPutter(1, lock, condition, queue, 1);
0832: localBarrier.await();
0833: } catch (Exception e) {
0834: throw new AssertionError(e);
0835: }
0836: }
0837: });
0838:
0839: Thread t2 = new Thread(new Runnable() {
0840: public void run() {
0841: try {
0842: doGetter(2, lock, condition, queue);
0843: localBarrier.await();
0844: } catch (Exception e) {
0845: throw new AssertionError(e);
0846: }
0847: }
0848: });
0849:
0850: t1.start();
0851: t2.start();
0852: localBarrier.await();
0853: }
0854:
0855: barrier.await();
0856: }
0857:
0858: private void basicConditionVariableTesting(int index,
0859: WriteLock lock, Condition condition) throws Exception {
0860: printTimeStamp(index, "basicConditionVariableTesting");
0861:
0862: final long id = new Long(getApplicationId()).longValue();
0863:
0864: if (index == 0) {
0865: doPutter(id, lock, condition, queue, numOfGetters);
0866: } else {
0867: doGetter(id, lock, condition, queue);
0868: }
0869:
0870: barrier.await();
0871: }
0872:
0873: private void doPutter(long id, WriteLock lock, Condition condition,
0874: List queue, int numOfGetters) throws Exception {
0875: Thread.currentThread().setName("PUTTER-" + id);
0876:
0877: for (int i = 0; i < NUM_OF_PUTS; i++) {
0878: lock.lock();
0879: try {
0880: System.err.println("PUTTER-" + id + " Putting " + i);
0881: queue.add(new WorkItem(String.valueOf(i)));
0882: if (i % 2 == 0) {
0883: condition.signalAll();
0884: } else {
0885: condition.signal();
0886: }
0887: } finally {
0888: lock.unlock();
0889: }
0890: }
0891:
0892: for (int i = 0; i < numOfGetters; i++) {
0893: lock.lock();
0894: try {
0895: queue.add(WorkItem.STOP);
0896: condition.signalAll();
0897: } finally {
0898: lock.unlock();
0899: }
0900: }
0901: }
0902:
0903: private void doGetter(long id, WriteLock lock, Condition condition,
0904: List queue) throws Exception {
0905: Thread.currentThread().setName("GETTER-" + id);
0906:
0907: int i = 0;
0908: while (true) {
0909: lock.lock();
0910: lock.lock();
0911: try {
0912: while (queue.size() == 0) {
0913: int choice = i % 4;
0914: switch (choice) {
0915: case 0:
0916: condition.await();
0917: break;
0918: case 1:
0919: condition.awaitUninterruptibly();
0920: break;
0921: case 2:
0922: long millis = random.nextInt(10000);
0923: condition.await(millis, TimeUnit.MILLISECONDS);
0924: break;
0925: case 3:
0926: long nanos = random.nextInt(10000);
0927: condition.awaitNanos(nanos);
0928: break;
0929: }
0930: i++;
0931: }
0932: WorkItem wi = (WorkItem) queue.remove(0);
0933: if (wi.isStop()) {
0934: return;
0935: }
0936: System.err.println("GETTER- " + id + " removes " + wi);
0937:
0938: } finally {
0939: lock.unlock();
0940: lock.unlock();
0941: }
0942: }
0943: }
0944:
0945: private void basicAPITest(int index, ReentrantReadWriteLock lock)
0946: throws Exception {
0947: printTimeStamp(index, "basicAPITest");
0948:
0949: WriteLock writeLock = lock.writeLock();
0950: ReadLock readLock = lock.readLock();
0951: if (index == 0) {
0952: writeLock.lock();
0953: writeLock.lock();
0954: writeLock.lock();
0955: barrier4.await();
0956: Thread.sleep(2000);
0957: if (!isCrashTest) {
0958: Assert.assertTrue(lock.hasQueuedThreads());
0959: }
0960: Assert.assertEquals(3, lock.getWriteHoldCount());
0961: writeLock.unlock();
0962: Assert.assertEquals(2, lock.getWriteHoldCount());
0963: writeLock.unlock();
0964: Assert.assertEquals(1, lock.getWriteHoldCount());
0965: writeLock.unlock();
0966: barrier4.await();
0967: } else if (index == 1) {
0968: barrier4.await();
0969: readLock.lock();
0970: readLock.lock();
0971: barrier4.await();
0972: Thread.sleep(2000);
0973: Assert.assertEquals(2, lock.getReadLockCount());
0974: readLock.unlock();
0975: Assert.assertEquals(1, lock.getReadLockCount());
0976: readLock.unlock();
0977: }
0978: barrier.await();
0979:
0980: Assert.assertFalse(lock.hasQueuedThreads());
0981:
0982: barrier.await();
0983:
0984: if (index == 0) {
0985: writeLock.lock();
0986: barrier2.await();
0987: Thread.sleep(4000);
0988: Assert.assertEquals(2, lock.getQueueLength());
0989: Assert.assertTrue(lock.isWriteLocked());
0990: Assert.assertTrue(lock.isWriteLockedByCurrentThread());
0991: writeLock.unlock();
0992: } else if (index == 1) {
0993: barrier2.await();
0994: readLock.lock();
0995: readLock.unlock();
0996: } else {
0997: barrier2.await();
0998: writeLock.lock();
0999: writeLock.unlock();
1000: }
1001:
1002: barrier.await();
1003: }
1004:
1005: private void reentrantReadLockWithWriteTest(int index,
1006: ReentrantReadWriteLock lock) throws Exception {
1007: printTimeStamp(index, "reentrantReadLockWithWriteTest");
1008:
1009: final WriteLock writeLock = lock.writeLock();
1010: final ReadLock readLock = lock.readLock();
1011: if (index == 0) {
1012: final CyclicBarrier localBarrier = new CyclicBarrier(2);
1013: Thread t1 = new Thread(new Runnable() {
1014: public void run() {
1015: try {
1016: localBarrier.await();
1017: writeLock.lock();
1018: writeLock.unlock();
1019: localBarrier.await();
1020: } catch (Exception e) {
1021: throw new AssertionError(e);
1022: }
1023: }
1024: });
1025: readLock.lock();
1026: t1.start();
1027: localBarrier.await();
1028: readLock.lock();
1029: readLock.unlock();
1030: readLock.unlock();
1031: localBarrier.await();
1032: }
1033:
1034: barrier.await();
1035: }
1036:
1037: private void lockDownGradeTest(int index,
1038: ReentrantReadWriteLock lock) throws Exception {
1039: printTimeStamp(index, "lockDownGradeTest");
1040:
1041: final WriteLock writeLock = lock.writeLock();
1042: final ReadLock readLock = lock.readLock();
1043: if (index == 0) {
1044: writeLock.lock();
1045: readLock.lock();
1046: writeLock.unlock();
1047: readLock.unlock();
1048: }
1049: barrier.await();
1050: }
1051:
1052: private void basicTryWriteLockTimeoutTest(int index,
1053: ReentrantReadWriteLock lock) throws Exception {
1054: printTimeStamp(index, "basicTryWriteLockTimeoutTest");
1055:
1056: final WriteLock writeLock = lock.writeLock();
1057: if (index == 0) {
1058: boolean isLocked = writeLock
1059: .tryLock(1000, TimeUnit.SECONDS);
1060: try {
1061: barrier2.await();
1062: assertTryLockResult(isLocked);
1063: barrier3.await();
1064: } finally {
1065: unLockIfLocked(writeLock, isLocked);
1066: }
1067: barrier3.await();
1068: } else {
1069: barrier2.await();
1070: boolean isLocked = writeLock.tryLock(5, TimeUnit.SECONDS);
1071: assertTryLockResult(!isLocked);
1072: unLockIfLocked(writeLock, isLocked);
1073: barrier3.await();
1074: barrier3.await();
1075: }
1076: barrier.await();
1077: }
1078:
1079: private void modifyDataUsingReadLockTest(int index,
1080: ReentrantReadWriteLock lock) throws Exception {
1081: printTimeStamp(index, "modifyDataUsingReadLockTest");
1082:
1083: ReadLock readLock = lock.readLock();
1084:
1085: if (index == 0) {
1086: readLock.lock();
1087: try {
1088: dataRoot.putData("key1", "value1");
1089: throw new AssertionError(
1090: "Should have thrown a ReadOnlyException.");
1091: } catch (ReadOnlyException re) {
1092: // expected;
1093: } finally {
1094: readLock.unlock();
1095: }
1096: }
1097:
1098: barrier.await();
1099: }
1100:
1101: private void modifyDataTest(int index, ReentrantReadWriteLock lock)
1102: throws Exception {
1103: printTimeStamp(index, "modifyDataTest");
1104:
1105: ReadLock readLock = lock.readLock();
1106: WriteLock writeLock = lock.writeLock();
1107:
1108: if (index == 0) {
1109: writeLock.lock();
1110: try {
1111: dataRoot.putData("key2", "value2");
1112: } finally {
1113: writeLock.unlock();
1114: }
1115: barrier2.await();
1116: } else {
1117: barrier2.await();
1118: readLock.lock();
1119: try {
1120: Object data = dataRoot.getData("key2");
1121: Assert.assertEquals("value2", data);
1122: } finally {
1123: readLock.unlock();
1124: }
1125: }
1126:
1127: barrier.await();
1128: }
1129:
1130: private void basicTryWriteReadLockTest(int index,
1131: ReentrantReadWriteLock lock) throws Exception {
1132: printTimeStamp(index, "basicTryWriteReadLockTest");
1133:
1134: final ReadLock readLock = lock.readLock();
1135: final WriteLock writeLock = lock.writeLock();
1136:
1137: if (index == 0) {
1138: boolean isLocked = writeLock.tryLock();
1139: barrier2.await();
1140: try {
1141: assertTryLockResult(isLocked);
1142: } finally {
1143: barrier3.await();
1144: unLockIfLocked(writeLock, isLocked);
1145: }
1146: } else {
1147: barrier2.await();
1148: boolean isLocked = readLock.tryLock();
1149: assertTryLockResult(!isLocked);
1150: unLockIfLocked(readLock, isLocked);
1151: barrier3.await();
1152: }
1153:
1154: barrier.await();
1155: }
1156:
1157: private void basicTryReadWriteLockTest(int index,
1158: ReentrantReadWriteLock lock) throws Exception {
1159: printTimeStamp(index, "basicTryReadWriteLockTest");
1160:
1161: final ReadLock readLock = lock.readLock();
1162: final WriteLock writeLock = lock.writeLock();
1163:
1164: if (index == 0) {
1165: barrier2.await();
1166: boolean isLocked = writeLock.tryLock();
1167: assertTryLockResult(!isLocked);
1168: unLockIfLocked(writeLock, isLocked);
1169: barrier3.await();
1170: } else {
1171: boolean isLocked = readLock.tryLock();
1172: try {
1173: barrier2.await();
1174: assertTryLockResult(isLocked);
1175: } finally {
1176: barrier3.await();
1177: unLockIfLocked(readLock, isLocked);
1178: }
1179: }
1180:
1181: barrier.await();
1182: }
1183:
1184: private void basicTryReadLockTest(int index,
1185: ReentrantReadWriteLock lock) throws Exception {
1186: printTimeStamp(index, "basicTryReadLockTest");
1187:
1188: final ReadLock readLock = lock.readLock();
1189: boolean isLocked = readLock.tryLock();
1190: try {
1191: barrier2.await();
1192: assertTryLockResult(isLocked);
1193: } finally {
1194: unLockIfLocked(readLock, isLocked);
1195: }
1196: barrier.await();
1197: }
1198:
1199: private void basicSingleNodeReadThenWriteLockingTest(int index,
1200: ReentrantReadWriteLock lock) throws Exception {
1201: printTimeStamp(index, "basicSingleNodeReadThenWriteLockingTest");
1202:
1203: final ReadLock readLock = lock.readLock();
1204: final WriteLock writeLock = lock.writeLock();
1205:
1206: if (index == 0) {
1207: final CyclicBarrier localBarrier = new CyclicBarrier(4);
1208: final CyclicBarrier localBarrier2 = new CyclicBarrier(5);
1209:
1210: Thread t1 = new Thread(new Runnable() {
1211: public void run() {
1212: writeLock.lock();
1213: try {
1214: localBarrier.await();
1215: Thread.sleep(5000);
1216: } catch (Exception e) {
1217: throw new TCRuntimeException(e);
1218: } finally {
1219: writeLock.unlock();
1220: }
1221: try {
1222: localBarrier2.await();
1223: } catch (Exception e) {
1224: throw new TCRuntimeException(e);
1225: }
1226: }
1227: });
1228:
1229: Thread t2 = new Thread(new Runnable() {
1230: public void run() {
1231: try {
1232: localBarrier.await();
1233: readLock.lock();
1234: try {
1235: Thread.sleep(2000);
1236: } finally {
1237: readLock.unlock();
1238: }
1239: } catch (Exception e) {
1240: throw new TCRuntimeException(e);
1241: }
1242: try {
1243: localBarrier2.await();
1244: } catch (Exception e) {
1245: throw new TCRuntimeException(e);
1246: }
1247: }
1248: });
1249:
1250: Thread t3 = new Thread(new Runnable() {
1251: public void run() {
1252: try {
1253: localBarrier.await();
1254: readLock.lock();
1255: try {
1256: Thread.sleep(2000);
1257: } finally {
1258: readLock.unlock();
1259: }
1260: } catch (Exception e) {
1261: throw new TCRuntimeException(e);
1262: }
1263: try {
1264: localBarrier2.await();
1265: } catch (Exception e) {
1266: throw new TCRuntimeException(e);
1267: }
1268: }
1269: });
1270:
1271: Thread t4 = new Thread(new Runnable() {
1272: public void run() {
1273: try {
1274: localBarrier.await();
1275: writeLock.lock();
1276: try {
1277: Thread.sleep(2000);
1278: } finally {
1279: writeLock.unlock();
1280: }
1281: } catch (Exception e) {
1282: throw new TCRuntimeException(e);
1283: }
1284: try {
1285: localBarrier2.await();
1286: } catch (Exception e) {
1287: throw new TCRuntimeException(e);
1288: }
1289: }
1290: });
1291: t1.start();
1292: t2.start();
1293: t3.start();
1294: t4.start();
1295:
1296: localBarrier2.await();
1297: }
1298:
1299: barrier.await();
1300: }
1301:
1302: private void basicMultiNodesReadThenWriteLockingTest(int index,
1303: ReentrantReadWriteLock lock) throws Exception {
1304: printTimeStamp(index, "basicMultiNodesReadThenWriteLockingTest");
1305:
1306: ReadLock readLock = lock.readLock();
1307: WriteLock writeLock = lock.writeLock();
1308:
1309: if (index == 0) {
1310: writeLock.lock();
1311: try {
1312: barrier2.await();
1313: Thread.sleep(5000);
1314: } finally {
1315: writeLock.unlock();
1316: }
1317: } else if (index == 1 || index == 2) {
1318: barrier2.await();
1319: readLock.lock();
1320: try {
1321: Thread.sleep(2000);
1322: } finally {
1323: readLock.unlock();
1324: }
1325: } else if (index == 3) {
1326: barrier2.await();
1327: writeLock.lock();
1328: try {
1329: Thread.sleep(3000);
1330: } finally {
1331: writeLock.unlock();
1332: }
1333: }
1334:
1335: barrier.await();
1336: }
1337:
1338: private void unLockIfLocked(Lock lock, boolean isLocked) {
1339: if (isLocked) {
1340: lock.unlock();
1341: }
1342: }
1343:
1344: private void assertTryLockResult(boolean isLocked) {
1345: if (!isCrashTest) {
1346: Assert.assertTrue(isLocked);
1347: }
1348: }
1349:
1350: private void printTimeStamp(int index, String methodName)
1351: throws Exception {
1352: if (index == 0) {
1353: System.err.println("Running method " + methodName
1354: + " -- time: " + (new Date()));
1355: }
1356:
1357: barrier.await();
1358: }
1359:
1360: public static void visitL1DSOConfig(ConfigVisitor visitor,
1361: DSOClientConfigHelper config) {
1362: String testClass = ReentrantReadWriteLockTestApp.class
1363: .getName();
1364: TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
1365:
1366: config.addIncludePattern(testClass + "$*");
1367:
1368: String methodExpression = "* " + testClass + "*.*(..)";
1369: config.addWriteAutolock(methodExpression);
1370:
1371: spec.addRoot("nonFairReadWriteLockRoot",
1372: "nonFairReadWriteLockRoot");
1373: spec.addRoot("fairReadWriteLockRoot", "fairReadWriteLockRoot");
1374: spec.addRoot("barrier", "barrier");
1375: spec.addRoot("barrier2", "barrier2");
1376: spec.addRoot("barrier3", "barrier3");
1377: spec.addRoot("barrier4", "barrier4");
1378: spec.addRoot("barrier5", "barrier5");
1379: spec.addRoot("dataRoot", "dataRoot");
1380: spec.addRoot("nonFairCondition", "nonFairCondition");
1381: spec.addRoot("fairCondition", "fairCondition");
1382: spec.addRoot("queue", "queue");
1383: }
1384:
1385: private static class DataRoot {
1386: private Map store = new HashMap();
1387: private ReentrantReadWriteLock lock;
1388:
1389: public void putData(Object key, Object value) {
1390: store.put(key, value);
1391: }
1392:
1393: public Object getData(Object key) {
1394: return store.get(key);
1395: }
1396:
1397: public synchronized void setLock(ReentrantReadWriteLock lock) {
1398: this .lock = lock;
1399: }
1400: }
1401:
1402: private static class WorkItem {
1403: static final WorkItem STOP = new WorkItem("STOP");
1404:
1405: private final String name;
1406:
1407: WorkItem(String name) {
1408: this .name = name;
1409: }
1410:
1411: boolean isStop() {
1412: return STOP.name.equals(name);
1413: }
1414:
1415: public String toString() {
1416: return this .name;
1417: }
1418: }
1419:
1420: private static class TestRunnable1 implements Runnable {
1421: private WriteLock lock;
1422: private Condition conditionObject;
1423:
1424: public TestRunnable1(WriteLock lock, Condition conditionObject) {
1425: this .lock = lock;
1426: this .conditionObject = conditionObject;
1427: }
1428:
1429: public void run() {
1430: lock.lock();
1431: try {
1432: conditionObject.await();
1433: } catch (InterruptedException e) {
1434: throw new TCRuntimeException(e);
1435: } finally {
1436: lock.unlock();
1437: }
1438: }
1439: }
1440:
1441: }
|