1 /** 2 * @file alloc_counter_tests.c 3 * 4 * @remark Copyright 2003 OProfile authors 5 * @remark Read the file COPYING 6 * 7 * @author John Levon 8 * @author Philippe Elie 9 */ 10 11 #include <stdlib.h> 12 #include <stdio.h> 13 14 #include "op_parse_event.h" 15 #include "op_alloc_counter.h" 16 #include "op_events.h" 17 #include "op_hw_config.h" 18 #include "op_cpu_type.h" 19 #include "op_events.h" 20 21 /* FIXME: alpha description events need 20 but when running test on x86 22 * OP_MAX_COUNTERS is 8, so we can't use it */ 23 #define MAX_EVENTS 20 24 25 26 /* some test are setup to fail in a known way */ 27 enum failure_type { 28 no_failure, 29 fail_to_find_event, 30 fail_to_alloc_counter 31 }; 32 33 struct allocated_counter { 34 op_cpu cpu_type; 35 char const * const * events; 36 size_t alloc_map[MAX_EVENTS]; 37 /* expected failure for this test */ 38 enum failure_type failure; 39 }; 40 41 42 /* not more than MAX_EVENTS string for all these arrays */ 43 static char const * const events_alpha_ev4_1[] = { 44 "ISSUES:4096:0:1:1", 45 NULL 46 }; 47 48 static char const * const events_alpha_ev4_2[] = { 49 "UNKNOWN_EVENT:4096:0:1:1", 50 NULL 51 }; 52 53 static char const * const events_ppro_1[] = { 54 "CPU_CLK_UNHALTED:4096:0:1:1", 55 NULL 56 }; 57 58 static char const * const events_ppro_2[] = { 59 "CPU_CLK_UNHALTED:4096:0:1:1", 60 "DATA_MEM_REFS:4096:0:1:1", 61 NULL 62 }; 63 64 static char const * const events_ppro_3[] = { 65 /* fail_to_alloc_counter: 2 event to counter 0 */ 66 "COMP_FLOP_RET:4096:0:1:1", 67 "FLOPS:4096:0:1:1", 68 NULL 69 }; 70 71 static char const * const events_ppro_4[] = { 72 "FLOPS:4096:0:1:1", 73 "FP_ASSIST:4096:0:1:1", 74 NULL 75 }; 76 77 static char const * const events_ppro_5[] = { 78 "FP_ASSIST:4096:0:1:1", 79 "FLOPS:4096:0:1:1", 80 NULL 81 }; 82 83 static char const * const events_p4_1[] = { 84 "BRANCH_RETIRED:4096:1:1:1", 85 "MISPRED_BRANCH_RETIRED:4096:1:1:1", 86 "BPU_FETCH_REQUEST:4096:1:1:1", 87 "ITLB_REFERENCE:4096:1:1:1", 88 "MEMORY_CANCEL:4096:4:1:1", 89 "MEMORY_COMPLETE:4096:1:1:1", 90 "TC_MS_XFER:4096:1:1:1", 91 "UOP_QUEUE_WRITES:4096:1:1:1", 92 NULL 93 }; 94 95 static char const * const events_p4_2[] = { 96 /* fail_to_alloc_counter: 3 event to counter 3, 7 */ 97 "BRANCH_RETIRED:4096:1:1:1", 98 "MISPRED_BRANCH_RETIRED:4096:1:1:1", 99 "INSTR_RETIRED:4096:1:1:1", 100 "BPU_FETCH_REQUEST:4096:1:1:1", 101 "ITLB_REFERENCE:4096:1:1:1", 102 "MEMORY_CANCEL:4096:4:1:1", 103 "MEMORY_COMPLETE:4096:1:1:1", 104 "TC_MS_XFER:4096:1:1:1", 105 NULL 106 }; 107 108 static char const * const events_mips_34k[] = { 109 /* fail_to_alloc_counter: w/o 2006-8-03 Jeremiah Lott patch, see 110 * ChangeLog */ 111 "DTLB_MISSES:500:0:1:1", 112 "JR_31_INSNS:500:0:1:1", 113 NULL 114 }; 115 116 static struct allocated_counter const tests[] = { 117 { CPU_AXP_EV4, events_alpha_ev4_1, { 0 }, no_failure }, 118 { CPU_AXP_EV4, events_alpha_ev4_2, { -1 }, fail_to_find_event }, 119 { CPU_PPRO, events_ppro_1, { 0 }, no_failure }, 120 { CPU_PPRO, events_ppro_2, { 0, 1 }, no_failure }, 121 { CPU_PPRO, events_ppro_3, { -1 }, fail_to_alloc_counter }, 122 { CPU_PPRO, events_ppro_4, { 0, 1 }, no_failure }, 123 { CPU_PPRO, events_ppro_5, { 1, 0 }, no_failure }, 124 { CPU_P4, events_p4_1, { 3, 7, 0, 4, 2, 6, 1, 5 }, no_failure }, 125 { CPU_P4, events_p4_2, { -1 }, fail_to_alloc_counter }, 126 { CPU_MIPS_34K, events_mips_34k, { 1, 0 }, no_failure }, 127 { CPU_NO_GOOD, 0, { 0 }, 0 } 128 }; 129 130 131 static void show_events(char const * const * events) 132 { 133 for ( ; *events; ++events) 134 printf("%s\n", *events); 135 } 136 137 138 static void show_counter_map(size_t const * counter_map, size_t nr_events) 139 { 140 size_t i; 141 for (i = 0; i < nr_events; ++i) 142 printf("%lu ", (unsigned long)counter_map[i]); 143 printf("\n"); 144 } 145 146 147 static void do_test(struct allocated_counter const * it) 148 { 149 size_t i; 150 size_t * counter_map; 151 size_t nr_events; 152 struct parsed_event parsed[MAX_EVENTS]; 153 struct op_event const * event[MAX_EVENTS]; 154 155 op_events(it->cpu_type); 156 157 nr_events = parse_events(parsed, MAX_EVENTS, it->events); 158 159 for (i = 0; i < nr_events; ++i) { 160 event[i] = find_event_by_name(parsed[i].name, parsed[i].unit_mask, 161 parsed[i].unit_mask_valid); 162 if (!event[i]) { 163 if (it->failure == fail_to_find_event) 164 goto free_events; 165 printf("Can't find events %s for cpu %s\n", 166 parsed[i].name, 167 op_get_cpu_type_str(it->cpu_type)); 168 exit(EXIT_FAILURE); 169 } 170 } 171 172 counter_map = map_event_to_counter(event, nr_events, it->cpu_type); 173 if (!counter_map) { 174 if (it->failure == fail_to_alloc_counter) 175 goto free_events; 176 printf("Can't map this set of events to counter:\n"); 177 show_events(it->events); 178 exit(EXIT_FAILURE); 179 } 180 181 for (i = 0; i < nr_events; ++i) { 182 if (counter_map[i] != it->alloc_map[i]) { 183 printf("Incorrect allocation map for these events:\n"); 184 show_events(it->events); 185 printf("(expect, found):\n"); 186 show_counter_map(it->alloc_map, nr_events); 187 show_counter_map(counter_map, nr_events); 188 exit(EXIT_FAILURE); 189 } 190 } 191 192 if (it->failure != no_failure) { 193 /* test should fail but success! */ 194 printf("test should fail with a failure type %d but succeed " 195 "for events:\n", it->failure); 196 for (i = 0; i < nr_events; ++i) 197 printf("%s\n", it->events[i]); 198 exit(EXIT_FAILURE); 199 } 200 201 free(counter_map); 202 free_events: 203 op_free_events(); 204 } 205 206 207 int main(void) 208 { 209 struct allocated_counter const * it; 210 211 setenv("OPROFILE_EVENTS_DIR", OPROFILE_SRCDIR "/events", 1); 212 213 for (it = tests; it->cpu_type != CPU_NO_GOOD; ++it) 214 do_test(it); 215 216 return 0; 217 } 218