[PATCH v3 5/8]Perf: add extend mechanism for evsel->id & evsel->fd

From: chenggang
Date: Wed Mar 13 2013 - 05:43:34 EST


From: chenggang <chenggang.qcg@xxxxxxxxxx>

Add extend mechanism for evsel->id & evsel->fd.

Cc: David Ahern <dsahern@xxxxxxxxx>
Cc: Peter Zijlstra <a.p.zijlstra@xxxxxxxxx>
Cc: Paul Mackerras <paulus@xxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Arnaldo Carvalho de Melo <acme@xxxxxxxxxxxxxxxxxx>
Cc: Arjan van de Ven <arjan@xxxxxxxxxxxxxxx>
Cc: Namhyung Kim <namhyung@xxxxxxxxx>
Cc: Yanmin Zhang <yanmin.zhang@xxxxxxxxx>
Cc: Wu Fengguang <fengguang.wu@xxxxxxxxx>
Cc: Mike Galbraith <efault@xxxxxx>
Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Chenggang Qin <chenggang.qcg@xxxxxxxxxx>

---
tools/perf/util/evsel.c | 76 ++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/evsel.h | 8 +++++
tools/perf/util/thread_map.c | 2 +-
3 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 015321f..2eb75f9 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -599,6 +599,16 @@ int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
return evsel->fd != NULL ? 0 : -ENOMEM;
}

+/*
+ * Return the pointer to new fds (fds for the new thread at all cpus).
+ */
+static int** perf_evsel__extend_fd(struct perf_evsel *evsel)
+{
+ int init_fd = -1;
+
+ return (int**)xyarray__append(evsel->fd, (char *)&init_fd);
+}
+
int perf_evsel__set_filter(struct perf_evsel *evsel, int ncpus, int nthreads,
const char *filter)
{
@@ -617,6 +627,26 @@ int perf_evsel__set_filter(struct perf_evsel *evsel, int ncpus, int nthreads,
return 0;
}

+int perf_evsel__extend_id(struct perf_evsel *evsel)
+{
+ if (xyarray__append(evsel->sample_id, NULL) == NULL)
+ return -ENOMEM;
+
+ if (xyarray__append(evsel->id, NULL) == NULL) {
+ xyarray__remove(evsel->sample_id, -1);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+void perf_evsel__remove_id(struct perf_evsel *evsel, int tidx)
+{
+ xyarray__remove(evsel->id, tidx);
+ evsel->ids--;
+ xyarray__remove(evsel->sample_id, tidx);
+}
+
int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
{
evsel->sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id));
@@ -937,6 +967,52 @@ int perf_evsel__open_per_thread(struct perf_evsel *evsel,
return __perf_evsel__open(evsel, &empty_cpu_map.map, threads);
}

+void perf_evsel__close_single_thread(struct perf_evsel *evsel, int cpu_nr,
+ int tidx)
+{
+ int cpu;
+
+ for (cpu = 0; cpu < cpu_nr; cpu++) {
+ if (FD(evsel, cpu, tidx) >= 0)
+ close(FD(evsel, cpu, tidx));
+ }
+ xyarray__remove(evsel->fd, tidx);
+}
+
+int perf_evsel__open_single_thread(struct perf_evsel *evsel,
+ struct cpu_map *cpus, int tid)
+{
+ int cpu;
+ int pid = -1;
+ unsigned long flags = 0;
+ int **new_fds;
+
+ if ((new_fds = perf_evsel__extend_fd(evsel)) == NULL)
+ return -1;
+
+ if (evsel->cgrp) {
+ flags = PERF_FLAG_PID_CGROUP;
+ pid = evsel->cgrp->fd;
+ }
+
+ for (cpu = 0; cpu < cpus->nr; cpu++) {
+ int group_fd;
+
+ if (!evsel->cgrp)
+ pid = tid;
+
+ group_fd = get_group_fd(evsel, cpu, -1);
+ evsel->attr.disabled = 0;
+ *new_fds[cpu] = sys_perf_event_open(&evsel->attr, pid,
+ cpus->map[cpu], group_fd,
+ flags);
+ if (*new_fds[cpu] < 0)
+ return -errno;
+ }
+
+ return 0;
+}
+
static int perf_evsel__parse_id_sample(const struct perf_evsel *evsel,
const union perf_event *event,
struct perf_sample *sample)
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 7adb116..ae391d4 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -128,6 +128,9 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
void perf_evsel__id_new(struct perf_evsel *evsel, int nr);
u64 *perf_evsel__get_id(struct perf_evsel *evsel, int idx);

+int perf_evsel__extend_id(struct perf_evsel *evsel);
+void perf_evsel__remove_id(struct perf_evsel *evsel, int tidx);
+
void __perf_evsel__set_sample_bit(struct perf_evsel *evsel,
enum perf_event_sample_format bit);
void __perf_evsel__reset_sample_bit(struct perf_evsel *evsel,
@@ -152,6 +155,11 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
struct thread_map *threads);
void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads);

+int perf_evsel__open_single_thread(struct perf_evsel *evsel,
+ struct cpu_map *cpus, int tid);
+void perf_evsel__close_single_thread(struct perf_evsel *evsel, int cpu_nr,
+ int tidx);
+
struct perf_sample;

void *perf_evsel__rawptr(struct perf_evsel *evsel, struct perf_sample *sample,
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index 301f4ce..76f3da7 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -64,7 +64,7 @@ int thread_map__has_pid(struct thread_map *threads, pid_t pid)
}

/*
- * Append a thread_pid at the last of @threads.
+ * Append a thread_pid at the tail of @threads.
*/
int thread_map__append(struct thread_map *threads, pid_t pid)
{
--
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/