opd_events.c
Go to the documentation of this file.00001
00012 #include "config.h"
00013
00014 #include "opd_events.h"
00015 #include "opd_printf.h"
00016 #include "opd_extended.h"
00017 #include "oprofiled.h"
00018
00019 #include "op_string.h"
00020 #include "op_config.h"
00021 #include "op_cpufreq.h"
00022 #include "op_cpu_type.h"
00023 #include "op_libiberty.h"
00024 #include "op_hw_config.h"
00025 #include "op_sample_file.h"
00026 #include "op_events.h"
00027
00028 #include <stdlib.h>
00029 #include <stdio.h>
00030
00031 extern op_cpu cpu_type;
00032
00033 struct opd_event opd_events[OP_MAX_COUNTERS];
00034
00035 static double cpu_speed;
00036
00037 static void malformed_events(void)
00038 {
00039 fprintf(stderr, "oprofiled: malformed events passed "
00040 "on the command line\n");
00041 exit(EXIT_FAILURE);
00042 }
00043
00044
00045 static char * copy_token(char ** c, char delim)
00046 {
00047 char * tmp = *c;
00048 char * tmp2 = *c;
00049 char * str;
00050
00051 if (!**c)
00052 return NULL;
00053
00054 while (*tmp2 && *tmp2 != delim)
00055 ++tmp2;
00056
00057 if (tmp2 == tmp)
00058 return NULL;
00059
00060 str = op_xstrndup(tmp, tmp2 - tmp);
00061 *c = tmp2;
00062 if (**c)
00063 ++*c;
00064 return str;
00065 }
00066
00067
00068 static unsigned long copy_ulong(char ** c, char delim)
00069 {
00070 unsigned long val = 0;
00071 char * str = copy_token(c, delim);
00072 if (!str)
00073 malformed_events();
00074 val = strtoul(str, NULL, 0);
00075 free(str);
00076 return val;
00077 }
00078
00079
00080 void opd_parse_events(char const * events)
00081 {
00082 char * ev = xstrdup(events);
00083 char * c;
00084 size_t cur = 0;
00085
00086 cpu_speed = op_cpu_frequency();
00087
00088 if (cpu_type == CPU_TIMER_INT) {
00089 struct opd_event * event = &opd_events[0];
00090 event->name = xstrdup("TIMER");
00091 event->value = event->counter
00092 = event->count = event->um = 0;
00093 event->kernel = 1;
00094 event->user = 1;
00095 return;
00096 }
00097
00098 if (!ev || !strlen(ev)) {
00099 fprintf(stderr, "oprofiled: no events passed.\n");
00100 exit(EXIT_FAILURE);
00101 }
00102
00103 verbprintf(vmisc, "Events: %s\n", ev);
00104
00105 c = ev;
00106
00107 while (*c && cur < op_nr_counters) {
00108 struct opd_event * event = &opd_events[cur];
00109
00110 if (!(event->name = copy_token(&c, ':')))
00111 malformed_events();
00112 event->value = copy_ulong(&c, ':');
00113 event->counter = copy_ulong(&c, ':');
00114 event->count = copy_ulong(&c, ':');
00115 event->um = copy_ulong(&c, ':');
00116 event->kernel = copy_ulong(&c, ':');
00117 event->user = copy_ulong(&c, ',');
00118 ++cur;
00119 }
00120
00121 if (*c) {
00122 fprintf(stderr, "oprofiled: too many events passed.\n");
00123 exit(EXIT_FAILURE);
00124 }
00125
00126 free(ev);
00127 }
00128
00129
00130 struct opd_event * find_counter_event(unsigned long counter)
00131 {
00132 size_t i;
00133 struct opd_event * ret = NULL;
00134
00135 if (counter >= OP_MAX_COUNTERS) {
00136 if((ret = opd_ext_find_counter_event(counter)) != NULL)
00137 return ret;
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 if (op_cpu_has_timer_fs()
00150 && strcmp(opd_events[0].name, TIMER_EVENT_NAME) == 0
00151 && !opd_events[1].name) {
00152 return &opd_events[0];
00153
00154 }
00155
00156 for (i = 0; i < op_nr_counters && opd_events[i].name; ++i) {
00157 if (counter == opd_events[i].counter)
00158 return &opd_events[i];
00159 }
00160
00161 fprintf(stderr, "Unknown event for counter %lu\n", counter);
00162 abort();
00163 return NULL;
00164 }
00165
00166
00167 void fill_header(struct opd_header * header, unsigned long counter,
00168 vma_t anon_start, vma_t cg_to_anon_start,
00169 int is_kernel, int cg_to_is_kernel,
00170 int spu_samples, uint64_t embed_offset, time_t mtime)
00171 {
00172 struct opd_event * event = find_counter_event(counter);
00173
00174 memset(header, '\0', sizeof(struct opd_header));
00175 header->version = OPD_VERSION;
00176 memcpy(header->magic, OPD_MAGIC, sizeof(header->magic));
00177 header->cpu_type = cpu_type;
00178 header->ctr_event = event->value;
00179 header->ctr_count = event->count;
00180 header->ctr_um = event->um;
00181 header->is_kernel = is_kernel;
00182 header->cg_to_is_kernel = cg_to_is_kernel;
00183 header->cpu_speed = cpu_speed;
00184 header->mtime = mtime;
00185 header->anon_start = anon_start;
00186 header->spu_profile = spu_samples;
00187 header->embedded_offset = embed_offset;
00188 header->cg_to_anon_start = cg_to_anon_start;
00189 }