perf thread_map: Add thread_map__remove function
authorJiri Olsa <jolsa@kernel.org>
Mon, 12 Dec 2016 10:35:41 +0000 (11:35 +0100)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 15 Dec 2016 19:25:45 +0000 (16:25 -0300)
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 <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1481538943-21874-4-git-send-email-jolsa@kernel.org
[ Added stdlib.h, to get the free() declaration ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/tests/builtin-test.c
tools/perf/tests/tests.h
tools/perf/tests/thread-map.c
tools/perf/util/thread_map.c
tools/perf/util/thread_map.h

index 23605202d4a1acf2aaf26882f67b6dd6fbf3ee91..a77dcc0d24e3f356c9da230cd84a35eddde99852 100644 (file)
@@ -185,6 +185,10 @@ static struct test generic_tests[] = {
                .desc = "Synthesize thread map",
                .func = test__thread_map_synthesize,
        },
+       {
+               .desc = "Remove thread map",
+               .func = test__thread_map_remove,
+       },
        {
                .desc = "Synthesize cpu map",
                .func = test__cpu_map_synthesize,
index 0d7b251305afcffd355727c3792696b82192d7f3..a512f0c8ff5b50160b0206c602769df89185c521 100644 (file)
@@ -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);
index cee2a2cdc93353fc18915889bd32b9a43cad9c30..a4a4b4625ac3d8864531b781c747945b53f1f849 100644 (file)
@@ -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;
+}
index 40585f5b7027d1d1eb7c0d78e754c1a7963a74f9..f9eab200fd757ee0f6824cad0b2bbe9316afbec1 100644 (file)
@@ -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;
+}
index bd3b971588da57ce14951df6d0a0870a6def1355..ea0ef08c6303413b6ececf2b93ec905914e558aa 100644 (file)
@@ -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 */