travis: Add a Windows 32-bit variant build test
[strongswan.git] / scripts / thread_analysis.c
1 /* Analyzes the concurrent use of charon's threads
2 *
3 * Copyright (C) 2008 Andreas Steffen
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 #define LOGFILE "moon.daemon.log"
22 #define LINE_LEN 2048
23 #define THREADS 99
24
25 typedef enum state_t state_t;
26
27 enum state_t {
28 STATE_IDLE = 0,
29 STATE_INIT = 1,
30 STATE_AUTH = 2,
31 STATE_BUSY = 3,
32 STATE_RETRY = 4,
33 STATE_ERROR = 5
34 };
35
36 typedef enum print_t print_t;
37
38 enum print_t {
39 MODE_ANY = 0,
40 MODE_ADD = 1,
41 MODE_DEL = 2
42 };
43
44 static char *state_names[] = { "idle", "init", "auth", "busy", "retry", "error" };
45
46 static int readline(FILE *fd, char *line)
47 {
48 while (fread(line, 1, 1, fd))
49 {
50 if (*line == '\n')
51 {
52 *line = '\0';
53 return 1;
54 }
55 line++;
56 }
57 *line = '\0';
58 return 0;
59 }
60
61 static void printline(state_t *state, char *timestamp)
62 {
63 int states[] = { 0, 0, 0, 0, 0};
64 int th, total ;
65
66 printf(" <tr>\n");
67 printf(" <td class=\"log\">%.15s</td>", timestamp);
68
69 for (th = 1; th <= THREADS; th++)
70 {
71 states[state[th]]++;
72 printf("<td class=\"%s\"></td>", state_names[state[th]]);
73 }
74 total = states[STATE_INIT] + states[STATE_AUTH] + states[STATE_BUSY] + states[STATE_RETRY];
75 printf("<td class=\"init\">%d</td><td class=\"auth\">%d</td><td class=\"busy\">%d</td>",
76 states[STATE_INIT], states[STATE_AUTH], total);
77 for (th = 10; th <= (THREADS + 2); th += 5)
78 {
79 printf("<td class=\"%s\"></td>", (th <= total + 2)? "busy":"idle");
80 }
81 printf("\n");
82 printf(" </tr>\n");
83 }
84
85 int main(int argc, char *argv[])
86 {
87 char line[LINE_LEN];
88 int section = 0;
89 int mode = MODE_ANY;
90 int th;
91 FILE *fd;
92
93 state_t state[THREADS + 1];
94
95 /* threads 1..5 and 9 are always busy */
96 for (th = 1; th <= THREADS; th++)
97 {
98 state[th] = (th <= 7 && th != 3)? STATE_BUSY : STATE_IDLE;
99 }
100
101 /* open the log file */
102 fd = fopen(LOGFILE, "r");
103 if (!fd)
104 {
105 printf("could not open log file '%s'\n", LOGFILE);
106 return 1;
107 }
108
109 printf("<html>\n");
110 printf("<head>\n");
111 printf(" <title>Charon Thread Analysis</title>\n");
112 printf(" <style>\n");
113 printf(" body { font: 11px verdana,arial, helvetica, sans-serif }\n");
114 printf(" td { font: 10px verdana,arial, helvetica, sans-serif;\n");
115 printf(" text-align: center; padding: 0px 1px 0px 1px; background: #FFFF66 }\n");
116 printf(" td.log { text-align: left; background: #FFFF66; white-space: nowrap }\n");
117 printf(" td.idle { background: #FFFF66 }\n");
118 printf(" td.init { background: #FFA522 }\n");
119 printf(" td.auth { background: #90EE90 }\n");
120 printf(" td.busy { background: #ADD8E6 }\n");
121 printf(" td.retry { background: #7B68EE }\n");
122 printf(" td.error { background: #FF6347 }\n");
123 printf(" hr { background-color: #000000; border: 0; height: 1px; }\n");
124 printf(" a:visited { color: #000000 }\n");
125 printf(" a:link { color: #000000 }\n");
126 printf(" a:hover { color: #0000FF }\n");
127 printf(" </style>\n");
128 printf("</head>\n");
129 printf("<body>\n");
130 printf(" <h1>Charon Thread Analysis</h1>\n");
131 printf(" <table>\n");
132
133 /* print table header */
134 printf(" <tr>\n");
135 printf(" <td class=\"log\">Timestamp</td>");
136 for (th = 1 ; th <= THREADS; th++)
137 {
138 printf("<td>%02d</td>", th);
139 }
140 printf("<td class=\"init\">I</td><td class=\"auth\">A</td><td class=\"busy\">B</td>");
141 for (th = 10; th <= (THREADS + 2); th += 5)
142 {
143 printf("<td class=\"busy\">%d</td>", (th == 100)? 99:th);
144 }
145 printf("\n");
146 printf(" </tr>\n");
147
148 while (readline(fd, line))
149 {
150 char *p_section, *p_charon, *p_thread, *p_log;
151
152 p_section = strstr(line, "---");
153 if (p_section)
154 {
155 printline(state, line);
156 mode = MODE_ANY;
157
158 if (section++ < 1)
159 {
160 continue;
161 }
162 else
163 {
164 break;
165 }
166 }
167
168 p_charon = strstr(line, "charon");
169 if (!p_charon)
170 {
171 continue;
172 }
173
174 /* determine thread */
175 p_thread = p_charon + 8;
176 th = atol(p_thread);
177
178 /* determine log message */
179 p_log = p_charon + 16;
180 if (strstr(p_log, "received packet"))
181 {
182 if (mode == MODE_DEL)
183 {
184 printline(state, line);
185 }
186 mode = MODE_ADD;
187 if (state[th] != STATE_IDLE)
188 {
189 state[th] = STATE_ERROR;
190 }
191 else
192 {
193 state[th] = STATE_BUSY;
194 }
195 }
196 if (strstr(p_log, "sending packet"))
197 {
198 if (mode == MODE_ADD)
199 {
200 printline(state, line);
201 }
202 mode = MODE_DEL;
203 if (state[th] == STATE_IDLE)
204 {
205 state[th] = STATE_ERROR;
206 }
207 else
208 {
209 state[th] = STATE_IDLE;
210 }
211 }
212 if (strstr(p_log, "parsed IKE_SA_INIT request"))
213 {
214 if (state[th] != STATE_BUSY)
215 {
216 state[th] = STATE_ERROR;
217 }
218 else
219 {
220 state[th] = STATE_INIT;
221 }
222 }
223 if (strstr(p_log, "parsed IKE_AUTH request"))
224 {
225 if (state[th] != STATE_BUSY)
226 {
227 state[th] = STATE_ERROR;
228 }
229 else
230 {
231 state[th] = STATE_AUTH;
232 }
233 }
234 if (strstr(p_log, "already processing"))
235 {
236 if (state[th] != STATE_IDLE)
237 {
238 state[th] = STATE_ERROR;
239 }
240 else
241 {
242 state[th] = STATE_RETRY;
243 }
244 printline(state, line);
245 mode = MODE_ANY;
246 state[th] = STATE_IDLE;
247 }
248 }
249 printf(" </table>\n");
250 printf(" <p>\n");
251 printf(" <table>\n");
252 printf(" <tr>\n");
253 printf(" <td class=\"init\">&nbsp;I&nbsp;</td><td>IKE_SA_INIT Thread &nbsp;</td>\n");
254 printf(" <td class=\"auth\">&nbsp;A&nbsp;</td><td>IKE_AUTH Thread &nbsp;</td>\n");
255 printf(" <td class=\"retry\">&nbsp;R&nbsp;</td><td>Retransmit Thread &nbsp;</td>\n");
256 printf(" <td class=\"busy\">&nbsp;B&nbsp;</td><td>Busy Thread &nbsp;</td>\n");
257 printf(" <td class=\"error\">&nbsp;E&nbsp;</td><td>State Error &nbsp;</td>\n");
258 printf(" </tr>\n");
259 printf(" </table>\n");
260 printf(" <p>\n");
261 printf(" <hr/>\n");
262 printf(" <em>&copy; 2008\n");
263 printf(" <a href=\"http://ita.hsr.ch?&L=1\" target=\"popup\">\n");
264 printf(" ITA Institute for Internet Technologies and Applications</a> -\n");
265 printf(" <a href=\"http://www.hsr.ch/?&L=1\" target=\"popup\">\n");
266 printf(" HSR Hochschule f&uuml;r Technik Rapperswil</a>\n");
267 printf(" </em>\n");
268 printf("</body>\n");
269 printf("</html>\n");
270
271 fclose(fd);
272 return 0;
273 }