misc: use right include for fctnl.h and poll.h
[vpp.git] / src / tools / perftool / c2cpel.c
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2006-2016 Cisco and/or its affiliates.
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 express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <netinet/in.h>
19 #include <string.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <sys/mman.h>
24 #include <unistd.h>
25 #include <ctype.h>
26 #include <vppinfra/clib.h>
27 #include <vppinfra/vec.h>
28 #include <vppinfra/hash.h>
29 #include <vppinfra/elog.h>
30 #include <vppinfra/mem.h>
31 #include <pwd.h>
32 #include <stdarg.h>
33 #include <time.h>
34 #include "cpel.h"
35 #include "cpel_util.h"
36
37 static elog_main_t elog_main;
38
39 /*
40  * convert_clib_file
41  */
42 void convert_clib_file(char *clib_file)
43 {
44     clib_error_t *error = 0;
45     int i;
46     elog_main_t *em = &elog_main;
47     double starttime, delta;
48
49     error = elog_read_file (&elog_main, clib_file);
50
51     if (error) {
52         clib_warning("%U", format_clib_error, error);
53         exit (1);
54     }
55
56     em = &elog_main;
57
58     starttime = em->events[0].time;
59
60     for (i = 0; i < vec_len (em->events); i++) {
61         elog_event_t *e;        /* clib event */
62         evt_t *ep;              /* xxx2cpel event */
63         u8 *s;
64         u64 timestamp;
65         elog_event_type_t *t;
66         u8 *brief_event_name;
67         u8 *track_name;
68         int j;
69
70         e = vec_elt_at_index(em->events, i);
71
72         /* Seconds since start of log */
73         delta = e->time - starttime;
74
75         /* u64 nanoseconds since start of log */
76         timestamp = delta * 1e9;
77
78         s = format (0, "%U%c", format_elog_event, em, e, 0);
79
80         /* allocate an event instance */
81         vec_add2(the_events, ep, 1);
82         ep->timestamp = timestamp;
83
84         /* convert string event code to a real number */
85         t = vec_elt_at_index (em->event_types, e->event_type);
86
87         /*
88          * Construct a reasonable event name.
89          * Truncate the format string at the first whitespace break
90          * or printf format character.
91          */
92         brief_event_name = format (0, "%s", t->format);
93
94         for (j = 0; j < vec_len (brief_event_name); j++) {
95             if (brief_event_name[j] == ' ' ||
96                 brief_event_name[j] == '%' ||
97                 brief_event_name[j] == '(') {
98                 brief_event_name[j] = 0;
99                 break;
100             }
101         }
102         /* Throw away that much of the formatted event */
103         vec_delete (s, j+1, 0);
104
105         ep->event_id = find_or_add_event(brief_event_name, "%s");
106
107         track_name = format (0, "%U%c", format_elog_track_name, em, e, 0);
108
109         ep->track_id = find_or_add_track (track_name);
110
111         ep->datum = find_or_add_strtab(s);
112
113         vec_free (track_name);
114         vec_free(brief_event_name);
115         vec_free(s);
116     }
117 }
118
119 u8 *vec_basename (char *s)
120 {
121     u8 * rv;
122     char *cp = s;
123
124     while (*cp)
125         cp++;
126
127     cp--;
128
129     while (cp > s && *cp != '/')
130         cp--;
131
132     if (cp > s)
133         cp++;
134
135     rv = format (0, "%s", cp);
136     return rv;
137 }
138
139
140 int event_compare (const void *a0, const void *a1)
141 {
142     evt_t *e0 = (evt_t *)a0;
143     evt_t *e1 = (evt_t *)a1;
144
145     if (e0->timestamp < e1->timestamp)
146         return -1;
147     else if (e0->timestamp > e1->timestamp)
148         return 1;
149     return 0;
150 }
151
152 int main (int argc, char **argv)
153 {
154     int curarg=1;
155     char **inputfiles = 0;
156     char *outputfile = 0;
157     FILE *ofp;
158
159     clib_mem_init_thread_safe (0, 256 << 20);
160
161     if (argc < 3)
162         goto usage;
163
164     while (curarg < argc) {
165         if (!strncmp(argv[curarg], "--input-file", 3)) {
166             curarg++;
167             if (curarg < argc) {
168                 vec_add1 (inputfiles, argv[curarg]);
169                 curarg++;
170                 continue;
171             }
172             clib_warning("Missing filename after --input-file\n");
173             exit (1);
174         }
175
176         if (!strncmp(argv[curarg], "--output-file", 3)) {
177             curarg ++;
178             if (curarg < argc) {
179                 outputfile = argv[curarg];
180                 curarg ++;
181                 continue;
182             }
183             clib_warning("Missing filename after --output-file\n");
184             exit(1);
185         }
186         vec_add1 (inputfiles, argv[curarg]);
187         curarg++;
188         continue;
189
190     usage:
191         fformat(stderr,
192                 "c2cpel [--input-file] <filename> --output-file <filename>\n");
193         exit(1);
194     }
195
196     if (vec_len(inputfiles) == 0 || outputfile == 0)
197         goto usage;
198
199     if (vec_len(inputfiles) > 1)
200         goto usage;
201
202     clib_mem_init (0, ((uword)3<<30));
203
204     cpel_util_init();
205
206     convert_clib_file (inputfiles[0]);
207
208     ofp = fopen (outputfile, "w");
209     if (ofp == NULL) {
210         clib_unix_warning ("couldn't create %s", outputfile);
211         exit (1);
212     }
213
214     alpha_sort_tracks();
215     fixup_event_tracks();
216
217     /*
218      * Four sections: string-table, event definitions, track defs, events.
219      */
220     if (!write_cpel_header(ofp, 4)) {
221         clib_warning ("Error writing cpel header to %s...\n", outputfile);
222         unlink(outputfile);
223         exit(1);
224     }
225
226     if (!write_string_table(ofp)) {
227         clib_warning ("Error writing string table to %s...\n", outputfile);
228         unlink(outputfile);
229         exit(1);
230     }
231
232     if (!write_event_defs(ofp)) {
233         clib_warning ("Error writing event defs to %s...\n", outputfile);
234         unlink(outputfile);
235         exit(1);
236     }
237
238     if (!write_track_defs(ofp)) {
239         clib_warning ("Error writing track defs to %s...\n", outputfile);
240         unlink(outputfile);
241         exit(1);
242     }
243
244     if (!write_events(ofp, (u64) 1e9)) {
245         clib_warning ("Error writing events to %s...\n", outputfile);
246         unlink(outputfile);
247         exit(1);
248
249     }
250     fclose(ofp);
251     exit (0);
252 }