blob: 5aeb605a33c76eba1f37f2746d783ccd4258b876 [file] [log] [blame]
Mike Dodd8cfa7022010-11-17 11:12:26 -08001/**
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 */
Jeff Brown7a33c862011-02-02 14:00:44 -0800111 "DTLB_MISSES:500:0:1:1",
112 "JR_31_INSNS:500:0:1:1",
Mike Dodd8cfa7022010-11-17 11:12:26 -0800113 NULL
114};
115
116static 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 },
Jeff Brown7a33c862011-02-02 14:00:44 -0800126 { CPU_MIPS_34K, events_mips_34k, { 1, 0 }, no_failure },
Mike Dodd8cfa7022010-11-17 11:12:26 -0800127 { CPU_NO_GOOD, 0, { 0 }, 0 }
128};
129
130
131static void show_events(char const * const * events)
132{
133 for ( ; *events; ++events)
134 printf("%s\n", *events);
135}
136
137
138static 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
147static 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);
202free_events:
203 op_free_events();
204}
205
206
207int 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}