Home | History | Annotate | Download | only in tests
      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