• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
show_events(char const * const * events)131 static void show_events(char const * const * events)
132 {
133 	for ( ; *events; ++events)
134 		printf("%s\n", *events);
135 }
136 
137 
show_counter_map(size_t const * counter_map,size_t nr_events)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 
do_test(struct allocated_counter const * it)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 
main(void)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