dpdk: Add support for Mellanox ConnectX-4 devices
[vpp.git] / 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/fcntl.h>
24 #include <sys/mman.h>
25 #include <unistd.h>
26 #include <ctype.h>
27 #include <vppinfra/clib.h>
28 #include <vppinfra/vec.h>
29 #include <vppinfra/hash.h>
30 #include <vppinfra/elog.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->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, 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     if (argc < 3)
160         goto usage;
161
162     while (curarg < argc) {
163         if (!strncmp(argv[curarg], "--input-file", 3)) {
164             curarg++;
165             if (curarg < argc) {
166                 vec_add1 (inputfiles, argv[curarg]);
167                 curarg++;
168                 continue;
169             }
170             clib_warning("Missing filename after --input-file\n");
171             exit (1);
172         }
173
174         if (!strncmp(argv[curarg], "--output-file", 3)) {
175             curarg ++;
176             if (curarg < argc) {
177                 outputfile = argv[curarg];
178                 curarg ++;
179                 continue;
180             }
181             clib_warning("Missing filename after --output-file\n");
182             exit(1);
183         }
184         vec_add1 (inputfiles, argv[curarg]);
185         curarg++;
186         continue;
187
188     usage:
189         fformat(stderr, 
190                 "c2cpel [--input-file] <filename> --output-file <filename>\n");
191         exit(1);
192     }
193
194     if (vec_len(inputfiles) == 0 || outputfile == 0)
195         goto usage;
196         
197     if (vec_len(inputfiles) > 1)
198         goto usage;
199
200     cpel_util_init();
201
202     convert_clib_file (inputfiles[0]);
203
204     ofp = fopen (outputfile, "w");
205     if (ofp == NULL) {
206         clib_unix_warning ("couldn't create %s", outputfile);
207         exit (1);
208     }
209     
210     alpha_sort_tracks();
211     fixup_event_tracks();
212
213     /*
214      * Four sections: string-table, event definitions, track defs, events. 
215      */
216     if (!write_cpel_header(ofp, 4)) {
217         clib_warning ("Error writing cpel header to %s...\n", outputfile);
218         unlink(outputfile);
219         exit(1);
220     }
221
222     if (!write_string_table(ofp)) {
223         clib_warning ("Error writing string table to %s...\n", outputfile);
224         unlink(outputfile);
225         exit(1);
226     }
227
228     if (!write_event_defs(ofp)) {
229         clib_warning ("Error writing event defs to %s...\n", outputfile);
230         unlink(outputfile);
231         exit(1);
232     }
233
234     if (!write_track_defs(ofp)) {
235         clib_warning ("Error writing track defs to %s...\n", outputfile);
236         unlink(outputfile);
237         exit(1);
238     }
239
240     if (!write_events(ofp, (u64) 1e9)) {
241         clib_warning ("Error writing events to %s...\n", outputfile);
242         unlink(outputfile);
243         exit(1);
244         
245     }
246     fclose(ofp);
247     exit (0);
248 }