aboutsummaryrefslogtreecommitdiff
path: root/libop
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:04:47 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:04:47 -0800
commit7984f7ab3e13cda0c3b04ffeb2608f232e57f93a (patch)
tree480cc437dec853127d8a2f82dcd5a2f6de124a39 /libop
parent48ae5fc270ea3bbb965b4bd07cb1691a5c115642 (diff)
downloadoprofile-7984f7ab3e13cda0c3b04ffeb2608f232e57f93a.tar.gz
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'libop')
-rw-r--r--libop/Android.mk1
-rw-r--r--libop/op_alloc_counter.c50
-rw-r--r--libop/op_config.c77
-rw-r--r--libop/op_config.h44
-rw-r--r--libop/op_config_24.h30
-rw-r--r--libop/op_cpu_type.c24
-rw-r--r--libop/op_cpu_type.h23
-rw-r--r--libop/op_events.c85
-rw-r--r--libop/op_events.h16
-rw-r--r--libop/op_get_interface.c5
-rw-r--r--libop/op_mangle.c23
-rw-r--r--libop/op_mangle.h1
-rw-r--r--libop/op_sample_file.h4
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 */