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 MOZ_COUNT_CTOR(TestLatencyParent);
25 }
26
~TestLatencyParent()27 TestLatencyParent::~TestLatencyParent() { MOZ_COUNT_DTOR(TestLatencyParent); }
28
Main()29 void TestLatencyParent::Main() {
30 TimeDuration resolution = TimeDuration::Resolution();
31 if (resolution.ToSeconds() > kTimingResolutionCutoff) {
32 puts(" (skipping TestLatency, timing resolution is too poor)");
33 Close();
34 return;
35 }
36
37 printf(" timing resolution: %g seconds\n", resolution.ToSecondsSigDigits());
38
39 if (mozilla::ipc::LoggingEnabled())
40 MOZ_CRASH(
41 "you really don't want to log all IPC messages during this test, trust "
42 "me");
43
44 PingPongTrial();
45 }
46
PingPongTrial()47 void TestLatencyParent::PingPongTrial() {
48 mStart = TimeStamp::Now();
49 if (!SendPing()) fail("sending Ping()");
50 }
51
Ping5Pong5Trial()52 void TestLatencyParent::Ping5Pong5Trial() {
53 mStart = TimeStamp::Now();
54
55 if (!SendPing5() || !SendPing5() || !SendPing5() || !SendPing5() ||
56 !SendPing5())
57 fail("sending Ping5()");
58 }
59
RecvPong()60 mozilla::ipc::IPCResult TestLatencyParent::RecvPong() {
61 TimeDuration thisTrial = (TimeStamp::Now() - mStart);
62 mPPTimeTotal += thisTrial;
63
64 if (0 == (mPPTrialsToGo % 1000))
65 printf(" PP trial %d: %g\n", mPPTrialsToGo,
66 thisTrial.ToSecondsSigDigits());
67
68 if (--mPPTrialsToGo > 0)
69 PingPongTrial();
70 else
71 Ping5Pong5Trial();
72 return IPC_OK();
73 }
74
RecvPong5()75 mozilla::ipc::IPCResult TestLatencyParent::RecvPong5() {
76 ++mWhichPong5;
77
78 if (mWhichPong5 < 5) {
79 return IPC_OK();
80 }
81
82 mWhichPong5 = 0;
83
84 TimeDuration thisTrial = (TimeStamp::Now() - mStart);
85 mPP5TimeTotal += thisTrial;
86
87 if (0 == (mPP5TrialsToGo % 1000))
88 printf(" PP5 trial %d: %g\n", mPP5TrialsToGo,
89 thisTrial.ToSecondsSigDigits());
90
91 if (0 < --mPP5TrialsToGo)
92 Ping5Pong5Trial();
93 else
94 RpcTrials();
95
96 return IPC_OK();
97 }
98
RpcTrials()99 void TestLatencyParent::RpcTrials() {
100 TimeStamp start = TimeStamp::Now();
101 for (int i = 0; i < NR_TRIALS; ++i) {
102 if (!CallRpc()) fail("can't call Rpc()");
103 if (0 == (i % 1000)) printf(" Rpc trial %d\n", i);
104 }
105 mRpcTimeTotal = (TimeStamp::Now() - start);
106
107 SpamTrial();
108 }
109
SpamTrial()110 void TestLatencyParent::SpamTrial() {
111 TimeStamp start = TimeStamp::Now();
112 for (int i = 0; i < NR_SPAMS - 1; ++i) {
113 if (!SendSpam()) fail("sending Spam()");
114 if (0 == (i % 10000)) printf(" Spam trial %d\n", i);
115 }
116
117 // Synchronize with the child process to ensure all messages have
118 // been processed. This adds the overhead of a reply message from
119 // child-->here, but should be insignificant compared to >>
120 // NR_SPAMS.
121 if (!CallSynchro()) fail("calling Synchro()");
122
123 mSpamTimeTotal = (TimeStamp::Now() - start);
124
125 CompressedSpamTrial();
126 }
127
CompressedSpamTrial()128 void TestLatencyParent::CompressedSpamTrial() {
129 for (int i = 0; i < NR_SPAMS; ++i) {
130 if (!SendCompressedSpam(i + 1)) fail("sending CompressedSpam()");
131 if (0 == (i % 10000)) printf(" CompressedSpam trial %d\n", i);
132 }
133
134 uint32_t lastSeqno;
135 if (!CallSynchro2(&lastSeqno, &mNumChildProcessedCompressedSpams))
136 fail("calling Synchro2()");
137
138 if (lastSeqno != NR_SPAMS)
139 fail("last seqno was %u, expected %u", lastSeqno, NR_SPAMS);
140
141 // NB: since this is testing an optimization, it's somewhat bogus.
142 // Need to make a warning if it actually intermittently fails in
143 // practice, which is doubtful.
144 if (!(mNumChildProcessedCompressedSpams < NR_SPAMS))
145 fail("Didn't compress any messages?");
146
147 Exit();
148 }
149
Exit()150 void TestLatencyParent::Exit() { Close(); }
151
152 //-----------------------------------------------------------------------------
153 // child
154
TestLatencyChild()155 TestLatencyChild::TestLatencyChild()
156 : mLastSeqno(0), mNumProcessedCompressedSpams(0), mWhichPing5(0) {
157 MOZ_COUNT_CTOR(TestLatencyChild);
158 }
159
~TestLatencyChild()160 TestLatencyChild::~TestLatencyChild() { MOZ_COUNT_DTOR(TestLatencyChild); }
161
RecvPing()162 mozilla::ipc::IPCResult TestLatencyChild::RecvPing() {
163 SendPong();
164 return IPC_OK();
165 }
166
RecvPing5()167 mozilla::ipc::IPCResult TestLatencyChild::RecvPing5() {
168 ++mWhichPing5;
169
170 if (mWhichPing5 < 5) {
171 return IPC_OK();
172 }
173
174 mWhichPing5 = 0;
175
176 if (!SendPong5() || !SendPong5() || !SendPong5() || !SendPong5() ||
177 !SendPong5())
178 fail("sending Pong5()");
179
180 return IPC_OK();
181 }
182
AnswerRpc()183 mozilla::ipc::IPCResult TestLatencyChild::AnswerRpc() { return IPC_OK(); }
184
RecvSpam()185 mozilla::ipc::IPCResult TestLatencyChild::RecvSpam() {
186 // no-op
187 return IPC_OK();
188 }
189
AnswerSynchro()190 mozilla::ipc::IPCResult TestLatencyChild::AnswerSynchro() { return IPC_OK(); }
191
RecvCompressedSpam(const uint32_t & seqno)192 mozilla::ipc::IPCResult TestLatencyChild::RecvCompressedSpam(
193 const uint32_t& seqno) {
194 if (seqno <= mLastSeqno)
195 fail("compressed seqnos must monotonically increase");
196
197 mLastSeqno = seqno;
198 ++mNumProcessedCompressedSpams;
199 return IPC_OK();
200 }
201
AnswerSynchro2(uint32_t * lastSeqno,uint32_t * numMessagesDispatched)202 mozilla::ipc::IPCResult TestLatencyChild::AnswerSynchro2(
203 uint32_t* lastSeqno, uint32_t* numMessagesDispatched) {
204 *lastSeqno = mLastSeqno;
205 *numMessagesDispatched = mNumProcessedCompressedSpams;
206 return IPC_OK();
207 }
208
209 } // namespace _ipdltest
210 } // namespace mozilla
211