From: chenggang <chenggang....@taobao.com>

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

Cc: David Ahern <dsah...@gmail.com>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: Arnaldo Carvalho de Melo <a...@ghostprotocols.net>
Cc: Arjan van de Ven <ar...@linux.intel.com>
Cc: Namhyung Kim <namhy...@gmail.com>
Cc: Yanmin Zhang <yanmin.zh...@intel.com>
Cc: Wu Fengguang <fengguang...@intel.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Chenggang Qin <chenggang....@taobao.com>

---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to