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.BrokenBarrierException;
007: import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
008:
009: import com.tc.object.config.ConfigVisitor;
010: import com.tc.object.config.DSOClientConfigHelper;
011: import com.tc.object.config.TransparencyClassSpec;
012: import com.tc.object.config.spec.CyclicBarrierSpec;
013: import com.tc.simulator.app.ApplicationConfig;
014: import com.tc.simulator.listener.ListenerProvider;
015: import com.tctest.runner.AbstractTransparentApp;
016:
017: import java.util.ArrayList;
018: import java.util.List;
019:
020: public class GreedyLocksSystemTestApp extends AbstractTransparentApp {
021:
022: public static final int NODE_COUNT = 3;
023: public static final int EXECUTION_COUNT = 5;
024: public static final int ITERATION_COUNT = 1;
025:
026: private List locks = new ArrayList();
027: private CyclicBarrier barrier = new CyclicBarrier(NODE_COUNT
028: * EXECUTION_COUNT);
029: private String name;
030: private static int id = 0;
031: private static int count = 5;
032:
033: public GreedyLocksSystemTestApp(String appId,
034: ApplicationConfig cfg, ListenerProvider listenerProvider) {
035: super (appId, cfg, listenerProvider);
036: }
037:
038: public static void visitL1DSOConfig(ConfigVisitor visitor,
039: DSOClientConfigHelper config) {
040: String testClass = GreedyLocksSystemTestApp.class.getName();
041: String lockClass = GreedyLocksSystemTestApp.LockObject.class
042: .getName();
043: TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
044: config.addIncludePattern(lockClass);
045:
046: String setIDMethodExpression = "* " + testClass + "*.setID(..)";
047:
048: String readMethodExpression = "* " + lockClass + "*.read(..)";
049: String writeCountMethodExpression = "* " + lockClass
050: + "*.getWriteCount(..)";
051: String timeoutCountMethodExpression = "* " + lockClass
052: + "*.getTimeoutCount(..)";
053: String notifyCountMethodExpression = "* " + lockClass
054: + "*.getNotifyCount(..)";
055: String writeMethodExpression = "* " + lockClass + "*.write(..)";
056: String waitNotifyMethodExpression = "* " + lockClass
057: + "*.waitAndNotify(..)";
058:
059: config.addWriteAutolock(setIDMethodExpression);
060: config.addReadAutolock(readMethodExpression);
061: config.addReadAutolock(writeCountMethodExpression);
062: config.addReadAutolock(timeoutCountMethodExpression);
063: config.addReadAutolock(notifyCountMethodExpression);
064: config.addWriteAutolock(writeMethodExpression);
065: config.addWriteAutolock(waitNotifyMethodExpression);
066: spec.addRoot("locks", "locks");
067: spec.addRoot("barrier", "barrier");
068: new CyclicBarrierSpec().visit(visitor, config);
069: }
070:
071: public void run() {
072: name = Thread.currentThread().getName();
073:
074: setID();
075:
076: try {
077: barrier.barrier();
078: } catch (BrokenBarrierException e) {
079: e.printStackTrace();
080: } catch (InterruptedException e) {
081: e.printStackTrace();
082: }
083:
084: for (int i = id - 1; i < locks.size(); i++) {
085: LockObject lock = (LockObject) locks.get(i);
086: println(" Working on " + lock);
087: int read = 0, write = 0;
088:
089: // READ loop
090: for (int j = 0; j < count; j++) {
091: read = lock.read();
092: }
093: println(lock + ":: After Read loop :: " + read);
094:
095: // Write loop
096: for (int j = 0; j < count; j++) {
097: write = lock.write();
098: }
099: println(lock + ": After Write loop :: " + write);
100:
101: // Wait notify
102: for (int j = 0; j < count; j++) {
103: lock.waitAndNotify(toString());
104: }
105: println(lock + ": Timeouts :: " + lock.getTimeoutCount());
106: println(lock + ": Notifies :: " + lock.getNotifyCount());
107:
108: // READ, WRITE and Wait Notify
109: for (int j = 0; j < count; j++) {
110: read = lock.read();
111: write = lock.write();
112: lock.waitAndNotify(toString());
113: }
114: println(lock + ":: Reads :: " + read);
115: println(lock + ":: Writes :: " + write);
116: println(lock + ": Timeouts :: " + lock.getTimeoutCount());
117: println(lock + ": Notifies :: " + lock.getNotifyCount());
118: }
119: }
120:
121: private void println(String string) {
122: System.out.println(toString() + string);
123: }
124:
125: public String toString() {
126: return "Client(" + id + ")::" + name + "::";
127: }
128:
129: private void setID() {
130: synchronized (locks) {
131: if (id == 0) {
132: // first thread
133: id = locks.size() + 1;
134: locks.add(new LockObject(locks, id));
135: // count *= id;
136: }
137: }
138: }
139:
140: private static class LockObject {
141:
142: private List locks;
143: private int lockID;
144:
145: int writeCount = 0;
146: int waitCount = 0;
147: int timeoutCount = 0;
148: int notifiedCount = 0;
149:
150: LockObject(List list, int id) {
151: this .locks = list;
152: this .lockID = id;
153: }
154:
155: synchronized int read() {
156: int c = writeCount;
157: for (int i = 0; i < locks.size(); i++) {
158: LockObject lock = (LockObject) locks.get(i);
159: if (lock != this ) {
160: c += lock.getWriteCount();
161: }
162: }
163: return c;
164: }
165:
166: synchronized void waitAndNotify(String name) {
167: waitCount++;
168: try {
169: long start = System.currentTimeMillis();
170: wait(500);
171: if ((System.currentTimeMillis() - start) >= 500) {
172: timeoutCount++;
173: } else {
174: notifiedCount++;
175: }
176: } catch (InterruptedException e) {
177: e.printStackTrace();
178: }
179: waitCount--;
180: switch (waitCount % 3) {
181: case 0:
182: break;
183: case 1:
184: notify();
185: break;
186: case 2:
187: notifyAll();
188: }
189: }
190:
191: int getWriteCount() {
192: return writeCount;
193: }
194:
195: int getTimeoutCount() {
196: return timeoutCount;
197: }
198:
199: int getNotifyCount() {
200: return notifiedCount;
201: }
202:
203: synchronized int write() {
204: int c = ++writeCount;
205: for (int i = 0; i < locks.size(); i++) {
206: LockObject lock = (LockObject) locks.get(i);
207: if (lock != this ) {
208: c += lock.getWriteCount();
209: }
210: }
211: return c;
212: }
213:
214: int getID() {
215: return lockID;
216: }
217:
218: public String toString() {
219: return "LockObject(" + getID() + ")";
220: }
221: }
222:
223: }
|