ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/RLIBar.java
Revision: 1.9
Committed: Thu Jan 15 18:34:19 2015 UTC (9 years, 3 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.8: +0 -4 lines
Log Message:
delete extraneous blank lines

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6 // Adapted from code that was in turn
7 // Derived from SocketPerformanceTest.java - BugID: 4763450
8 //
9 //
10
11 import java.io.*;
12 import java.net.*;
13 import java.util.concurrent.*;
14 import java.util.concurrent.locks.*;
15
16 public class RLIBar {
17
18 static int batchLimit;
19 static int mseq;
20 static int nReady;
21 static int ExThreads;
22 static int ASum;
23 static final ReentrantLock Gate = new ReentrantLock();
24 static final Condition GateCond = Gate.newCondition();
25
26 static final ReentrantLock HoldQ = new ReentrantLock();
27 static final Condition HoldQCond = HoldQ.newCondition();
28 static boolean Hold = false;
29 static int HoldPop;
30 static int HoldLimit;
31
32 private static boolean HoldCheck() {
33 try {
34 HoldQ.lock();
35 try {
36 if (!Hold) return false;
37 else {
38 ++HoldPop;
39 if (HoldPop >= HoldLimit) {
40 System.out.print("Holding ");
41 Thread.sleep(1000);
42 System.out.println();
43 Hold = false;
44 HoldQCond.signalAll();
45 }
46 else
47 while (Hold)
48 HoldQCond.await();
49
50 if (--HoldPop == 0) HoldQCond.signalAll();
51 return true;
52 }
53 }
54 finally {
55 HoldQ.unlock();
56 }
57 } catch (Exception Ex) {
58 System.out.println("Unexpected exception in Hold: " + Ex);
59 return false;
60 }
61 }
62
63 private static class Server {
64 private int nClients;
65 final ReentrantLock thisLock = new ReentrantLock();
66 final Condition thisCond = thisLock.newCondition();
67
68 Server(int nClients) {
69 this.nClients = nClients;
70 try {
71 for (int i = 0; i < nClients; ++i) {
72 final int fix = i;
73 new Thread() { public void run() { runServer(fix); }}.start();
74 }
75 } catch (Exception e) {
76 System.err.println(e);
77 }
78 }
79
80 // the total number of messages received by all server threads
81 // on this server
82 int msgsReceived = 0;
83
84 // incremented each time we get a complete batch of requests
85 private int currentBatch = 0;
86
87 // the number of requests received since the last time currentBatch
88 // was incremented
89 private int currentBatchSize = 0;
90
91 private void runServer(int id) {
92 int msg;
93 boolean held = false;
94 final ReentrantLock thisLock = this.thisLock;
95 final Condition thisCond = this.thisCond;
96
97 try {
98
99 // Startup barrier - rendezvous - wait for all threads.
100 // Forces all threads to park on their LWPs, ensuring
101 // proper provisioning on T1.
102 // Alternately, use THR_BOUND threads
103 Gate.lock(); try {
104 ++nReady;
105 if (nReady == ExThreads) {
106 GateCond.signalAll();
107 }
108 while (nReady != ExThreads)
109 GateCond.await();
110 } finally { Gate.unlock(); }
111
112 for (;;) {
113 // if (!held && currentBatchSize == 0) held = HoldCheck ();
114 msg = (++ mseq) ^ id;
115 thisLock.lock();
116 try {
117 ASum += msg;
118 ++msgsReceived;
119 int myBatch = currentBatch;
120 if (++currentBatchSize >= batchLimit) {
121 // this batch is full, start a new one ...
122 ++currentBatch;
123 currentBatchSize = 0;
124 // and wake up everyone in this one
125 thisCond.signalAll();
126 }
127 // Wait until our batch is complete
128 while (myBatch == currentBatch)
129 thisCond.await();
130 }
131 finally {
132 thisLock.unlock();
133 }
134 }
135 } catch (Exception e) {
136 System.err.println("Server thread: exception " + e);
137 e.printStackTrace();
138 }
139 }
140 }
141
142 public static void main(String[] args) throws Exception {
143 int nServers = 10;
144 int nClients = 10;
145 int samplePeriod = 10000;
146 int nSamples = 5;
147
148 int nextArg = 0;
149 while (nextArg < args.length) {
150 String arg = args[nextArg++];
151 if (arg.equals("-nc"))
152 nClients = Integer.parseInt(args[nextArg++]);
153 else if (arg.equals("-ns"))
154 nServers = Integer.parseInt(args[nextArg++]);
155 else if (arg.equals("-batch"))
156 batchLimit = Integer.parseInt(args[nextArg++]);
157 else if (arg.equals("-sample"))
158 samplePeriod = Integer.parseInt(args[nextArg++]);
159 else if (arg.equals("-np"))
160 nSamples = Integer.parseInt(args[nextArg++]);
161 else {
162 System.err.println("Argument error:" + arg);
163 System.exit(1);
164 }
165 }
166 if (nClients <= 0 || nServers <= 0 || samplePeriod <= 0 || batchLimit > nClients) {
167 System.err.println("Argument error");
168 System.exit(1);
169 }
170
171 // default batch size is 2/3 the number of clients
172 // (for no particular reason)
173 if (false && batchLimit <= 0)
174 batchLimit = (2 * nClients + 1) / 3;
175
176 ExThreads = nServers * nClients; // expected # of threads
177 HoldLimit = ExThreads;
178
179 // start up all threads
180 Server[] servers = new Server[nServers];
181 for (int i = 0; i < nServers; ++i) {
182 servers[i] = new Server(nClients);
183 }
184
185 // Wait for consensus
186 try {
187 Gate.lock(); try {
188 while (nReady != ExThreads ) GateCond.await();
189 } finally { Gate.unlock(); }
190 } catch (Exception ex) {
191 System.out.println(ex);
192 }
193 System.out.println(
194 nReady + " Ready: nc=" + nClients + " ns=" + nServers + " batch=" + batchLimit);
195
196 // Start sampling ...
197 // Methodological problem: all the mutator threads
198 // can starve the compiler threads, resulting in skewed scores.
199 // In theory, over time, the scores will improve as the compiler
200 // threads are granted CPU cycles, but in practice a "warm up" phase
201 // might be good idea to help C2. For this reason I've implemented
202 // the "Hold" facility.
203
204 long lastNumMsgs = 0;
205 long sampleStart = System.currentTimeMillis();
206 for (int j = 0; j < nSamples; ++j) {
207 // when this sample period is supposed to end
208 long sampleEnd = sampleStart + samplePeriod;
209 for (;;) {
210 long now = System.currentTimeMillis();
211 if (now >= sampleEnd) {
212 // when it really did end
213 sampleEnd = now;
214 break;
215 }
216 Thread.sleep(sampleEnd - now);
217 }
218
219 if (false && j == 2) {
220 System.out.print("Hold activated ...");
221 HoldQ.lock();
222 try {
223 Hold = true;
224 while (Hold) HoldQCond.await();
225 }
226 finally {
227 HoldQ.unlock();
228 }
229 }
230
231 // there's no synchronization here, so the total i get is
232 // approximate, but that's OK since any i miss for this
233 // sample will get credited to the next sample, and on average
234 // we'll be right
235 long numMsgs = 0;
236 for (int i = 0; i < nServers; ++i)
237 numMsgs += servers[i].msgsReceived;
238 long deltaMsgs = numMsgs - lastNumMsgs;
239 long deltaT = sampleEnd - sampleStart;
240 if (true || j != 2) { // Don't report results if we issued a hold ...
241 System.out.print(
242 "Sample period = " + deltaT + " ms; "
243 + "New msgs rcvd = " + deltaMsgs + "; "
244 + "Throughput = " + (deltaMsgs*1000 / deltaT) + " msg/sec\n");
245 // for (int i = 0; i < nServers; ++i)
246 // servers[i].thisLock.dump();
247 }
248 sampleStart = sampleEnd;
249 lastNumMsgs = numMsgs;
250 }
251 System.exit(0);
252 }
253 }