alloc_counter_tests.c revision 8cfa702f803c5ef6a2b062a489a1b2cf66b45b5e
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 */
27enum failure_type {
28	no_failure,
29	fail_to_find_event,
30	fail_to_alloc_counter
31};
32
33struct 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 */
43static char const * const events_alpha_ev4_1[] = {
44	"ISSUES:4096:0:1:1",
45	NULL
46};
47
48static char const * const events_alpha_ev4_2[] = {
49	"UNKNOWN_EVENT:4096:0:1:1",
50	NULL
51};
52
53static char const * const events_ppro_1[] = {
54	"CPU_CLK_UNHALTED:4096:0:1:1",
55	NULL
56};
57
58static 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
64static 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
71static char const * const events_ppro_4[] = {
72	"FLOPS:4096:0:1:1",
73	"FP_ASSIST:4096:0:1:1",
74	NULL
75};
76
77static char const * const events_ppro_5[] = {
78	"FP_ASSIST:4096:0:1:1",
79	"FLOPS:4096:0:1:1",
80	NULL
81};
82
83static 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
95static 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
108static char const * const events_mips_34k[] = {
109	/* fail_to_alloc_counter: w/o 2006-8-03  Jeremiah Lott patch, see
110	 * ChangeLog */
111	"INSTRUCTIONS:500:0:1:1",
112	"JR_31_INSN_EXECED:500:0:1:1",
113	"BRANCH_INSNS_LAUNCHED:500:0:1:1",
114	"L2_MISSES:500:0:1:1",
115	NULL
116};
117
118static struct allocated_counter const tests[] = {
119	{ CPU_AXP_EV4, events_alpha_ev4_1, { 0 }, no_failure },
120	{ CPU_AXP_EV4, events_alpha_ev4_2, { -1 }, fail_to_find_event },
121	{ CPU_PPRO, events_ppro_1, { 0 }, no_failure },
122	{ CPU_PPRO, events_ppro_2, { 0, 1 }, no_failure },
123	{ CPU_PPRO, events_ppro_3, { -1 }, fail_to_alloc_counter },
124	{ CPU_PPRO, events_ppro_4, { 0, 1 }, no_failure },
125	{ CPU_PPRO, events_ppro_5, { 1, 0 }, no_failure },
126	{ CPU_P4, events_p4_1, { 3, 7, 0, 4, 2, 6, 1, 5 }, no_failure },
127	{ CPU_P4, events_p4_2, { -1 }, fail_to_alloc_counter },
128	{ CPU_MIPS_34K, events_mips_34k, { 1, 0, 2, 3 }, no_failure },
129	{ CPU_NO_GOOD, 0, { 0 }, 0 }
130};
131
132
133static void show_events(char const * const * events)
134{
135	for ( ; *events; ++events)
136		printf("%s\n", *events);
137}
138
139
140static void show_counter_map(size_t const * counter_map, size_t nr_events)
141{
142	size_t i;
143	for (i = 0; i < nr_events; ++i)
144		printf("%lu ", (unsigned long)counter_map[i]);
145	printf("\n");
146}
147
148
149static void do_test(struct allocated_counter const * it)
150{
151	size_t i;
152	size_t * counter_map;
153	size_t nr_events;
154	struct parsed_event parsed[MAX_EVENTS];
155	struct op_event const * event[MAX_EVENTS];
156
157	op_events(it->cpu_type);
158
159	nr_events = parse_events(parsed, MAX_EVENTS, it->events);
160
161	for (i = 0; i < nr_events; ++i) {
162		event[i] = find_event_by_name(parsed[i].name, parsed[i].unit_mask,
163		                              parsed[i].unit_mask_valid);
164		if (!event[i]) {
165			if (it->failure == fail_to_find_event)
166				goto free_events;
167			printf("Can't find events %s for cpu %s\n",
168			       parsed[i].name,
169			       op_get_cpu_type_str(it->cpu_type));
170			exit(EXIT_FAILURE);
171		}
172	}
173
174	counter_map =  map_event_to_counter(event, nr_events, it->cpu_type);
175	if (!counter_map) {
176		if (it->failure == fail_to_alloc_counter)
177			goto free_events;
178		printf("Can't map this set of events to counter:\n");
179		show_events(it->events);
180		exit(EXIT_FAILURE);
181	}
182
183	for (i = 0; i < nr_events; ++i) {
184		if (counter_map[i] != it->alloc_map[i]) {
185			printf("Incorrect allocation map for these events:\n");
186			show_events(it->events);
187			printf("(expect, found):\n");
188			show_counter_map(it->alloc_map, nr_events);
189			show_counter_map(counter_map, nr_events);
190			exit(EXIT_FAILURE);
191		}
192	}
193
194	if (it->failure != no_failure) {
195		/* test should fail but success! */
196		printf("test should fail with a failure type %d but succeed "
197		       "for events:\n", it->failure);
198		for (i = 0; i < nr_events; ++i)
199			printf("%s\n", it->events[i]);
200		exit(EXIT_FAILURE);
201	}
202
203	free(counter_map);
204free_events:
205	op_free_events();
206}
207
208
209int main(void)
210{
211	struct allocated_counter const * it;
212
213	setenv("OPROFILE_EVENTS_DIR", OPROFILE_SRCDIR "/events", 1);
214
215	for (it = tests; it->cpu_type != CPU_NO_GOOD; ++it)
216		do_test(it);
217
218	return 0;
219}
220