diff options
Diffstat (limited to 'perftool/c2cpel.c')
-rw-r--r-- | perftool/c2cpel.c | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/perftool/c2cpel.c b/perftool/c2cpel.c new file mode 100644 index 00000000000..38e6fe52e55 --- /dev/null +++ b/perftool/c2cpel.c @@ -0,0 +1,248 @@ +/* + *------------------------------------------------------------------ + * Copyright (c) 2006-2016 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stdio.h> +#include <stdlib.h> +#include <netinet/in.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/fcntl.h> +#include <sys/mman.h> +#include <unistd.h> +#include <ctype.h> +#include <vppinfra/clib.h> +#include <vppinfra/vec.h> +#include <vppinfra/hash.h> +#include <vppinfra/elog.h> +#include <pwd.h> +#include <stdarg.h> +#include <time.h> +#include "cpel.h" +#include "cpel_util.h" + +static elog_main_t elog_main; + +/* + * convert_clib_file + */ +void convert_clib_file(char *clib_file) +{ + clib_error_t *error = 0; + int i; + elog_main_t *em = &elog_main; + double starttime, delta; + + error = elog_read_file (&elog_main, clib_file); + + if (error) { + clib_warning("%U", format_clib_error, error); + exit (1); + } + + em = &elog_main; + + starttime = em->events[0].time; + + for (i = 0; i < vec_len (em->events); i++) { + elog_event_t *e; /* clib event */ + evt_t *ep; /* xxx2cpel event */ + u8 *s; + u64 timestamp; + elog_event_type_t *t; + u8 *brief_event_name; + u8 *track_name; + int j; + + e = vec_elt_at_index(em->events, i); + + /* Seconds since start of log */ + delta = e->time - starttime; + + /* u64 nanoseconds since start of log */ + timestamp = delta * 1e9; + + s = format (0, "%U%c", format_elog_event, em, e, 0); + + /* allocate an event instance */ + vec_add2(the_events, ep, 1); + ep->timestamp = timestamp; + + /* convert string event code to a real number */ + t = vec_elt_at_index (em->event_types, e->type); + + /* + * Construct a reasonable event name. + * Truncate the format string at the first whitespace break + * or printf format character. + */ + brief_event_name = format (0, "%s", t->format); + + for (j = 0; j < vec_len (brief_event_name); j++) { + if (brief_event_name[j] == ' ' || + brief_event_name[j] == '%' || + brief_event_name[j] == '(') { + brief_event_name[j] = 0; + break; + } + } + /* Throw away that much of the formatted event */ + vec_delete (s, j+1, 0); + + ep->event_id = find_or_add_event(brief_event_name, "%s"); + + track_name = format (0, "%U%c", format_elog_track, em, e, 0); + + ep->track_id = find_or_add_track (track_name); + + ep->datum = find_or_add_strtab(s); + + vec_free (track_name); + vec_free(brief_event_name); + vec_free(s); + } +} + +u8 *vec_basename (char *s) +{ + u8 * rv; + char *cp = s; + + while (*cp) + cp++; + + cp--; + + while (cp > s && *cp != '/') + cp--; + + if (cp > s) + cp++; + + rv = format (0, "%s", cp); + return rv; +} + + +int event_compare (const void *a0, const void *a1) +{ + evt_t *e0 = (evt_t *)a0; + evt_t *e1 = (evt_t *)a1; + + if (e0->timestamp < e1->timestamp) + return -1; + else if (e0->timestamp > e1->timestamp) + return 1; + return 0; +} + +int main (int argc, char **argv) +{ + int curarg=1; + char **inputfiles = 0; + char *outputfile = 0; + FILE *ofp; + + if (argc < 3) + goto usage; + + while (curarg < argc) { + if (!strncmp(argv[curarg], "--input-file", 3)) { + curarg++; + if (curarg < argc) { + vec_add1 (inputfiles, argv[curarg]); + curarg++; + continue; + } + clib_warning("Missing filename after --input-file\n"); + exit (1); + } + + if (!strncmp(argv[curarg], "--output-file", 3)) { + curarg ++; + if (curarg < argc) { + outputfile = argv[curarg]; + curarg ++; + continue; + } + clib_warning("Missing filename after --output-file\n"); + exit(1); + } + vec_add1 (inputfiles, argv[curarg]); + curarg++; + continue; + + usage: + fformat(stderr, + "c2cpel [--input-file] <filename> --output-file <filename>\n"); + exit(1); + } + + if (vec_len(inputfiles) == 0 || outputfile == 0) + goto usage; + + if (vec_len(inputfiles) > 1) + goto usage; + + cpel_util_init(); + + convert_clib_file (inputfiles[0]); + + ofp = fopen (outputfile, "w"); + if (ofp == NULL) { + clib_unix_warning ("couldn't create %s", outputfile); + exit (1); + } + + alpha_sort_tracks(); + fixup_event_tracks(); + + /* + * Four sections: string-table, event definitions, track defs, events. + */ + if (!write_cpel_header(ofp, 4)) { + clib_warning ("Error writing cpel header to %s...\n", outputfile); + unlink(outputfile); + exit(1); + } + + if (!write_string_table(ofp)) { + clib_warning ("Error writing string table to %s...\n", outputfile); + unlink(outputfile); + exit(1); + } + + if (!write_event_defs(ofp)) { + clib_warning ("Error writing event defs to %s...\n", outputfile); + unlink(outputfile); + exit(1); + } + + if (!write_track_defs(ofp)) { + clib_warning ("Error writing track defs to %s...\n", outputfile); + unlink(outputfile); + exit(1); + } + + if (!write_events(ofp, (u64) 1e9)) { + clib_warning ("Error writing events to %s...\n", outputfile); + unlink(outputfile); + exit(1); + + } + fclose(ofp); + exit (0); +} |