Hi Ingo, Peter et al,
Trying to simplify using the API for tools and more specifically for
'perf test' regression tests, please take a look, perhaps starting from the last
changeset, that implements a regression test using the resulting library API.
It also reduces the 'perf' tool footprint by not using hard coded array
sizes, more need to be done, but should be a good start, one changeset shows a
good reduction in BSS use.
Suggestions for naming most welcome, I thought about using "event__",
but that is taken, "perf_event__", but thought it would clash with "event_t",
so used the jargon used for the '-e' parameters: "Event Selector", but don't
like it that much, what do you think?
Writing the first regression test I think there are more ways to simplify,
on top of these, like not requiring a thread_map, i.e. passing NULL for that
parameter would mean: self-monitor, etc.
If you are pleased as-is, please pull from:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 perf/test
Regards,
- Arnaldo
Arnaldo Carvalho de Melo (11):
perf tools: Introduce event selectors
perf evsel: Adopt MATCH_EVENT macro from 'stat'
perf util: Move do_read from session to util
perf evsel: Delete the event selectors at exit
perf evsel: Steal the counter reading routines from stat
perf evsel: Introduce per cpu and per thread open helpers
perf tools: Refactor cpumap to hold nr and the map
perf tools: Refactor all_tids to hold nr and the map
perf evsel: Use {cpu,thread}_map to shorten list of parameters
perf evsel: Auto allocate resources needed for some methods
perf test: Add test for counting open syscalls
tools/perf/Makefile | 4 +
tools/perf/builtin-record.c | 152 +++++++--------
tools/perf/builtin-stat.c | 368 +++++++++++++++---------------------
tools/perf/builtin-test.c | 83 ++++++++
tools/perf/builtin-top.c | 221 ++++++++++++----------
tools/perf/perf.c | ...From: Arnaldo Carvalho de Melo <acme@redhat.com>
Abstracting away the loops needed to create the various event fd handlers.
The users have to pass a confiruged perf->evsel.attr field, which is already
usable after perf_evsel__new (constructor) time, using defaults.
Comes out of the ad-hoc routines in builtin-stat, that now uses it.
Fixed a small silly bug where we were die()ing before killing our
children, dysfunctional family this one 8-)
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-stat.c | 84 ++++++++++++++-------------------------------
tools/perf/util/evsel.c | 52 ++++++++++++++++++++++++++++
tools/perf/util/evsel.h | 5 +++
3 files changed, 83 insertions(+), 58 deletions(-)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a8b00b4..065e79e 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -53,8 +53,6 @@
#include <math.h>
#include <locale.h>
-#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
-
#define DEFAULT_SEPARATOR " "
static struct perf_event_attr default_attrs[] = {
@@ -160,56 +158,24 @@ struct stats runtime_cycles_stats[MAX_NR_CPUS];
struct stats runtime_branches_stats[MAX_NR_CPUS];
struct stats walltime_nsecs_stats;
-#define ERR_PERF_OPEN \
-"counter %d, sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information."
-
-static int create_perf_stat_counter(struct perf_evsel *evsel, bool *perm_err)
+static int create_perf_stat_counter(struct perf_evsel *evsel)
{
struct perf_event_attr *attr = &evsel->attr;
- int thread;
- int ncreated = 0;
...From: Arnaldo Carvalho de Melo <acme@redhat.com>
So that later, we can pass the cpu_map instance instead of (nr_cpus, cpu_map)
for things like perf_evsel__open and friends.
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-record.c | 14 +++---
tools/perf/builtin-stat.c | 36 ++++++------
tools/perf/builtin-top.c | 22 ++++----
tools/perf/util/cpumap.c | 123 +++++++++++++++++++++++++++++++++----------
tools/perf/util/cpumap.h | 10 +++-
5 files changed, 138 insertions(+), 67 deletions(-)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 052de17..220e6e7 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -39,7 +39,7 @@ static u64 user_interval = ULLONG_MAX;
static u64 default_interval = 0;
static u64 sample_type;
-static int nr_cpus = 0;
+static struct cpu_map *cpus;
static unsigned int page_size;
static unsigned int mmap_pages = 128;
static unsigned int user_freq = UINT_MAX;
@@ -670,8 +670,8 @@ static int __cmd_record(int argc, const char **argv)
if (!system_wide && no_inherit && !cpu_list) {
open_counters(-1);
} else {
- for (i = 0; i < nr_cpus; i++)
- open_counters(cpumap[i]);
+ for (i = 0; i < cpus->nr; i++)
+ open_counters(cpus->map[i]);
}
perf_session__set_sample_type(session, sample_type);
@@ -927,14 +927,14 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
thread_num = 1;
}
- nr_cpus = read_cpu_map(cpu_list);
- if (nr_cpus < 1) {
- perror("failed to collect number of CPUs");
+ cpus = ...From: Arnaldo Carvalho de Melo <acme@redhat.com>
While writing the first user of the routines created from the ad-hoc
routines in the existing builtins I noticed that the resulting set of
calls was too long, reduce it by doing some best effort allocations.
Tools that need to operate on multiple threads and cpus should pre-allocate
enough resources by explicitely calling the perf_evsel__alloc_{fd,counters}
methods.
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/evsel.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index e44be52..c95267e 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -66,6 +66,9 @@ int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
if (FD(evsel, cpu, thread) < 0)
return -EINVAL;
+ if (evsel->counts == NULL && perf_evsel__alloc_counts(evsel, cpu + 1) < 0)
+ return -ENOMEM;
+
if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) < 0)
return -errno;
@@ -129,6 +132,9 @@ int perf_evsel__open_per_cpu(struct perf_evsel *evsel, struct cpu_map *cpus)
{
int cpu;
+ if (evsel->fd == NULL && perf_evsel__alloc_fd(evsel, cpus->nr, 1) < 0)
+ return -1;
+
for (cpu = 0; cpu < cpus->nr; cpu++) {
FD(evsel, cpu, 0) = sys_perf_event_open(&evsel->attr, -1,
cpus->map[cpu], -1, 0);
@@ -150,6 +156,9 @@ int perf_evsel__open_per_thread(struct perf_evsel *evsel, struct thread_map *thr
{
int thread;
+ if (evsel->fd == NULL && perf_evsel__alloc_fd(evsel, 1, threads->nr))
+ return -1;
+
for (thread = 0; thread < threads->nr; thread++) {
...From: Arnaldo Carvalho de Melo <acme@redhat.com>
So that later, we can pass the thread_map instance instead of
(thread_num, thread_map) for things like perf_evsel__open and friends,
just like was done with cpu_map.
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-record.c | 39 +++++++++++++++------------------------
tools/perf/builtin-stat.c | 41 +++++++++++++++++------------------------
tools/perf/builtin-top.c | 35 +++++++++++++----------------------
tools/perf/util/thread.c | 43 +++++++++++++++++++++++++++++--------------
tools/perf/util/thread.h | 15 ++++++++++++++-
5 files changed, 88 insertions(+), 85 deletions(-)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 220e6e7..7bc0490 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -54,8 +54,7 @@ static bool sample_id_all_avail = true;
static bool system_wide = false;
static pid_t target_pid = -1;
static pid_t target_tid = -1;
-static pid_t *all_tids = NULL;
-static int thread_num = 0;
+static struct thread_map *threads;
static pid_t child_pid = -1;
static bool no_inherit = false;
static enum write_mode_t write_mode = WRITE_FORCE;
@@ -318,9 +317,9 @@ static void create_counter(struct perf_evsel *evsel, int cpu)
retry_sample_id:
attr->sample_id_all = sample_id_all_avail ? 1 : 0;
- for (thread_index = 0; thread_index < thread_num; thread_index++) {
+ for (thread_index = 0; thread_index < threads->nr; thread_index++) {
try_again:
- FD(evsel, nr_cpu, thread_index) = sys_perf_event_open(attr, ...From: Arnaldo Carvalho de Melo <acme@redhat.com> Out of ad-hoc code and global arrays with hard coded sizes. This is the first step on having a library that will be first used on regression tests in the 'perf test' tool. [acme@felicio linux]$ size /tmp/perf.before text data bss dec hex filename 1273776 97384 5104416 6475576 62cf38 /tmp/perf.before [acme@felicio linux]$ size /tmp/perf.new text data bss dec hex filename 1275422 97416 1392416 2765254 2a31c6 /tmp/perf.new Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Tom Zanussi <tzanussi@gmail.com> Cc: Thomas Gleixner <tglx@linutronix.de> LKML-Reference: <new-submission> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Makefile | 4 + tools/perf/builtin-record.c | 113 +++++++++++------------ tools/perf/builtin-stat.c | 175 ++++++++++++++++++++++-------------- tools/perf/builtin-top.c | 176 +++++++++++++++++++++--------------- tools/perf/util/evsel.c | 35 +++++++ tools/perf/util/evsel.h | 24 +++++ tools/perf/util/header.c | 9 +- tools/perf/util/header.h | 3 +- tools/perf/util/parse-events.c | 47 +++++++---- tools/perf/util/parse-events.h | 17 +++-- tools/perf/util/trace-event-info.c | 30 ++++--- tools/perf/util/trace-event.h | 5 +- tools/perf/util/xyarray.c | 20 ++++ tools/perf/util/xyarray.h | 20 ++++ 14 files changed, 433 insertions(+), 245 deletions(-) create mode 100644 tools/perf/util/evsel.c create mode 100644 tools/perf/util/evsel.h create mode 100644 tools/perf/util/xyarray.c create mode 100644 tools/perf/util/xyarray.h diff --git a/tools/perf/Makefile b/tools/perf/Makefile index ...
From: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-stat.c | 4 ++--
tools/perf/util/evsel.c | 24 +++++++++++++-----------
tools/perf/util/evsel.h | 11 +++++++----
3 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 6b9146c..02b2d80 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -166,7 +166,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)
PERF_FORMAT_TOTAL_TIME_RUNNING;
if (system_wide)
- return perf_evsel__open_per_cpu(evsel, cpus->nr, cpus->map);
+ return perf_evsel__open_per_cpu(evsel, cpus);
attr->inherit = !no_inherit;
if (target_pid == -1 && target_tid == -1) {
@@ -174,7 +174,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)
attr->enable_on_exec = 1;
}
- return perf_evsel__open_per_thread(evsel, threads->nr, threads->map);
+ return perf_evsel__open_per_thread(evsel, threads);
}
/*
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index e62cc5e..e44be52 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1,6 +1,8 @@
#include "evsel.h"
#include "../perf.h"
#include "util.h"
+#include "cpumap.h"
+#include "thread.h"
#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
@@ -123,13 +125,13 @@ int __perf_evsel__read(struct perf_evsel *evsel,
return 0;
}
-int perf_evsel__open_per_cpu(struct perf_evsel *evsel, int ncpus, int *cpu_map)
+int perf_evsel__open_per_cpu(struct perf_evsel *evsel, struct cpu_map *cpus)
...Arnaldo, The version of perf at tip-x86 commit 9274b36, segfaults for me: $ gdb perf (gdb) r stat date Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7fdc602eb6e0 (LWP 4590)] cmd_stat (argc=1, argv=0x7fff6fa2a9f0, prefix=<value optimized out>) at builtin-stat.c:206 206 update_stats(&ps->res_stats[i], count[i]); (gdb) bt #0 cmd_stat (argc=1, argv=0x7fff6fa2a9f0, prefix=<value optimized out>) at builtin-stat.c:206 #1 0x0000000000405c8b in handle_internal_command (argc=2, argv=0x7fff6fa2a9f0) at perf.c:286 #2 0x00000000004060b0 in main (argc=2, argv=0x7fff6fa2a680) at perf.c:403 Most like ps is NULL. --
[acme@felicio linux]$ perf stat date | head -5
Tue Jan 4 12:03:05 BRST 2011
Performance counter stats for 'date':
4,525 cache-misses # 7.640 M/sec
343,171 cache-references # 579.405 M/sec
14,853 branch-misses # 8.214 %
180,833 branches # 305.316 M/sec
897,837 instructions # 0.000 IPC (scaled from 67.67%)
<not counted> cycles
201 page-faults # 0.339 M/sec
1 CPU-migrations # 0.002 M/sec
1 context-switches # 0.002 M/sec
0.592282 task-clock-msecs # 0.583 CPUs
0.001015291 seconds time elapsed
[acme@felicio linux]$
Re-reading the code now, thanks!
--
Arnaldo,
Looks like what's wrong is not ps but count:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7f96967fd6e0 (LWP 5156)]
0x0000000000412b58 in read_counter_aggr (counter=0x7d4820) at builtin-stat.c:206
206 update_stats(&ps->res_stats[i], count[i]);
(gdb) print ps
$1 = (struct perf_stat *) 0x7d48a0
(gdb) print *ps
$2 = {res_stats = {{n = 0, mean = 0, M2 = 0}, {n = 0, mean = 0, M2 =
0}, {n = 0, mean = 0, M2 = 0}}}
(gdb) print count
$3 = (u64 *) 0x12
(gdb) print *count
Cannot access memory at address 0x12
(gdb) print count
$4 = (u64 *) 0x12
On Tue, Jan 4, 2011 at 3:03 PM, Arnaldo Carvalho de Melo
--
Count is:
u64 *count = counter->counts->aggr.values;
And counter->counts type is:
struct perf_counts_values {
union {
struct {
u64 val;
u64 ena;
u64 run;
};
u64 values[3];
};
};
struct perf_counts {
s8 scaled;
struct perf_counts_values aggr;
struct perf_counts_values cpu[];
};
So for counter->counts->aggr.values to be 0x12 counter->counts must be
--
Can you try with this patch?
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 02b2d80..7876b11 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -196,12 +196,14 @@ static inline int nsec_counter(struct perf_evsel *evsel)
static int read_counter_aggr(struct perf_evsel *counter)
{
struct perf_stat *ps = counter->priv;
- u64 *count = counter->counts->aggr.values;
+ u64 *count;
int i;
if (__perf_evsel__read(counter, cpus->nr, threads->nr, scale) < 0)
return -1;
+ count = counter->counts->aggr.values;
+
for (i = 0; i < 3; i++)
update_stats(&ps->res_stats[i], count[i]);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index d337761..26962ea 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -89,8 +89,12 @@ int __perf_evsel__read(struct perf_evsel *evsel,
{
size_t nv = scale ? 3 : 1;
int cpu, thread;
- struct perf_counts_values *aggr = &evsel->counts->aggr, count;
+ struct perf_counts_values *aggr, count;
+ if (evsel->counts == NULL && perf_evsel__alloc_counts(evsel, ncpus) < 0)
+ return -ENOMEM;
+
+ aggr = &evsel->counts->aggr;
aggr->val = 0;
for (cpu = 0; cpu < ncpus; cpu++) {
--
No improvement with this patch. On Tue, Jan 4, 2011 at 3:27 PM, Arnaldo Carvalho de Melo --
I was guessing you were using it somehow without calling perf_evsel__alloc_counts, now I guess you're just using what is in tip/perf/core, no local changes, right? Next step: there are anonymous structs inside anonymous unions, what compiler/distro? --
On Tue, Jan 4, 2011 at 3:36 PM, Arnaldo Carvalho de Melo I am using: --
The issue is related to a mismatch in the data structure layout between builtin-stat.c and util/evsel.c. The offset of the counts fields is different between the two files. Getting closer..... --
Ok, The problem comes both files picking up a different verison for perf_event.h. In my case, util/evsel.c was using /usr/include/linux/perf_event.h whereas builtin-stat.c was using ../../include/linux/perf_event.h. Both have a different struct perf_event_attr. When I remove the /usr/include/linux/perf_event.h file, then I cannot compile perf anymore: In file included from perf.c:15: util/parse-events.h:7:30: error: linux/perf_event.h: No such file or directory Looks like something changed in the Makefile and the util modules don't know where to pickup perf_event.h --
Ouch, all need to use ../../include/linux/perf_event.h, I think, my bad, checking that. Thanks for figuring out the issue! - Arnaldo --
Just submitted a patch to fix this. On Tue, Jan 4, 2011 at 4:24 PM, Arnaldo Carvalho de Melo --
That also means that on your build machine, you have a matching perf_event.h. --
With the patch below now we have all as: [acme@felicio linux]$ find tools/ -name "*.[ch]" | xargs grep 'include.\+perf_event\.h' tools/perf/util/session.h:#include "../../../include/linux/perf_event.h" tools/perf/util/header.h:#include "../../../include/linux/perf_event.h" tools/perf/util/evsel.h:#include "../../../include/linux/perf_event.h" tools/perf/perf.h:#include "../../include/linux/perf_event.h" [acme@felicio linux]$ Can you try it so that I can get your Acked-by and Tested-by? diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 863d78d..a0ccd69 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -3,7 +3,7 @@ #include <linux/list.h> #include <stdbool.h> -#include <linux/perf_event.h> +#include "../../../include/linux/perf_event.h" #include "types.h" #include "xyarray.h" diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 1c9043c..cefef9a 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -4,9 +4,9 @@ * Parse symbolic events/counts passed in as options: */ -#include <linux/perf_event.h> +#include <linux/list.h> +#include "types.h" -struct list_head; struct perf_evsel; extern struct list_head evsel_list; --
Indeed counts is bogus: ./perf stat -i -e cycles date evt:0x7d4250 counts=0x7d4450 <-- from perf_evsel__alloc_counts() Tue Jan 4 15:28:36 CET 2011 counter=0x7d4250 counts=(nil) <-- from read_counter_aggr() Segmentation fault On Tue, Jan 4, 2011 at 3:19 PM, Arnaldo Carvalho de Melo --
Strange I'm not reproducing it here (printf just on read_counter_aggr):
[acme@felicio linux]$ perf stat date
Tue Jan 4 12:32:15 BRST 2011
0x2586820: 0x2586948
0x2586790: 0x25869f8
0x2586700: 0x2586aa8
0x2586670: 0x2586b58
0x25865e0: 0x2586c08
0x2586550: 0x2586cb8
0x25864c0: 0x2586d68
0x2586430: 0x2586e18
0x25863a0: 0x2586ec8
0x2586310: 0x2586f78
Performance counter stats for 'date':
7,512 cache-misses # 13.010 M/sec
342,645 cache-references # 593.445 M/sec
14,884 branch-misses # 8.241 %
180,611 branches # 312.810 M/sec
925,986 instructions # 0.000 IPC (scaled from 49.88%)
<not counted> cycles
201 page-faults # 0.348 M/sec
0 CPU-migrations # 0.000 M/sec
0 context-switches # 0.000 M/sec
0.577383 task-clock-msecs # 0.588 CPUs
0.000982448 seconds time elapsed
[acme@felicio linux]$
[acme@felicio linux]$ gcc -v
Using built-in specs.
COLLECT_GCC=/usr/bin/gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.5.1/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,lto --enable-plugin --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 ...Well, it shoudldn't, as we do, before calling that function:
list_for_each_entry(pos, &evsel_list, node) {
if (perf_evsel__alloc_stat_priv(pos) < 0 ||
perf_evsel__alloc_counts(pos, cpus->nr) < 0 ||
perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0)
goto out_free_fd;
}
And then at line 206 it does:
update_stats(&ps->res_stats[i], count[i]);
ps was set to be:
struct perf_stat *ps = counter->priv;
that was set by perf_evsel__alloc_stat_priv
and count is
u64 *count = counter->counts->aggr.values;
That was allocated by perf_evsel__alloc_counts
/me scratches head :-\
- Arnaldo
--
