1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18
19 /*!
20 ** Socket statistics
21 */
22
23 #include "oscl_socket_tuneables.h"
24 #if(PV_OSCL_SOCKET_STATS_LOGGING)
25 #include "oscl_socket_stats.h"
26 #include "oscl_tickcount.h"
27 #include "pvlogger.h"
28 #include "oscl_socket_tuneables.h"
29 #include "oscl_scheduler_ao.h"
30 #include "oscl_snprintf.h"
31
32 #define LOGINFOMED(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG,iLogger,PVLOGMSG_DEBUG,m);
33
34 #define PV_SOCKET_STR_LEN 512
35
36 static const char* const TPVSocketFxnStrShort[] =
37 {
38 "Send "
39 , "SendTo "
40 , "Recv "
41 , "RecvFrom"
42 , "Connect "
43 , "Accept "
44 , "Shutdown"
45 , "Bind"
46 , "Listen"
47 } ;
48
OsclSocketStats()49 OsclSocketStats::OsclSocketStats()
50 {
51 iLogStr = (char*)OSCL_MALLOC(PV_SOCKET_STR_LEN);
52 iLogger = PVLogger::GetLoggerObject("OsclSocketStats");
53 iSock = NULL;
54 iServ = NULL;
55 for (uint32 i = 0; i < OsclSocketStats_NUM_ACTIVE_REQUESTS; i++)
56 {
57 iLastCompletionTime[i] = (-1);
58 iExcessPollEvents[i] = 0;
59 }
60 }
~OsclSocketStats()61 OsclSocketStats::~OsclSocketStats()
62 {
63 if (iLogStr)
64 OSCL_FREE(iLogStr);
65 }
Construct(OsclAny * aContainer,OsclAny * aServ)66 void OsclSocketStats::Construct(OsclAny* aContainer, OsclAny*aServ)
67 {
68 iSock = aContainer;
69 iServ = aServ;
70 }
71
Add(TPVSocketFxn aFxn,TOsclSocketStatEvent aEvent,int32 aParam)72 void OsclSocketStats::Add(TPVSocketFxn aFxn, TOsclSocketStatEvent aEvent, int32 aParam)
73 {
74 iLock.Lock();
75 if (aEvent == EOsclSocket_ServPoll)
76 {
77 if (iPollEvents[aFxn].size() >= OsclSocketStats_MAX_POLL_EVENTS)
78 {//to avoid having the poll events vector grow without bound
79 iExcessPollEvents[aFxn]++;
80 }
81 else
82 {
83 OsclSocketStatEventEntry event(aEvent, OsclTickCount::TickCount(), iEvents[aFxn].size());
84 iPollEvents[aFxn].push_back(event);
85 }
86 }
87 else
88 {
89 OsclSocketStatEventEntry event(aEvent, OsclTickCount::TickCount(), aParam);
90 iEvents[aFxn].push_back(event);
91 }
92 iLock.Unlock();
93 }
Clear(TPVSocketFxn aFxn)94 void OsclSocketStats::Clear(TPVSocketFxn aFxn)
95 {
96 iLock.Lock();
97 if (iEvents[aFxn].size())
98 iLastCompletionTime[aFxn] = iEvents[aFxn][iEvents[aFxn].size() - 1].iTicks;
99 iEvents[aFxn].clear();
100 iPollEvents[aFxn].clear();
101 iExcessPollEvents[aFxn] = 0;
102 iLock.Unlock();
103 }
104
Log(TPVSocketFxn aFxn)105 void OsclSocketStats::Log(TPVSocketFxn aFxn)
106 {
107 //log events
108 {
109 int32 len = 0;
110 iLogStr[0] = '\0';
111 for (uint32 i = 0; i < iEvents[aFxn].size(); i++)
112 {
113 if (PV_SOCKET_STR_LEN - len <= 0)
114 break;
115 if (iEvents[aFxn][i].iParam != (-1))
116 {
117 //log event with a parameter
118 len += oscl_snprintf(iLogStr + len, PV_SOCKET_STR_LEN - len, "%s (n=%d) %d "
119 , TPVSocketStatStr[iEvents[aFxn][i].iEvent]
120 , iEvents[aFxn][i].iParam
121 , iEvents[aFxn][i].iTicks);
122 }
123 else
124 {
125 //log event with no parameter
126 len += oscl_snprintf(iLogStr + len, PV_SOCKET_STR_LEN - len, "%s %d "
127 , TPVSocketStatStr[iEvents[aFxn][i].iEvent]
128 , iEvents[aFxn][i].iTicks);
129 }
130 }
131 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x,Sock=0x%x): %s delta=%d, %s"
132 , iServ, iSock
133 , TPVSocketFxnStrShort[aFxn]
134 , (iLastCompletionTime[aFxn] == (-1)) ? (-1) : iEvents[aFxn][iEvents[aFxn].size() - 1].iTicks - iLastCompletionTime[aFxn]
135 , iLogStr));
136 }
137
138 //log polling events
139 {
140 int32 len = 0;
141 iLogStr[0] = '\0';
142 int32 lastIndex = (-1);
143 for (uint32 i = 0; i < iPollEvents[aFxn].size(); i++)
144 {
145 if (PV_SOCKET_STR_LEN - len <= 0)
146 break;
147 if (iPollEvents[aFxn][i].iParam != lastIndex)
148 {
149 //log polling index plus times.
150 len += oscl_snprintf(iLogStr + len, PV_SOCKET_STR_LEN - len, "(%d) %d "
151 , iPollEvents[aFxn][i].iParam
152 , iPollEvents[aFxn][i].iTicks
153 );
154 }
155 else
156 {
157 //log time only
158 len += oscl_snprintf(iLogStr + len, PV_SOCKET_STR_LEN - len, "%d "
159 , iPollEvents[aFxn][i].iTicks
160 );
161 }
162 lastIndex = iPollEvents[aFxn][i].iParam;
163 }
164 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x,Sock=0x%x): %s Poll=%d, Times %s"
165 , iServ, iSock
166 , TPVSocketFxnStrShort[aFxn]
167 , iPollEvents[aFxn].size()
168 , iLogStr));
169 if (iExcessPollEvents[aFxn] > 0)
170 {
171 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x,Sock=0x%x): %s Num ExcessPollEvents=%d"
172 , iServ, iSock
173 , TPVSocketFxnStrShort[aFxn]
174 , iExcessPollEvents[aFxn]
175 ));
176 }
177 }
178 }
179
Log()180 void OsclSocketStats::Log()
181 {
182 //log events not related to a particular socket API
183 {
184 int32 len = 0;
185 iLogStr[0] = '\0';
186 for (uint32 i = 0; i < iEvents[0].size(); i++)
187 {
188 if (PV_SOCKET_STR_LEN - len <= 0)
189 break;
190 if (iEvents[0][i].iParam != (-1))
191 {
192 //log event with a parameter
193 len += oscl_snprintf(iLogStr + len, PV_SOCKET_STR_LEN - len, "%s (n=%d) %d "
194 , TPVSocketStatStr[iEvents[0][i].iEvent]
195 , iEvents[0][i].iParam
196 , iEvents[0][i].iTicks);
197 }
198 else
199 {
200 //log event with no parameter
201 len += oscl_snprintf(iLogStr + len, PV_SOCKET_STR_LEN - len, "%s %d "
202 , TPVSocketStatStr[iEvents[0][i].iEvent]
203 , iEvents[0][i].iTicks);
204 }
205 }
206 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x,Sock=0x%x): %s"
207 , iServ, iSock
208 , iLogStr));
209 }
210 }
211
LogAndDump()212 void OsclSocketStats::LogAndDump()
213 {
214 for (uint32 i = 0; i < OsclSocketStats_NUM_ACTIVE_REQUESTS; i++)
215 {
216 if (iEvents[i].size()
217 || iPollEvents[i].size())
218 {
219 Log((TPVSocketFxn)i);
220 }
221 Clear((TPVSocketFxn)i);
222 }
223 }
224
225
OsclSocketServStats()226 OsclSocketServStats::OsclSocketServStats()
227 {
228 iLogger = PVLogger::GetLoggerObject("OsclSocketStats");
229 iServ = NULL;
230 Clear();
231 }
~OsclSocketServStats()232 OsclSocketServStats::~OsclSocketServStats()
233 {
234 }
Construct(OsclAny * aServ)235 void OsclSocketServStats::Construct(OsclAny*aServ)
236 {
237 iServ = aServ;
238 }
239
ShowTuneables()240 void OsclSocketServStats::ShowTuneables()
241 {
242 //Log socket server type
243 #if (PV_SOCKET_SERVER)
244 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x): Socket Server: PV Socket Server", iServ));
245 #else
246 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x): Socket Server: Unknown Socket Server", iServ));
247 #endif
248 //Log socket request AO priority
249 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x): Socket Request AO Priority %d"
250 , iServ
251 , PV_SOCKET_REQUEST_AO_PRIORITY));
252
253 #if(PV_SOCKET_SERVER)
254 //Log pv socket server type
255 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x): Socket Server is %s"
256 , iServ
257 , (PV_SOCKET_SERVER_IS_THREAD) ? "Threaded" : "AO-Based"
258 ));
259 #if(PV_SOCKET_SERVER_IS_THREAD)
260 //pv server threaded params
261 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x): Socket Server Thread Priority %d", iServ, PV_SOCKET_SERVER_THREAD_PRIORITY));
262 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x): Socket Server Select Timeout (msec) %d", iServ, PV_SOCKET_SERVER_SELECT_TIMEOUT_MSEC));
263 #else
264 //pv server AO-based params
265 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x): Socket Server AO Priority %d", iServ, PV_SOCKET_SERVER_AO_PRIORITY));
266 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x): Socket Server AO Polling Interval (msec) %d", iServ, PV_SOCKET_SERVER_AO_INTERVAL_MSEC));
267 #endif
268
269 //pv Server logging
270 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x): Socket Server Logging %s"
271 , iServ
272 , (PV_OSCL_SOCKET_SERVER_LOGGER_OUTPUT) ? "Enabled" : "Disabled"));
273
274 #endif//PV_SOCKET_SERVER
275 }
276
Add(TOsclSocketServStatEvent aEvent)277 void OsclSocketServStats::Add(TOsclSocketServStatEvent aEvent)
278 {
279 iEvents[aEvent]++;
280 }
281
Log(TOsclSocketServStatEvent aEvent)282 void OsclSocketServStats::Log(TOsclSocketServStatEvent aEvent)
283 {
284 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x): Event %s Count %d"
285 , iServ
286 , TPVSocketServStatStr[aEvent]
287 , iEvents[aEvent]));
288 }
289
Clear()290 void OsclSocketServStats::Clear()
291 {
292 for (uint32 i = 0; i < EOsclSocketServ_LastEvent; i++)
293 iEvents[i] = 0;
294 }
295
LogAndDump()296 void OsclSocketServStats::LogAndDump()
297 {
298 if (!iServ)
299 return;
300 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x): ---Begin Stats--------", iServ));
301 ShowTuneables();
302 for (uint32 i = 0; i < EOsclSocketServ_LastEvent; i++)
303 Log((TOsclSocketServStatEvent)i);
304 LOGINFOMED((0, "OsclSocketStats(Serv=0x%x): ---End Stats----------", iServ));
305 Clear();
306 //this acts as thread logoff
307 iServ = NULL;
308 }
309
310 #endif
311
312
313
314
315
316
317