Commit-ID:  38af91f01de0e160c17ae380acb5bab5d51066f4
Gitweb:     http://git.kernel.org/tip/38af91f01de0e160c17ae380acb5bab5d51066f4
Author:     Jiri Olsa <jo...@kernel.org>
AuthorDate: Mon, 12 Dec 2016 11:35:41 +0100
Committer:  Arnaldo Carvalho de Melo <a...@redhat.com>
CommitDate: Thu, 15 Dec 2016 16:25:45 -0300

perf thread_map: Add thread_map__remove function

Add thread_map__remove function to remove thread from thread map.

Add automated test also.

Committer notes:

Testing it:

  # perf test "Remove thread map"
  39: Remove thread map                          : Ok
  # perf test -v "Remove thread map"
  39: Remove thread map                          :
  --- start ---
  test child forked, pid 4483
  2 threads: 4482, 4483
  1 thread: 4483
  0 thread:
  test child finished with 0
  ---- end ----
  Remove thread map: Ok
  #

Signed-off-by: Jiri Olsa <jo...@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <a...@redhat.com>
Cc: David Ahern <dsah...@gmail.com>
Cc: Namhyung Kim <namhy...@kernel.org>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Link: 
http://lkml.kernel.org/r/1481538943-21874-4-git-send-email-jo...@kernel.org
[ Added stdlib.h, to get the free() declaration ]
Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com>
---
 tools/perf/tests/builtin-test.c |  4 ++++
 tools/perf/tests/tests.h        |  1 +
 tools/perf/tests/thread-map.c   | 44 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/thread_map.c    | 22 +++++++++++++++++++++
 tools/perf/util/thread_map.h    |  1 +
 5 files changed, 72 insertions(+)

diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 2360520..a77dcc0 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -186,6 +186,10 @@ static struct test generic_tests[] = {
                .func = test__thread_map_synthesize,
        },
        {
+               .desc = "Remove thread map",
+               .func = test__thread_map_remove,
+       },
+       {
                .desc = "Synthesize cpu map",
                .func = test__cpu_map_synthesize,
        },
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 0d7b251..a512f0c 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -80,6 +80,7 @@ const char *test__bpf_subtest_get_desc(int subtest);
 int test__bpf_subtest_get_nr(void);
 int test_session_topology(int subtest);
 int test__thread_map_synthesize(int subtest);
+int test__thread_map_remove(int subtest);
 int test__cpu_map_synthesize(int subtest);
 int test__synthesize_stat_config(int subtest);
 int test__synthesize_stat(int subtest);
diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c
index cee2a2c..a4a4b46 100644
--- a/tools/perf/tests/thread-map.c
+++ b/tools/perf/tests/thread-map.c
@@ -1,3 +1,4 @@
+#include <stdlib.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <sys/prctl.h>
@@ -93,3 +94,46 @@ int test__thread_map_synthesize(int subtest __maybe_unused)
 
        return 0;
 }
+
+int test__thread_map_remove(int subtest __maybe_unused)
+{
+       struct thread_map *threads;
+       char *str;
+       int i;
+
+       TEST_ASSERT_VAL("failed to allocate map string",
+                       asprintf(&str, "%d,%d", getpid(), getppid()) >= 0);
+
+       threads = thread_map__new_str(str, NULL, 0);
+
+       TEST_ASSERT_VAL("failed to allocate thread_map",
+                       threads);
+
+       if (verbose)
+               thread_map__fprintf(threads, stderr);
+
+       TEST_ASSERT_VAL("failed to remove thread",
+                       !thread_map__remove(threads, 0));
+
+       TEST_ASSERT_VAL("thread_map count != 1", threads->nr == 1);
+
+       if (verbose)
+               thread_map__fprintf(threads, stderr);
+
+       TEST_ASSERT_VAL("failed to remove thread",
+                       !thread_map__remove(threads, 0));
+
+       TEST_ASSERT_VAL("thread_map count != 0", threads->nr == 0);
+
+       if (verbose)
+               thread_map__fprintf(threads, stderr);
+
+       TEST_ASSERT_VAL("failed to not remove thread",
+                       thread_map__remove(threads, 0));
+
+       for (i = 0; i < threads->nr; i++)
+               free(threads->map[i].comm);
+
+       free(threads);
+       return 0;
+}
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index 40585f5..f9eab20 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -448,3 +448,25 @@ bool thread_map__has(struct thread_map *threads, pid_t pid)
 
        return false;
 }
+
+int thread_map__remove(struct thread_map *threads, int idx)
+{
+       int i;
+
+       if (threads->nr < 1)
+               return -EINVAL;
+
+       if (idx >= threads->nr)
+               return -EINVAL;
+
+       /*
+        * Free the 'idx' item and shift the rest up.
+        */
+       free(threads->map[idx].comm);
+
+       for (i = idx; i < threads->nr - 1; i++)
+               threads->map[i] = threads->map[i + 1];
+
+       threads->nr--;
+       return 0;
+}
diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h
index bd3b971..ea0ef08 100644
--- a/tools/perf/util/thread_map.h
+++ b/tools/perf/util/thread_map.h
@@ -58,4 +58,5 @@ static inline char *thread_map__comm(struct thread_map *map, 
int thread)
 
 void thread_map__read_comms(struct thread_map *threads);
 bool thread_map__has(struct thread_map *threads, pid_t pid);
+int thread_map__remove(struct thread_map *threads, int idx);
 #endif /* __PERF_THREAD_MAP_H */

Reply via email to