1 #include "TestLatency.h"
2
3 #include "IPDLUnitTests.h" // fail etc.
4
5 // A ping/pong trial takes O(100us) or more, so if we don't have 10us
6 // resolution or better, the results will not be terribly useful
7 static const double kTimingResolutionCutoff = 0.00001; // 10us
8
9 namespace mozilla {
10 namespace _ipdltest {
11
12 //-----------------------------------------------------------------------------
13 // parent
14
TestLatencyParent()15 TestLatencyParent::TestLatencyParent() :
16 mStart(),
17 mPPTimeTotal(),
18 mPP5TimeTotal(),
19 mRpcTimeTotal(),
20 mPPTrialsToGo(NR_TRIALS),
21 mPP5TrialsToGo(NR_TRIALS),
22 mNumChildProcessedCompressedSpams(0),
23 mWhichPong5(0)
24 {
25 MOZ_COUNT_CTOR(TestLatencyParent);
26 }
27
~TestLatencyParent()28 TestLatencyParent::~TestLatencyParent()
29 {
30 MOZ_COUNT_DTOR(TestLatencyParent);
31 }
32
33 void
Main()34 TestLatencyParent::Main()
35 {
36 TimeDuration resolution = TimeDuration::Resolution();
37 if (resolution.ToSeconds() > kTimingResolutionCutoff) {
38 puts(" (skipping TestLatency, timing resolution is too poor)");
39 Close();
40 return;
41 }
42
43 printf(" timing resolution: %g seconds\n",
44 resolution.ToSecondsSigDigits());
45
46 if (mozilla::ipc::LoggingEnabled())
47 MOZ_CRASH("you really don't want to log all IPC messages during this test, trust me");
48
49 PingPongTrial();
50 }
51
52 void
PingPongTrial()53 TestLatencyParent::PingPongTrial()
54 {
55 mStart = TimeStamp::Now();
56 if (!SendPing())
57 fail("sending Ping()");
58 }
59
60 void
Ping5Pong5Trial()61 TestLatencyParent::Ping5Pong5Trial()
62 {
63 mStart = TimeStamp::Now();
64
65 if (!SendPing5() ||
66 !SendPing5() ||
67 !SendPing5() ||
68 !SendPing5() ||
69 !SendPing5())
70 fail("sending Ping5()");
71 }
72
73 mozilla::ipc::IPCResult
RecvPong()74 TestLatencyParent::RecvPong()
75 {
76 TimeDuration thisTrial = (TimeStamp::Now() - mStart);
77 mPPTimeTotal += thisTrial;
78
79 if (0 == (mPPTrialsToGo % 1000))
80 printf(" PP trial %d: %g\n",
81 mPPTrialsToGo, thisTrial.ToSecondsSigDigits());
82
83 if (--mPPTrialsToGo > 0)
84 PingPongTrial();
85 else
86 Ping5Pong5Trial();
87 return IPC_OK();
88 }
89
90 mozilla::ipc::IPCResult
RecvPong5()91 TestLatencyParent::RecvPong5()
92 {
93 ++mWhichPong5;
94
95 // MOZ_ASSERT((PTestLatency::PING5 != state()) == (mWhichPong5 < 5));
96
97 if (mWhichPong5 < 5) {
98 return IPC_OK();
99 }
100
101 mWhichPong5 = 0;
102
103 TimeDuration thisTrial = (TimeStamp::Now() - mStart);
104 mPP5TimeTotal += thisTrial;
105
106 if (0 == (mPP5TrialsToGo % 1000))
107 printf(" PP5 trial %d: %g\n",
108 mPP5TrialsToGo, thisTrial.ToSecondsSigDigits());
109
110 if (0 < --mPP5TrialsToGo)
111 Ping5Pong5Trial();
112 else
113 RpcTrials();
114
115 return IPC_OK();
116 }
117
118 void
RpcTrials()119 TestLatencyParent::RpcTrials()
120 {
121 TimeStamp start = TimeStamp::Now();
122 for (int i = 0; i < NR_TRIALS; ++i) {
123 if (!CallRpc())
124 fail("can't call Rpc()");
125 if (0 == (i % 1000))
126 printf(" Rpc trial %d\n", i);
127 }
128 mRpcTimeTotal = (TimeStamp::Now() - start);
129
130 SpamTrial();
131 }
132
133 void
SpamTrial()134 TestLatencyParent::SpamTrial()
135 {
136 TimeStamp start = TimeStamp::Now();
137 for (int i = 0; i < NR_SPAMS - 1; ++i) {
138 if (!SendSpam())
139 fail("sending Spam()");
140 if (0 == (i % 10000))
141 printf(" Spam trial %d\n", i);
142 }
143
144 // Synchronize with the child process to ensure all messages have
145 // been processed. This adds the overhead of a reply message from
146 // child-->here, but should be insignificant compared to >>
147 // NR_SPAMS.
148 if (!CallSynchro())
149 fail("calling Synchro()");
150
151 mSpamTimeTotal = (TimeStamp::Now() - start);
152
153 CompressedSpamTrial();
154 }
155
156 void
CompressedSpamTrial()157 TestLatencyParent::CompressedSpamTrial()
158 {
159 for (int i = 0; i < NR_SPAMS; ++i) {
160 if (!SendCompressedSpam(i + 1))
161 fail("sending CompressedSpam()");
162 if (0 == (i % 10000))
163 printf(" CompressedSpam trial %d\n", i);
164 }
165
166 uint32_t lastSeqno;
167 if (!CallSynchro2(&lastSeqno, &mNumChildProcessedCompressedSpams))
168 fail("calling Synchro2()");
169
170 if (lastSeqno != NR_SPAMS)
171 fail("last seqno was %u, expected %u", lastSeqno, NR_SPAMS);
172
173 // NB: since this is testing an optimization, it's somewhat bogus.
174 // Need to make a warning if it actually intermittently fails in
175 // practice, which is doubtful.
176 if (!(mNumChildProcessedCompressedSpams < NR_SPAMS))
177 fail("Didn't compress any messages?");
178
179 Exit();
180 }
181
182 void
Exit()183 TestLatencyParent::Exit()
184 {
185 Close();
186 }
187
188 //-----------------------------------------------------------------------------
189 // child
190
TestLatencyChild()191 TestLatencyChild::TestLatencyChild()
192 : mLastSeqno(0)
193 , mNumProcessedCompressedSpams(0)
194 , mWhichPing5(0)
195 {
196 MOZ_COUNT_CTOR(TestLatencyChild);
197 }
198
~TestLatencyChild()199 TestLatencyChild::~TestLatencyChild()
200 {
201 MOZ_COUNT_DTOR(TestLatencyChild);
202 }
203
204 mozilla::ipc::IPCResult
RecvPing()205 TestLatencyChild::RecvPing()
206 {
207 SendPong();
208 return IPC_OK();
209 }
210
211 mozilla::ipc::IPCResult
RecvPing5()212 TestLatencyChild::RecvPing5()
213 {
214 ++mWhichPing5;
215
216 // MOZ_ASSERT((PTestLatency::PONG1 != state()) == (mWhichPing5 < 5));
217
218 if (mWhichPing5 < 5) {
219 return IPC_OK();
220 }
221
222 mWhichPing5 = 0;
223
224 if (!SendPong5() ||
225 !SendPong5() ||
226 !SendPong5() ||
227 !SendPong5() ||
228 !SendPong5())
229 fail("sending Pong5()");
230
231 return IPC_OK();
232 }
233
234 mozilla::ipc::IPCResult
AnswerRpc()235 TestLatencyChild::AnswerRpc()
236 {
237 return IPC_OK();
238 }
239
240 mozilla::ipc::IPCResult
RecvSpam()241 TestLatencyChild::RecvSpam()
242 {
243 // no-op
244 return IPC_OK();
245 }
246
247 mozilla::ipc::IPCResult
AnswerSynchro()248 TestLatencyChild::AnswerSynchro()
249 {
250 return IPC_OK();
251 }
252
253 mozilla::ipc::IPCResult
RecvCompressedSpam(const uint32_t & seqno)254 TestLatencyChild::RecvCompressedSpam(const uint32_t& seqno)
255 {
256 if (seqno <= mLastSeqno)
257 fail("compressed seqnos must monotonically increase");
258
259 mLastSeqno = seqno;
260 ++mNumProcessedCompressedSpams;
261 return IPC_OK();
262 }
263
264 mozilla::ipc::IPCResult
AnswerSynchro2(uint32_t * lastSeqno,uint32_t * numMessagesDispatched)265 TestLatencyChild::AnswerSynchro2(uint32_t* lastSeqno,
266 uint32_t* numMessagesDispatched)
267 {
268 *lastSeqno = mLastSeqno;
269 *numMessagesDispatched = mNumProcessedCompressedSpams;
270 return IPC_OK();
271 }
272
273 } // namespace _ipdltest
274 } // namespace mozilla
275