001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tctest;
005:
006: import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
007: import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;
008:
009: import com.tc.exception.TCRuntimeException;
010: import com.tc.object.config.ConfigVisitor;
011: import com.tc.object.config.DSOClientConfigHelper;
012: import com.tc.object.config.TransparencyClassSpec;
013: import com.tc.object.config.spec.CyclicBarrierSpec;
014: import com.tc.object.config.spec.SynchronizedIntSpec;
015: import com.tc.simulator.app.ApplicationConfig;
016: import com.tc.simulator.listener.ListenerProvider;
017: import com.tctest.runner.AbstractTransparentApp;
018:
019: public class NestedPhysicalTransactionTestApp extends
020: AbstractTransparentApp {
021:
022: private final MyRoot root;
023: private final CyclicBarrier barrier;
024: private final SynchronizedInt participants;
025:
026: public static void visitL1DSOConfig(ConfigVisitor visitor,
027: DSOClientConfigHelper config) {
028: String testClass = NestedPhysicalTransactionTestApp.class
029: .getName();
030: TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
031: String methodExpression = "* " + testClass + "*.*(..)";
032: config.addWriteAutolock(methodExpression);
033: spec.addRoot("root", "the-data-root-yo");
034: spec.addRoot("participants", testClass + ".participants");
035: spec.addRoot("barrier", "barrier");
036: config.addIncludePattern(MyRoot.class.getName());
037: new CyclicBarrierSpec().visit(visitor, config);
038: new SynchronizedIntSpec().visit(visitor, config);
039: }
040:
041: public NestedPhysicalTransactionTestApp(String appId,
042: ApplicationConfig cfg, ListenerProvider listenerProvider) {
043: super (appId, cfg, listenerProvider);
044: root = new MyRoot();
045: barrier = new CyclicBarrier(this .getParticipantCount());
046: participants = new SynchronizedInt(0);
047: }
048:
049: public void run() {
050: int participantID = participants.increment();
051: try {
052: int count = 0;
053: for (int i = 0; i < this .getIntensity(); i++) {
054: barrier.barrier();
055: if (participantID == 1) {
056: root.incrementByThree();
057: barrier.barrier();
058: } else {
059: barrier.barrier();
060: count += 3;
061: int rootCount = root.getCount();
062: if (rootCount != count) {
063: throw new AssertionError("Expected " + count
064: + " but was " + rootCount);
065: }
066: }
067: }
068: } catch (InterruptedException e) {
069: throw new TCRuntimeException(e);
070: }
071: }
072:
073: private static final class MyRoot {
074: private final Object lock1 = new Object();
075: private final Object lock2 = new Object();
076: private int count;
077:
078: public int getCount() {
079: return count;
080: }
081:
082: public void incrementByThree() {
083: increment1();
084: }
085:
086: private synchronized void increment1() {
087: count++;
088: increment2();
089: }
090:
091: private void increment2() {
092: synchronized (lock1) {
093: count++;
094: increment3();
095: }
096: }
097:
098: private void increment3() {
099: synchronized (lock2) {
100: count++;
101: }
102: }
103:
104: }
105:
106: }
|