00001
00011 #include <stdlib.h>
00012 #include <stdio.h>
00013
00014 #include "op_parse_event.h"
00015 #include "op_alloc_counter.h"
00016 #include "op_events.h"
00017 #include "op_hw_config.h"
00018 #include "op_cpu_type.h"
00019 #include "op_events.h"
00020
00021
00022
00023 #define MAX_EVENTS 20
00024
00025
00026
00027 enum failure_type {
00028 no_failure,
00029 fail_to_find_event,
00030 fail_to_alloc_counter
00031 };
00032
00033 struct allocated_counter {
00034 op_cpu cpu_type;
00035 char const * const * events;
00036 size_t alloc_map[MAX_EVENTS];
00037
00038 enum failure_type failure;
00039 };
00040
00041
00042
00043 static char const * const events_alpha_ev4_1[] = {
00044 "ISSUES:4096:0:1:1",
00045 NULL
00046 };
00047
00048 static char const * const events_alpha_ev4_2[] = {
00049 "UNKNOWN_EVENT:4096:0:1:1",
00050 NULL
00051 };
00052
00053 static char const * const events_ppro_1[] = {
00054 "CPU_CLK_UNHALTED:4096:0:1:1",
00055 NULL
00056 };
00057
00058 static char const * const events_ppro_2[] = {
00059 "CPU_CLK_UNHALTED:4096:0:1:1",
00060 "DATA_MEM_REFS:4096:0:1:1",
00061 NULL
00062 };
00063
00064 static char const * const events_ppro_3[] = {
00065
00066 "COMP_FLOP_RET:4096:0:1:1",
00067 "FLOPS:4096:0:1:1",
00068 NULL
00069 };
00070
00071 static char const * const events_ppro_4[] = {
00072 "FLOPS:4096:0:1:1",
00073 "FP_ASSIST:4096:0:1:1",
00074 NULL
00075 };
00076
00077 static char const * const events_ppro_5[] = {
00078 "FP_ASSIST:4096:0:1:1",
00079 "FLOPS:4096:0:1:1",
00080 NULL
00081 };
00082
00083 static char const * const events_p4_1[] = {
00084 "BRANCH_RETIRED:4096:1:1:1",
00085 "MISPRED_BRANCH_RETIRED:4096:1:1:1",
00086 "BPU_FETCH_REQUEST:4096:1:1:1",
00087 "ITLB_REFERENCE:4096:1:1:1",
00088 "MEMORY_CANCEL:4096:4:1:1",
00089 "MEMORY_COMPLETE:4096:1:1:1",
00090 "TC_MS_XFER:4096:1:1:1",
00091 "UOP_QUEUE_WRITES:4096:1:1:1",
00092 NULL
00093 };
00094
00095 static char const * const events_p4_2[] = {
00096
00097 "BRANCH_RETIRED:4096:1:1:1",
00098 "MISPRED_BRANCH_RETIRED:4096:1:1:1",
00099 "INSTR_RETIRED:4096:1:1:1",
00100 "BPU_FETCH_REQUEST:4096:1:1:1",
00101 "ITLB_REFERENCE:4096:1:1:1",
00102 "MEMORY_CANCEL:4096:4:1:1",
00103 "MEMORY_COMPLETE:4096:1:1:1",
00104 "TC_MS_XFER:4096:1:1:1",
00105 NULL
00106 };
00107
00108 static char const * const events_mips_34k[] = {
00109
00110
00111 "DTLB_MISSES:500:0:1:1",
00112 "JR_31_INSNS:500:0:1:1",
00113 NULL
00114 };
00115
00116 static struct allocated_counter const tests[] = {
00117 { CPU_AXP_EV4, events_alpha_ev4_1, { 0 }, no_failure },
00118 { CPU_AXP_EV4, events_alpha_ev4_2, { -1 }, fail_to_find_event },
00119 { CPU_PPRO, events_ppro_1, { 0 }, no_failure },
00120 { CPU_PPRO, events_ppro_2, { 0, 1 }, no_failure },
00121 { CPU_PPRO, events_ppro_3, { -1 }, fail_to_alloc_counter },
00122 { CPU_PPRO, events_ppro_4, { 0, 1 }, no_failure },
00123 { CPU_PPRO, events_ppro_5, { 1, 0 }, no_failure },
00124 { CPU_P4, events_p4_1, { 3, 7, 0, 4, 2, 6, 1, 5 }, no_failure },
00125 { CPU_P4, events_p4_2, { -1 }, fail_to_alloc_counter },
00126 { CPU_MIPS_34K, events_mips_34k, { 1, 0 }, no_failure },
00127 { CPU_NO_GOOD, 0, { 0 }, 0 }
00128 };
00129
00130
00131 static void show_events(char const * const * events)
00132 {
00133 for ( ; *events; ++events)
00134 printf("%s\n", *events);
00135 }
00136
00137
00138 static void show_counter_map(size_t const * counter_map, size_t nr_events)
00139 {
00140 size_t i;
00141 for (i = 0; i < nr_events; ++i)
00142 printf("%lu ", (unsigned long)counter_map[i]);
00143 printf("\n");
00144 }
00145
00146
00147 static void do_test(struct allocated_counter const * it)
00148 {
00149 size_t i;
00150 size_t * counter_map;
00151 size_t nr_events;
00152 struct parsed_event parsed[MAX_EVENTS];
00153 struct op_event const * event[MAX_EVENTS];
00154
00155 op_events(it->cpu_type);
00156
00157 nr_events = parse_events(parsed, MAX_EVENTS, it->events);
00158
00159 for (i = 0; i < nr_events; ++i) {
00160 event[i] = find_event_by_name(parsed[i].name, parsed[i].unit_mask,
00161 parsed[i].unit_mask_valid);
00162 if (!event[i]) {
00163 if (it->failure == fail_to_find_event)
00164 goto free_events;
00165 printf("Can't find events %s for cpu %s\n",
00166 parsed[i].name,
00167 op_get_cpu_type_str(it->cpu_type));
00168 exit(EXIT_FAILURE);
00169 }
00170 }
00171
00172 counter_map = map_event_to_counter(event, nr_events, it->cpu_type);
00173 if (!counter_map) {
00174 if (it->failure == fail_to_alloc_counter)
00175 goto free_events;
00176 printf("Can't map this set of events to counter:\n");
00177 show_events(it->events);
00178 exit(EXIT_FAILURE);
00179 }
00180
00181 for (i = 0; i < nr_events; ++i) {
00182 if (counter_map[i] != it->alloc_map[i]) {
00183 printf("Incorrect allocation map for these events:\n");
00184 show_events(it->events);
00185 printf("(expect, found):\n");
00186 show_counter_map(it->alloc_map, nr_events);
00187 show_counter_map(counter_map, nr_events);
00188 exit(EXIT_FAILURE);
00189 }
00190 }
00191
00192 if (it->failure != no_failure) {
00193
00194 printf("test should fail with a failure type %d but succeed "
00195 "for events:\n", it->failure);
00196 for (i = 0; i < nr_events; ++i)
00197 printf("%s\n", it->events[i]);
00198 exit(EXIT_FAILURE);
00199 }
00200
00201 free(counter_map);
00202 free_events:
00203 op_free_events();
00204 }
00205
00206
00207 int main(void)
00208 {
00209 struct allocated_counter const * it;
00210
00211 setenv("OPROFILE_EVENTS_DIR", OPROFILE_SRCDIR "/events", 1);
00212
00213 for (it = tests; it->cpu_type != CPU_NO_GOOD; ++it)
00214 do_test(it);
00215
00216 return 0;
00217 }