diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:04:47 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:04:47 -0800 |
commit | 7984f7ab3e13cda0c3b04ffeb2608f232e57f93a (patch) | |
tree | 480cc437dec853127d8a2f82dcd5a2f6de124a39 /libop | |
parent | 48ae5fc270ea3bbb965b4bd07cb1691a5c115642 (diff) | |
download | oprofile-7984f7ab3e13cda0c3b04ffeb2608f232e57f93a.tar.gz |
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'libop')
-rw-r--r-- | libop/Android.mk | 1 | ||||
-rw-r--r-- | libop/op_alloc_counter.c | 50 | ||||
-rw-r--r-- | libop/op_config.c | 77 | ||||
-rw-r--r-- | libop/op_config.h | 44 | ||||
-rw-r--r-- | libop/op_config_24.h | 30 | ||||
-rw-r--r-- | libop/op_cpu_type.c | 24 | ||||
-rw-r--r-- | libop/op_cpu_type.h | 23 | ||||
-rw-r--r-- | libop/op_events.c | 85 | ||||
-rw-r--r-- | libop/op_events.h | 16 | ||||
-rw-r--r-- | libop/op_get_interface.c | 5 | ||||
-rw-r--r-- | libop/op_mangle.c | 23 | ||||
-rw-r--r-- | libop/op_mangle.h | 1 | ||||
-rw-r--r-- | libop/op_sample_file.h | 4 |
13 files changed, 306 insertions, 77 deletions
diff --git a/libop/Android.mk b/libop/Android.mk index 99fd081..8fbd1e6 100644 --- a/libop/Android.mk +++ b/libop/Android.mk @@ -3,6 +3,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ op_alloc_counter.c \ + op_config.c \ op_cpu_type.c \ op_events.c \ op_get_interface.c \ diff --git a/libop/op_alloc_counter.c b/libop/op_alloc_counter.c index 8d20134..353100a 100644 --- a/libop/op_alloc_counter.c +++ b/libop/op_alloc_counter.c @@ -12,6 +12,8 @@ */ #include <stdlib.h> +#include <ctype.h> +#include <dirent.h> #include "op_events.h" #include "op_libiberty.h" @@ -130,7 +132,7 @@ allocate_counter(counter_arc_head const * ctr_arc, int max_depth, int depth, counter_arc const * arc = list_entry(pos, counter_arc, next); if (allocated_mask & (1 << arc->counter)) - return 0; + continue; counter_map[depth] = arc->counter; @@ -143,6 +145,41 @@ allocate_counter(counter_arc_head const * ctr_arc, int max_depth, int depth, return 0; } +/* determine which directories are counter directories + */ +static int perfcounterdir(const struct dirent * entry) +{ + return (isdigit(entry->d_name[0])); +} + + +/** + * @param mask pointer where to place bit mask of unavailable counters + * + * return >= 0 number of counters that are available + * < 0 could not determine number of counters + * + */ +static int op_get_counter_mask(u32 * mask) +{ + struct dirent **counterlist; + int count, i; + /* assume nothing is available */ + u32 available=0; + + count = scandir("/dev/oprofile", &counterlist, perfcounterdir, alphasort); + if (count < 0) + /* unable to determine bit mask */ + return -1; + /* convert to bit map (0 where counter exists) */ + for (i=0; i<count; ++i) { + available |= 1 << atoi(counterlist[i]->d_name); + free(counterlist[i]); + } + *mask=~available; + free(counterlist); + return count; +} size_t * map_event_to_counter(struct op_event const * pev[], int nr_events, op_cpu cpu_type) @@ -150,8 +187,14 @@ size_t * map_event_to_counter(struct op_event const * pev[], int nr_events, counter_arc_head * ctr_arc; size_t * counter_map; int nr_counters; + u32 unavailable_counters = 0; - nr_counters = op_get_nr_counters(cpu_type); + nr_counters = op_get_counter_mask(&unavailable_counters); + /* no counters then probably perfmon managing perfmon hw */ + if (nr_counters <= 0) { + nr_counters = op_get_nr_counters(cpu_type); + unavailable_counters = (~0) << nr_counters; + } if (nr_counters < nr_events) return 0; @@ -159,7 +202,8 @@ size_t * map_event_to_counter(struct op_event const * pev[], int nr_events, counter_map = xmalloc(nr_counters * sizeof(size_t)); - if (!allocate_counter(ctr_arc, nr_events, 0, 0, counter_map)) { + if (!allocate_counter(ctr_arc, nr_events, 0, unavailable_counters, + counter_map)) { free(counter_map); counter_map = 0; } diff --git a/libop/op_config.c b/libop/op_config.c new file mode 100644 index 0000000..837242b --- /dev/null +++ b/libop/op_config.c @@ -0,0 +1,77 @@ +/** + * @file op_config.c + * Oprofile configuration parameters. + * + * @remark Copyright 2002 OProfile authors + * @remark Read the file COPYING + * + * @author Nathan Tallent + * @Modifications Daniel Hansel + */ + +#include "op_config.h" +#include "op_config_24.h" + +#include <limits.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +/* paths in op_config.h */ +char op_session_dir[PATH_MAX]; +char op_samples_dir[PATH_MAX]; +char op_samples_current_dir[PATH_MAX]; +char op_lock_file[PATH_MAX]; +char op_log_file[PATH_MAX]; +char op_pipe_file[PATH_MAX]; +char op_dump_status[PATH_MAX]; + +/* paths in op_config_24.h */ +char op_device[PATH_MAX]; +char op_note_device[PATH_MAX]; +char op_hash_device[PATH_MAX]; + +void +init_op_config_dirs(char const * session_dir) +{ + int session_dir_len; + + assert(session_dir); + session_dir_len = strlen(session_dir); + + if (session_dir_len + strlen("/samples/oprofiled.log") > PATH_MAX) { + fprintf(stderr, "Session_dir string \"%s\" is too large.\n", + session_dir); + exit(EXIT_FAILURE); + } + + strcpy(op_session_dir, session_dir); + + strcpy(op_samples_dir, op_session_dir); + strcat(op_samples_dir, "/samples/"); + + strcpy(op_samples_current_dir, op_samples_dir); + strcat(op_samples_current_dir, "/current/"); + + strcpy(op_lock_file, op_session_dir); + strcat(op_lock_file, "/lock"); + + strcpy(op_pipe_file, op_session_dir); + strcat(op_pipe_file, "/opd_pipe"); + + strcpy(op_log_file, op_samples_dir); + strcat(op_log_file, "oprofiled.log"); + + strcpy(op_dump_status, op_session_dir); + strcat(op_dump_status, "/complete_dump"); + + strcpy(op_device, op_session_dir); + strcat(op_device, "/opdev"); + + strcpy(op_note_device, op_session_dir); + strcat(op_note_device, "/opnotedev"); + + strcpy(op_hash_device, op_session_dir); + strcat(op_hash_device, "/ophashmapdev"); +} diff --git a/libop/op_config.h b/libop/op_config.h index 5e16ede..b384497 100644 --- a/libop/op_config.h +++ b/libop/op_config.h @@ -9,30 +9,50 @@ * * @author John Levon * @author Philippe Elie + * @Modifications Daniel Hansel */ #ifndef OP_CONFIG_H #define OP_CONFIG_H -/* various paths, duplicated in opcontrol */ +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * must be called to initialize the paths below. + * @param session_dir the non-NULL value of the base session directory + */ +void init_op_config_dirs(char const * session_dir); -#define OP_DRIVER_BASE "/dev.oprofile" -#define OP_BASE_DIR "/tmp/oprofile/" -//#define OP_BASE_DIR "/var/lib/oprofile/" +/* + * various paths, corresponding to opcontrol, that should be + * initialized by init_op_config_dirs() above. + */ +extern char op_session_dir[]; +extern char op_samples_dir[]; +extern char op_samples_current_dir[]; +extern char op_lock_file[]; +extern char op_log_file[]; +extern char op_pipe_file[]; +extern char op_dump_status[]; -#define OP_SAMPLES_DIR OP_BASE_DIR "samples/" -#define OP_SAMPLES_CURRENT_DIR OP_SAMPLES_DIR "current/" -#define OP_LOCK_FILE OP_BASE_DIR "lock" -#define OP_LOG_FILE OP_BASE_DIR "oprofiled.log" -#define OP_DUMP_STATUS OP_BASE_DIR "complete_dump" +#define OP_DRIVER_BASE "/dev/oprofile" +#define OP_DATA_DIR "/data/oprofile" /* Global directory that stores debug files */ #ifndef DEBUGDIR -//#define DEBUGDIR "/usr/lib/debug" -#define DEBUGDIR "/tmp/debug" +#define DEBUGDIR "/usr/lib/debug" #endif #define OPD_MAGIC "DAE\n" -#define OPD_VERSION 0x10 +#define OPD_VERSION 0x11 + +#define OP_MIN_CPU_BUF_SIZE 2048 +#define OP_MAX_CPU_BUF_SIZE 131072 + +#if defined(__cplusplus) +} +#endif #endif /* OP_CONFIG_H */ diff --git a/libop/op_config_24.h b/libop/op_config_24.h index 8767244..1786fae 100644 --- a/libop/op_config_24.h +++ b/libop/op_config_24.h @@ -14,22 +14,24 @@ #define OP_CONFIG_24_H #define OP_MOUNT "/proc/sys/dev/oprofile/" - -#define OP_DEVICE OP_BASE_DIR "opdev" -#define OP_NOTE_DEVICE OP_BASE_DIR "opnotedev" -#define OP_HASH_DEVICE OP_BASE_DIR "ophashmapdev" + +extern char op_device[]; +extern char op_note_device[]; +extern char op_hash_device[]; /*@{\name module default/min/max settings */ /** 65536 * sizeof(op_sample) */ #define OP_DEFAULT_BUF_SIZE 65536 -/** we don't try to wake-up daemon until it remains more than this free entry - * in eviction buffer */ +/** + * we don't try to wake-up daemon until it remains more than this free entry + * in eviction buffer + */ #define OP_PRE_WATERMARK(buffer_size) \ (((buffer_size) / 8) < OP_MIN_PRE_WATERMARK \ ? OP_MIN_PRE_WATERMARK \ : (buffer_size) / 8) -/* minimal buffer water mark before we try to wakeup daemon */ +/** minimal buffer water mark before we try to wakeup daemon */ #define OP_MIN_PRE_WATERMARK 8192 /** maximum number of entry in samples eviction buffer */ #define OP_MAX_BUF_SIZE 1048576 @@ -38,13 +40,15 @@ /** 16384 * sizeof(op_note) = 273680 bytes default */ #define OP_DEFAULT_NOTE_SIZE 16384 -/** we don't try to wake-up daemon until it remains more than this free entry - * in note buffer */ +/** + * we don't try to wake-up daemon until it remains more than this free entry + * in note buffer + */ #define OP_PRE_NOTE_WATERMARK(note_size) \ (((note_size) / 32) < OP_MIN_NOTE_PRE_WATERMARK \ ? OP_MIN_NOTE_PRE_WATERMARK \ : (note_size) / 32) -/* minimal note buffer water mark before we try to wakeup daemon */ +/** minimal note buffer water mark before we try to wakeup daemon */ #define OP_MIN_NOTE_PRE_WATERMARK 512 /** maximum number of entry in note buffer */ #define OP_MAX_NOTE_TABLE_SIZE 1048576 @@ -58,8 +62,10 @@ /*@}*/ -/** nr entries in hash map. This is the maximum number of name components - * allowed. Must be a prime number */ +/** + * nr entries in hash map. This is the maximum number of name components + * allowed. Must be a prime number + */ #define OP_HASH_MAP_NR 4093 /** size of string pool in bytes */ diff --git a/libop/op_cpu_type.c b/libop/op_cpu_type.c index d7ff4a7..b9d13de 100644 --- a/libop/op_cpu_type.c +++ b/libop/op_cpu_type.c @@ -9,14 +9,11 @@ * @author Philippe Elie */ -#include "config.h" - #include <stdio.h> #include <stdlib.h> #include <string.h> #include "op_cpu_type.h" -#include "op_config.h" struct cpu_descr { char const * pretty; @@ -48,8 +45,13 @@ static struct cpu_descr const cpu_descrs[MAX_CPU_TYPE] = { { "ARM/XScale PMU2", "arm/xscale2", CPU_ARM_XSCALE2, 5 }, { "ppc64 POWER4", "ppc64/power4", CPU_PPC64_POWER4, 8 }, { "ppc64 POWER5", "ppc64/power5", CPU_PPC64_POWER5, 6 }, + { "ppc64 POWER5+", "ppc64/power5+", CPU_PPC64_POWER5p, 6 }, { "ppc64 970", "ppc64/970", CPU_PPC64_970, 8 }, + { "MIPS 20K", "mips/20K", CPU_MIPS_20K, 1}, { "MIPS 24K", "mips/24K", CPU_MIPS_24K, 2}, + { "MIPS 25K", "mips/25K", CPU_MIPS_25K, 2}, + { "MIPS 34K", "mips/34K", CPU_MIPS_34K, 4}, + { "MIPS 5K", "mips/5K", CPU_MIPS_5K, 2}, { "MIPS R10000", "mips/r10000", CPU_MIPS_R10000, 2 }, { "MIPS R12000", "mips/r12000", CPU_MIPS_R12000, 4 }, { "QED RM7000", "mips/rm7000", CPU_MIPS_RM7000, 1 }, @@ -58,6 +60,20 @@ static struct cpu_descr const cpu_descrs[MAX_CPU_TYPE] = { { "NEC VR5432", "mips/vr5432", CPU_MIPS_VR5432, 2 }, { "NEC VR5500", "mips/vr5500", CPU_MIPS_VR5500, 2 }, { "e500", "ppc/e500", CPU_PPC_E500, 4 }, + { "e500v2", "ppc/e500v2", CPU_PPC_E500_2, 4 }, + { "Core Solo / Duo", "i386/core", CPU_CORE, 2 }, + { "PowerPC G4", "ppc/7450", CPU_PPC_7450, 6 }, + { "Core 2", "i386/core_2", CPU_CORE_2, 2 }, + { "ppc64 POWER6", "ppc64/power6", CPU_PPC64_POWER6, 4 }, + { "ppc64 970MP", "ppc64/970MP", CPU_PPC64_970MP, 8 }, + { "ppc64 Cell Broadband Engine", "ppc64/cell-be", CPU_PPC64_CELL, 8 }, + { "AMD64 family10", "x86-64/family10", CPU_FAMILY10, 4 }, + { "ppc64 PA6T", "ppc64/pa6t", CPU_PPC64_PA6T, 6 }, + { "ARM MPCore", "arm/mpcore", CPU_ARM_MPCORE, 2 }, + { "ARM V6 PMU", "arm/armv6", CPU_ARM_V6, 3 }, + { "ppc64 POWER5++", "ppc64/power5++", CPU_PPC64_POWER5pp, 6 }, + { "e300", "ppc/e300", CPU_PPC_E300, 4 }, + { "AVR32", "avr32", CPU_AVR32, 3 }, }; static size_t const nr_cpu_descrs = sizeof(cpu_descrs) / sizeof(struct cpu_descr); @@ -71,7 +87,7 @@ op_cpu op_get_cpu_type(void) fp = fopen("/proc/sys/dev/oprofile/cpu_type", "r"); if (!fp) { /* Try 2.6's oprofilefs one instead. */ - fp = fopen(OP_DRIVER_BASE"/cpu_type", "r"); + fp = fopen("/dev/oprofile/cpu_type", "r"); if (!fp) { fprintf(stderr, "Unable to open cpu_type file for reading\n"); fprintf(stderr, "Make sure you have done opcontrol --init\n"); diff --git a/libop/op_cpu_type.h b/libop/op_cpu_type.h index 9def1d7..be95ae2 100644 --- a/libop/op_cpu_type.h +++ b/libop/op_cpu_type.h @@ -16,7 +16,9 @@ extern "C" { #endif -/** supported cpu type */ +/** + * Supported cpu type. Always add new CPU types at the very end. + */ typedef enum { CPU_NO_GOOD = -1, /**< unsupported CPU type */ CPU_PPRO, /**< Pentium Pro */ @@ -41,8 +43,13 @@ typedef enum { CPU_ARM_XSCALE2, /**< ARM XScale 2 */ CPU_PPC64_POWER4, /**< ppc64 POWER4 family */ CPU_PPC64_POWER5, /**< ppc64 POWER5 family */ + CPU_PPC64_POWER5p, /**< ppc64 Power5+ family */ CPU_PPC64_970, /**< ppc64 970 family */ + CPU_MIPS_20K, /**< MIPS 20K */ CPU_MIPS_24K, /**< MIPS 24K */ + CPU_MIPS_25K, /**< MIPS 25K */ + CPU_MIPS_34K, /**< MIPS 34K */ + CPU_MIPS_5K, /**< MIPS 5K */ CPU_MIPS_R10000, /**< MIPS R10000 */ CPU_MIPS_R12000, /**< MIPS R12000 */ CPU_MIPS_RM7000, /**< QED RM7000 */ @@ -51,6 +58,20 @@ typedef enum { CPU_MIPS_VR5432, /**< NEC VR5432 */ CPU_MIPS_VR5500, /**< MIPS VR5500, VR5532 and VR7701 */ CPU_PPC_E500, /**< e500 */ + CPU_PPC_E500_2, /**< e500v2 */ + CPU_CORE, /**< Core Solo / Duo series */ + CPU_PPC_7450, /**< PowerPC G4 */ + CPU_CORE_2, /**< Intel Core 2 */ + CPU_PPC64_POWER6, /**< ppc64 POWER6 family */ + CPU_PPC64_970MP, /**< ppc64 970MP */ + CPU_PPC64_CELL, /**< ppc64 Cell Broadband Engine*/ + CPU_FAMILY10, /**< AMD family 10 */ + CPU_PPC64_PA6T, /**< ppc64 PA6T */ + CPU_ARM_MPCORE, /**< ARM MPCore */ + CPU_ARM_V6, /**< ARM V6 */ + CPU_PPC64_POWER5pp, /**< ppc64 Power5++ family */ + CPU_PPC_E300, /**< e300 */ + CPU_AVR32, /**< AVR32 */ MAX_CPU_TYPE } op_cpu; diff --git a/libop/op_events.c b/libop/op_events.c index 47bae76..b4a10e7 100644 --- a/libop/op_events.c +++ b/libop/op_events.c @@ -39,9 +39,8 @@ static void parse_error(char const * context) static int parse_int(char const * str) { int value; - if (sscanf(str, "%d", &value) != 1) { + if (sscanf(str, "%d", &value) != 1) parse_error("expected decimal value"); - } return value; } @@ -50,9 +49,11 @@ static int parse_int(char const * str) static int parse_hex(char const * str) { int value; - if (sscanf(str, "%x", &value) != 1) { + /* 0x/0X to force the use of hexa notation for field intended to + be in hexadecimal */ + if (sscanf(str, "0x%x", &value) != 1 && + sscanf(str, "0X%x", &value) != 1) parse_error("expected hexadecimal value"); - } return value; } @@ -61,9 +62,9 @@ static int parse_hex(char const * str) static u64 parse_long_hex(char const * str) { u64 value; - if (sscanf(str, "%Lx", &value) != 1) { + if (sscanf(str, "%Lx", &value) != 1) parse_error("expected long hexadecimal value"); - } + fflush(stderr); return value; } @@ -187,12 +188,11 @@ static void read_unit_masks(char const * file) um = new_unit_mask(); parse_um(um, line); } else { - if (!um) { + if (!um) parse_error("no unit mask name line"); - } - if (um->num >= MAX_UNIT_MASK) { + if (um->num >= MAX_UNIT_MASK) parse_error("oprofile: maximum unit mask entries exceeded"); - } + parse_um_entry(&um->um[um->num], line); ++(um->num); } @@ -259,9 +259,8 @@ static int next_token(char const ** cp, char ** name, char ** value) colon = strchr(colon, ':'); if (!colon) { - if (*c) { + if (*c) parse_error("next_token(): garbage at end of line"); - } return 0; } @@ -337,6 +336,10 @@ static void read_events(char const * file) if (seen_name) parse_error("duplicate name: tag"); seen_name = 1; + if (strchr(value, '/') != NULL) + parse_error("invalid event name"); + if (strchr(value, '.') != NULL) + parse_error("invalid event name"); event->name = value; } else if (strcmp(name, "event") == 0) { if (seen_event) @@ -385,7 +388,7 @@ next: static void check_unit_mask(struct op_unit_mask const * um, char const * cpu_name) { - u16 i; + u32 i; if (!um->used) { fprintf(stderr, "um %s is not used\n", um->name); @@ -397,10 +400,10 @@ static void check_unit_mask(struct op_unit_mask const * um, "entry (%s)\n", um->name, cpu_name); exit(EXIT_FAILURE); } else if (um->unit_type_mask == utm_bitmask) { - u16 default_mask = um->default_mask; - for (i = 0; i < um->num; ++i) { + u32 default_mask = um->default_mask; + for (i = 0; i < um->num; ++i) default_mask &= ~um->um[i].value; - } + if (default_mask) { fprintf(stderr, "um %s default mask is not valid " "(%s)\n", um->name, cpu_name); @@ -519,7 +522,7 @@ void op_free_events(void) } -static struct op_event * find_event(u8 nr) +static struct op_event * find_event(u32 nr) { struct list_head * pos; @@ -557,7 +560,7 @@ static FILE * open_event_mapping_file(char const * cpu_name) /** * This function is PPC64-specific. */ -static char const * get_mapping(u8 nr, FILE * fp) +static char const * get_mapping(u32 nr, FILE * fp) { char * line; char * name; @@ -587,14 +590,13 @@ static char const * get_mapping(u8 nr, FILE * fp) c = line; while (next_token(&c, &name, &value)) { if (strcmp(name, "event") == 0) { - u8 evt; + u32 evt; if (seen_event) parse_error("duplicate event tag"); seen_event = 1; evt = parse_hex(value); - if (evt == nr) { + if (evt == nr) event_found = 1; - } free(value); } else if (strcmp(name, "mmcr0") == 0) { if (seen_mmcr0) @@ -639,15 +641,20 @@ next: } -char const * find_mapping_for_event(u8 nr, op_cpu cpu_type) +char const * find_mapping_for_event(u32 nr, op_cpu cpu_type) { char const * cpu_name = op_get_cpu_name(cpu_type); FILE * fp = open_event_mapping_file(cpu_name); char const * map = NULL; switch (cpu_type) { + case CPU_PPC64_PA6T: case CPU_PPC64_970: + case CPU_PPC64_970MP: case CPU_PPC64_POWER4: case CPU_PPC64_POWER5: + case CPU_PPC64_POWER5p: + case CPU_PPC64_POWER5pp: + case CPU_PPC64_POWER6: if (!fp) { fprintf(stderr, "oprofile: could not open event mapping file %s\n", filename); exit(EXIT_FAILURE); @@ -680,7 +687,7 @@ struct op_event * find_event_by_name(char const * name) } -struct op_event * op_find_event(op_cpu cpu_type, u8 nr) +struct op_event * op_find_event(op_cpu cpu_type, u32 nr) { struct op_event * event; @@ -692,7 +699,7 @@ struct op_event * op_find_event(op_cpu cpu_type, u8 nr) } -int op_check_events(int ctr, u8 nr, u16 um, op_cpu cpu_type) +int op_check_events(int ctr, u32 nr, u32 um, op_cpu cpu_type) { int ret = OP_OK_EVENT; struct op_event * event; @@ -747,8 +754,11 @@ void op_default_event(op_cpu cpu_type, struct op_default_event_descr * descr) case CPU_PII: case CPU_PIII: case CPU_P6_MOBILE: + case CPU_CORE: + case CPU_CORE_2: case CPU_ATHLON: case CPU_HAMMER: + case CPU_FAMILY10: descr->name = "CPU_CLK_UNHALTED"; break; @@ -781,12 +791,26 @@ void op_default_event(op_cpu cpu_type, struct op_default_event_descr * descr) // we could possibly use the CCNT case CPU_ARM_XSCALE1: case CPU_ARM_XSCALE2: + case CPU_ARM_MPCORE: + case CPU_ARM_V6: + case CPU_AVR32: descr->name = "CPU_CYCLES"; break; + case CPU_PPC64_PA6T: case CPU_PPC64_970: + case CPU_PPC64_970MP: + case CPU_PPC_7450: case CPU_PPC64_POWER4: case CPU_PPC64_POWER5: + case CPU_PPC64_POWER6: + case CPU_PPC64_POWER5p: + case CPU_PPC64_POWER5pp: + case CPU_PPC64_CELL: + descr->name = "CYCLES"; + break; + + case CPU_MIPS_20K: descr->name = "CYCLES"; break; @@ -794,6 +818,15 @@ void op_default_event(op_cpu cpu_type, struct op_default_event_descr * descr) descr->name = "INSTRUCTIONS"; break; + case CPU_MIPS_34K: + descr->name = "INSTRUCTIONS"; + break; + + case CPU_MIPS_5K: + case CPU_MIPS_25K: + descr->name = "CYCLES"; + break; + case CPU_MIPS_R10000: case CPU_MIPS_R12000: descr->name = "INSTRUCTIONS_GRADUATED"; @@ -814,9 +847,11 @@ void op_default_event(op_cpu cpu_type, struct op_default_event_descr * descr) break; case CPU_PPC_E500: + case CPU_PPC_E500_2: + case CPU_PPC_E300: descr->name = "CPU_CLK"; break; - + // don't use default, if someone add a cpu he wants a compiler // warning if he forgets to handle it here. case CPU_TIMER_INT: diff --git a/libop/op_events.h b/libop/op_events.h index 1796fb9..f6462fc 100644 --- a/libop/op_events.h +++ b/libop/op_events.h @@ -28,8 +28,8 @@ enum unit_mask_type { utm_bitmask /**< bitmask */ }; -/** up to sixteen allowed unit masks */ -#define MAX_UNIT_MASK 16 +/** up to thirty two allowed unit masks */ +#define MAX_UNIT_MASK 32 /** Describe an unit mask. */ @@ -37,9 +37,9 @@ struct op_unit_mask { char * name; /**< name of unit mask type */ u32 num; /**< number of possible unit masks */ enum unit_mask_type unit_type_mask; - u16 default_mask; /**< only the gui use it */ + u32 default_mask; /**< only the gui use it */ struct op_described_um { - u16 value; + u32 value; char * desc; } um[MAX_UNIT_MASK]; struct list_head um_next; /**< next um in list */ @@ -50,7 +50,7 @@ struct op_unit_mask { /** Describe an event. */ struct op_event { u32 counter_mask; /**< bitmask of allowed counter */ - u8 val; /**< event number */ + u32 val; /**< event number */ /** which unit mask if any allowed */ struct op_unit_mask * unit; char * name; /**< the event name */ @@ -63,7 +63,7 @@ struct op_event { struct list_head * op_events(op_cpu cpu_type); /** Find a given event, returns NULL on error */ -struct op_event * op_find_event(op_cpu cpu_type, u8 nr); +struct op_event * op_find_event(op_cpu cpu_type, u32 nr); /** Find a given event by name */ struct op_event * find_event_by_name(char const * name); @@ -72,7 +72,7 @@ struct op_event * find_event_by_name(char const * name); * Find a mapping for a given event ID for architectures requiring additional information * from what is held in the events file. */ -char const * find_mapping_for_event(u8 val, op_cpu cpu_type); +char const * find_mapping_for_event(u32 val, op_cpu cpu_type); /** op_check_events() return code */ @@ -96,7 +96,7 @@ enum op_event_check { * * \sa op_cpu, OP_EVENTS_OK */ -int op_check_events(int ctr, u8 event, u16 um, op_cpu cpu_type); +int op_check_events(int ctr, u32 event, u32 um, op_cpu cpu_type); /** * free memory used by any call to above function. Need to be called only once diff --git a/libop/op_get_interface.c b/libop/op_get_interface.c index b57a79f..bdf72a5 100644 --- a/libop/op_get_interface.c +++ b/libop/op_get_interface.c @@ -8,15 +8,12 @@ * @author Will Cohen */ -#include "config.h" - #include <stdio.h> #include <stdlib.h> #include <string.h> #include "op_cpu_type.h" #include "op_file.h" -#include "op_config.h" op_interface op_get_interface(void) { @@ -27,7 +24,7 @@ op_interface op_get_interface(void) if (op_file_readable("/proc/sys/dev/oprofile/cpu_type")) { current_interface = OP_INTERFACE_24; - } else if (op_file_readable(OP_DRIVER_BASE"/cpu_type")) { + } else if (op_file_readable("/dev/oprofile/cpu_type")) { current_interface = OP_INTERFACE_26; } diff --git a/libop/op_mangle.c b/libop/op_mangle.c index a78d87f..1efe5b1 100644 --- a/libop/op_mangle.c +++ b/libop/op_mangle.c @@ -19,12 +19,14 @@ #include "op_sample_file.h" #include "op_config.h" -static void append_image(char * dest, int flags, int anon, char const * name) +static void append_image(char * dest, int flags, int anon, char const * name, char const * anon_name) { if ((flags & MANGLE_KERNEL) && !strchr(name, '/')) { strcat(dest, "{kern}/"); } else if (anon) { - strcat(dest, "{anon}/"); + strcat(dest, "{anon:"); + strcat(dest, anon_name); + strcat(dest,"}/"); } else { strcat(dest, "{root}/"); } @@ -44,15 +46,19 @@ char * op_mangle_filename(struct mangle_values const * values) * them), see P:3, FIXME: this is a bit weirds, we prolly need to * reword pp_interface */ char const * image_name = values->dep_name; + char const * anon_name = values->anon_name; char const * dep_name = values->image_name; char const * cg_image_name = values->cg_image_name; - len = strlen(OP_SAMPLES_CURRENT_DIR) + strlen(dep_name) + 1 - + strlen(values->event_name) + 1 + strlen(image_name) + 1; + len = strlen(op_samples_current_dir) + strlen(dep_name) + 1 + + strlen(values->event_name) + 1 + strlen(image_name) + 1; if (values->flags & MANGLE_CALLGRAPH) len += strlen(cg_image_name) + 1; + if (anon || cg_anon) + len += strlen(anon_name); + /* provision for tgid, tid, unit_mask, cpu and some {root}, {dep}, * {kern}, {anon} and {cg} marker */ /* FIXME: too ugly */ @@ -60,15 +66,16 @@ char * op_mangle_filename(struct mangle_values const * values) mangled = xmalloc(len); - strcpy(mangled, OP_SAMPLES_CURRENT_DIR); - append_image(mangled, values->flags, 0, image_name); + strcpy(mangled, op_samples_current_dir); + append_image(mangled, values->flags, 0, image_name, anon_name); strcat(mangled, "{dep}" "/"); - append_image(mangled, values->flags, anon, dep_name); + append_image(mangled, values->flags, anon, dep_name, anon_name); if (values->flags & MANGLE_CALLGRAPH) { strcat(mangled, "{cg}" "/"); - append_image(mangled, values->flags, cg_anon, cg_image_name); + append_image(mangled, values->flags, cg_anon, + cg_image_name, anon_name); } strcat(mangled, values->event_name); diff --git a/libop/op_mangle.h b/libop/op_mangle.h index 5d02d94..9b600dc 100644 --- a/libop/op_mangle.h +++ b/libop/op_mangle.h @@ -37,6 +37,7 @@ struct mangle_values { int flags; char const * image_name; + char const * anon_name; char const * dep_name; char const * cg_image_name; char const * event_name; diff --git a/libop/op_sample_file.h b/libop/op_sample_file.h index c3121c8..4f9f1d0 100644 --- a/libop/op_sample_file.h +++ b/libop/op_sample_file.h @@ -14,6 +14,7 @@ #include "op_types.h" +#include <stdint.h> #include <time.h> /* header of the sample files */ @@ -29,6 +30,9 @@ struct opd_header { double cpu_speed; time_t mtime; u32 cg_to_is_kernel; + /* spu_profile=1 says sample file contains Cell BE SPU profile data */ + u32 spu_profile; + uint64_t embedded_offset; u64 anon_start; u64 cg_to_anon_start; /* binary compatibility reserve */ |