alloc_counter_tests.c

Go to the documentation of this file.
00001 
00011 #include <stdlib.h>
00012 #include <stdio.h>
00013 
00014 #include "op_parse_event.h"
00015 #include "op_alloc_counter.h"
00016 #include "op_events.h"
00017 #include "op_hw_config.h"
00018 #include "op_cpu_type.h"
00019 #include "op_events.h"
00020 
00021 /* FIXME: alpha description events need 20 but when running test on x86
00022  * OP_MAX_COUNTERS is 8, so we can't use it */
00023 #define MAX_EVENTS 20
00024 
00025 
00026 /* some test are setup to fail in a known way */
00027 enum failure_type {
00028     no_failure,
00029     fail_to_find_event,
00030     fail_to_alloc_counter
00031 };
00032 
00033 struct allocated_counter {
00034     op_cpu cpu_type;
00035     char  const * const * events;
00036     size_t alloc_map[MAX_EVENTS];
00037     /* expected failure for this test */
00038     enum failure_type failure;
00039 };
00040 
00041 
00042 /* not more than MAX_EVENTS string for all these arrays */
00043 static char const * const events_alpha_ev4_1[] = {
00044     "ISSUES:4096:0:1:1",
00045     NULL
00046 };
00047 
00048 static char const * const events_alpha_ev4_2[] = {
00049     "UNKNOWN_EVENT:4096:0:1:1",
00050     NULL
00051 };
00052 
00053 static char const * const events_ppro_1[] = {
00054     "CPU_CLK_UNHALTED:4096:0:1:1",
00055     NULL
00056 };
00057 
00058 static char const * const events_ppro_2[] = {
00059     "CPU_CLK_UNHALTED:4096:0:1:1",
00060     "DATA_MEM_REFS:4096:0:1:1",
00061     NULL
00062 };
00063 
00064 static char const * const events_ppro_3[] = {
00065     /* fail_to_alloc_counter: 2 event to counter 0 */
00066     "COMP_FLOP_RET:4096:0:1:1",
00067     "FLOPS:4096:0:1:1",
00068     NULL
00069 };
00070 
00071 static char const * const events_ppro_4[] = {
00072     "FLOPS:4096:0:1:1",
00073     "FP_ASSIST:4096:0:1:1",
00074     NULL
00075 };
00076 
00077 static char const * const events_ppro_5[] = {
00078     "FP_ASSIST:4096:0:1:1",
00079     "FLOPS:4096:0:1:1",
00080     NULL
00081 };
00082 
00083 static char const * const events_p4_1[] = {
00084     "BRANCH_RETIRED:4096:1:1:1",
00085     "MISPRED_BRANCH_RETIRED:4096:1:1:1",
00086     "BPU_FETCH_REQUEST:4096:1:1:1",
00087     "ITLB_REFERENCE:4096:1:1:1",
00088     "MEMORY_CANCEL:4096:4:1:1",
00089     "MEMORY_COMPLETE:4096:1:1:1",
00090     "TC_MS_XFER:4096:1:1:1",
00091     "UOP_QUEUE_WRITES:4096:1:1:1",
00092     NULL
00093 };
00094 
00095 static char const * const events_p4_2[] = {
00096     /* fail_to_alloc_counter: 3 event to counter 3, 7 */
00097     "BRANCH_RETIRED:4096:1:1:1",
00098     "MISPRED_BRANCH_RETIRED:4096:1:1:1",
00099     "INSTR_RETIRED:4096:1:1:1",
00100     "BPU_FETCH_REQUEST:4096:1:1:1",
00101     "ITLB_REFERENCE:4096:1:1:1",
00102     "MEMORY_CANCEL:4096:4:1:1",
00103     "MEMORY_COMPLETE:4096:1:1:1",
00104     "TC_MS_XFER:4096:1:1:1",
00105     NULL
00106 };
00107 
00108 static char const * const events_mips_34k[] = {
00109     /* fail_to_alloc_counter: w/o 2006-8-03  Jeremiah Lott patch, see
00110      * ChangeLog */
00111     "DTLB_MISSES:500:0:1:1",
00112     "JR_31_INSNS:500:0:1:1",
00113     NULL
00114 };
00115 
00116 static struct allocated_counter const tests[] = {
00117     { CPU_AXP_EV4, events_alpha_ev4_1, { 0 }, no_failure },
00118     { CPU_AXP_EV4, events_alpha_ev4_2, { -1 }, fail_to_find_event },
00119     { CPU_PPRO, events_ppro_1, { 0 }, no_failure },
00120     { CPU_PPRO, events_ppro_2, { 0, 1 }, no_failure },
00121     { CPU_PPRO, events_ppro_3, { -1 }, fail_to_alloc_counter },
00122     { CPU_PPRO, events_ppro_4, { 0, 1 }, no_failure },
00123     { CPU_PPRO, events_ppro_5, { 1, 0 }, no_failure },
00124     { CPU_P4, events_p4_1, { 3, 7, 0, 4, 2, 6, 1, 5 }, no_failure },
00125     { CPU_P4, events_p4_2, { -1 }, fail_to_alloc_counter },
00126     { CPU_MIPS_34K, events_mips_34k, { 1, 0 }, no_failure },
00127     { CPU_NO_GOOD, 0, { 0 }, 0 }
00128 };
00129 
00130 
00131 static void show_events(char const * const * events)
00132 {
00133     for ( ; *events; ++events)
00134         printf("%s\n", *events);
00135 }
00136 
00137 
00138 static void show_counter_map(size_t const * counter_map, size_t nr_events)
00139 {
00140     size_t i;
00141     for (i = 0; i < nr_events; ++i)
00142         printf("%lu ", (unsigned long)counter_map[i]);
00143     printf("\n");
00144 }
00145 
00146 
00147 static void do_test(struct allocated_counter const * it)
00148 {
00149     size_t i;
00150     size_t * counter_map;
00151     size_t nr_events;
00152     struct parsed_event parsed[MAX_EVENTS];
00153     struct op_event const * event[MAX_EVENTS];
00154 
00155     op_events(it->cpu_type);
00156 
00157     nr_events = parse_events(parsed, MAX_EVENTS, it->events);
00158 
00159     for (i = 0; i < nr_events; ++i) {
00160         event[i] = find_event_by_name(parsed[i].name, parsed[i].unit_mask,
00161                                       parsed[i].unit_mask_valid);
00162         if (!event[i]) {
00163             if (it->failure == fail_to_find_event)
00164                 goto free_events;
00165             printf("Can't find events %s for cpu %s\n",
00166                    parsed[i].name,
00167                    op_get_cpu_type_str(it->cpu_type));
00168             exit(EXIT_FAILURE);
00169         }
00170     }
00171 
00172     counter_map =  map_event_to_counter(event, nr_events, it->cpu_type);
00173     if (!counter_map) {
00174         if (it->failure == fail_to_alloc_counter)
00175             goto free_events;
00176         printf("Can't map this set of events to counter:\n");
00177         show_events(it->events);
00178         exit(EXIT_FAILURE);
00179     }
00180 
00181     for (i = 0; i < nr_events; ++i) {
00182         if (counter_map[i] != it->alloc_map[i]) {
00183             printf("Incorrect allocation map for these events:\n");
00184             show_events(it->events);
00185             printf("(expect, found):\n");
00186             show_counter_map(it->alloc_map, nr_events);
00187             show_counter_map(counter_map, nr_events);
00188             exit(EXIT_FAILURE);
00189         }
00190     }
00191 
00192     if (it->failure != no_failure) {
00193         /* test should fail but success! */
00194         printf("test should fail with a failure type %d but succeed "
00195                "for events:\n", it->failure);
00196         for (i = 0; i < nr_events; ++i)
00197             printf("%s\n", it->events[i]);
00198         exit(EXIT_FAILURE);
00199     }
00200 
00201     free(counter_map);
00202 free_events:
00203     op_free_events();
00204 }
00205 
00206 
00207 int main(void)
00208 {
00209     struct allocated_counter const * it;
00210 
00211     setenv("OPROFILE_EVENTS_DIR", OPROFILE_SRCDIR "/events", 1);
00212 
00213     for (it = tests; it->cpu_type != CPU_NO_GOOD; ++it)
00214         do_test(it);
00215 
00216     return 0;
00217 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1