[PATCH 15/40] perf tools: Add a test case for timed thread handling
A test case for verifying live and dead thread tree management during time change and new machine__find{,new}_thread_time(). Cc: Frederic Weisbecker Signed-off-by: Namhyung Kim --- tools/perf/tests/Build| 1 + tools/perf/tests/builtin-test.c | 4 + tools/perf/tests/tests.h | 1 + tools/perf/tests/thread-lookup-time.c | 179 ++ 4 files changed, 185 insertions(+) create mode 100644 tools/perf/tests/thread-lookup-time.c diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 78d29a3a6a97..5ad495823b49 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -26,6 +26,7 @@ perf-y += sw-clock.o perf-y += mmap-thread-lookup.o perf-y += thread-comm.o perf-y += thread-mg-share.o +perf-y += thread-lookup-time.o perf-y += switch-tracking.o perf-y += keep-tracking.o perf-y += code-reading.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 372b6395a448..e83c7ce1b38a 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -175,6 +175,10 @@ static struct test { .func = test__thread_comm, }, { + .desc = "Test thread lookup with time", + .func = test__thread_lookup_time, + }, + { .func = NULL, }, }; diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index aa269eff798a..e9aa78c3d8fc 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -62,6 +62,7 @@ int test__fdarray__filter(void); int test__fdarray__add(void); int test__kmod_path__parse(void); int test__thread_comm(void); +int test__thread_lookup_time(void); #if defined(__x86_64__) || defined(__i386__) || defined(__arm__) #ifdef HAVE_DWARF_UNWIND_SUPPORT diff --git a/tools/perf/tests/thread-lookup-time.c b/tools/perf/tests/thread-lookup-time.c new file mode 100644 index ..0133a241b9fc --- /dev/null +++ b/tools/perf/tests/thread-lookup-time.c @@ -0,0 +1,179 @@ +#include "tests.h" +#include "machine.h" +#include "thread.h" +#include "map.h" +#include "debug.h" + +static int thread__print_cb(struct thread *th, void *arg __maybe_unused) +{ + printf("thread: %d, start time: %"PRIu64" %s\n", + th->tid, th->start_time, + th->dead ? "(dead)" : th->exited ? "(exited)" : ""); + return 0; +} + +static int lookup_with_timestamp(struct machine *machine) +{ + struct thread *t1, *t2, *t3; + union perf_event fork_event = { + .fork = { + .pid = 0, + .tid = 0, + .ppid = 1, + .ptid = 1, + }, + }; + struct perf_sample sample = { + .time = 5, + }; + + /* this is needed to keep dead threads in rbtree */ + perf_has_index = true; + + /* start_time is set to 0 */ + t1 = machine__findnew_thread(machine, 0, 0); + + if (verbose > 1) { + printf("= after t1 created ==\n"); + machine__for_each_thread(machine, thread__print_cb, NULL); + } + + TEST_ASSERT_VAL("wrong start time of old thread", t1->start_time == 0); + + TEST_ASSERT_VAL("cannot find current thread", + machine__find_thread(machine, 0, 0) == t1); + + TEST_ASSERT_VAL("cannot find current thread with time", + machine__findnew_thread_by_time(machine, 0, 0, 1) == t1); + + /* start_time is overwritten to new value */ + thread__set_comm(t1, "/usr/bin/perf", 2); + + if (verbose > 1) { + printf("= after t1 set comm ==\n"); + machine__for_each_thread(machine, thread__print_cb, NULL); + } + + TEST_ASSERT_VAL("failed to update start time", t1->start_time == 2); + + TEST_ASSERT_VAL("should not find passed thread", + /* this will create yet another dead thread */ + machine__findnew_thread_by_time(machine, 0, 0, 1) != t1); + + TEST_ASSERT_VAL("cannot find overwritten thread with time", + machine__find_thread_by_time(machine, 0, 0, 2) == t1); + + /* now t1 goes to dead thread tree, and create t2 */ + machine__process_fork_event(machine, _event, ); + + if (verbose > 1) { + printf("= after t2 forked ==\n"); + machine__for_each_thread(machine, thread__print_cb, NULL); + } + + t2 = machine__find_thread(machine, 0, 0); + + TEST_ASSERT_VAL("cannot find current thread", t2 != NULL); + + TEST_ASSERT_VAL("wrong start time of new thread", t2->start_time == 5); + + TEST_ASSERT_VAL("dead thread cannot be found", + machine__find_thread_by_time(machine, 0, 0, 1) != t1); + + TEST_ASSERT_VAL("cannot find dead thread
[PATCH 15/40] perf tools: Add a test case for timed thread handling
A test case for verifying live and dead thread tree management during time change and new machine__find{,new}_thread_time(). Cc: Frederic Weisbecker fweis...@gmail.com Signed-off-by: Namhyung Kim namhy...@kernel.org --- tools/perf/tests/Build| 1 + tools/perf/tests/builtin-test.c | 4 + tools/perf/tests/tests.h | 1 + tools/perf/tests/thread-lookup-time.c | 179 ++ 4 files changed, 185 insertions(+) create mode 100644 tools/perf/tests/thread-lookup-time.c diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 78d29a3a6a97..5ad495823b49 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -26,6 +26,7 @@ perf-y += sw-clock.o perf-y += mmap-thread-lookup.o perf-y += thread-comm.o perf-y += thread-mg-share.o +perf-y += thread-lookup-time.o perf-y += switch-tracking.o perf-y += keep-tracking.o perf-y += code-reading.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 372b6395a448..e83c7ce1b38a 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -175,6 +175,10 @@ static struct test { .func = test__thread_comm, }, { + .desc = Test thread lookup with time, + .func = test__thread_lookup_time, + }, + { .func = NULL, }, }; diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index aa269eff798a..e9aa78c3d8fc 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -62,6 +62,7 @@ int test__fdarray__filter(void); int test__fdarray__add(void); int test__kmod_path__parse(void); int test__thread_comm(void); +int test__thread_lookup_time(void); #if defined(__x86_64__) || defined(__i386__) || defined(__arm__) #ifdef HAVE_DWARF_UNWIND_SUPPORT diff --git a/tools/perf/tests/thread-lookup-time.c b/tools/perf/tests/thread-lookup-time.c new file mode 100644 index ..0133a241b9fc --- /dev/null +++ b/tools/perf/tests/thread-lookup-time.c @@ -0,0 +1,179 @@ +#include tests.h +#include machine.h +#include thread.h +#include map.h +#include debug.h + +static int thread__print_cb(struct thread *th, void *arg __maybe_unused) +{ + printf(thread: %d, start time: %PRIu64 %s\n, + th-tid, th-start_time, + th-dead ? (dead) : th-exited ? (exited) : ); + return 0; +} + +static int lookup_with_timestamp(struct machine *machine) +{ + struct thread *t1, *t2, *t3; + union perf_event fork_event = { + .fork = { + .pid = 0, + .tid = 0, + .ppid = 1, + .ptid = 1, + }, + }; + struct perf_sample sample = { + .time = 5, + }; + + /* this is needed to keep dead threads in rbtree */ + perf_has_index = true; + + /* start_time is set to 0 */ + t1 = machine__findnew_thread(machine, 0, 0); + + if (verbose 1) { + printf(= after t1 created ==\n); + machine__for_each_thread(machine, thread__print_cb, NULL); + } + + TEST_ASSERT_VAL(wrong start time of old thread, t1-start_time == 0); + + TEST_ASSERT_VAL(cannot find current thread, + machine__find_thread(machine, 0, 0) == t1); + + TEST_ASSERT_VAL(cannot find current thread with time, + machine__findnew_thread_by_time(machine, 0, 0, 1) == t1); + + /* start_time is overwritten to new value */ + thread__set_comm(t1, /usr/bin/perf, 2); + + if (verbose 1) { + printf(= after t1 set comm ==\n); + machine__for_each_thread(machine, thread__print_cb, NULL); + } + + TEST_ASSERT_VAL(failed to update start time, t1-start_time == 2); + + TEST_ASSERT_VAL(should not find passed thread, + /* this will create yet another dead thread */ + machine__findnew_thread_by_time(machine, 0, 0, 1) != t1); + + TEST_ASSERT_VAL(cannot find overwritten thread with time, + machine__find_thread_by_time(machine, 0, 0, 2) == t1); + + /* now t1 goes to dead thread tree, and create t2 */ + machine__process_fork_event(machine, fork_event, sample); + + if (verbose 1) { + printf(= after t2 forked ==\n); + machine__for_each_thread(machine, thread__print_cb, NULL); + } + + t2 = machine__find_thread(machine, 0, 0); + + TEST_ASSERT_VAL(cannot find current thread, t2 != NULL); + + TEST_ASSERT_VAL(wrong start time of new thread, t2-start_time == 5); + + TEST_ASSERT_VAL(dead thread cannot be found, + machine__find_thread_by_time(machine, 0, 0, 1) != t1); + + TEST_ASSERT_VAL(cannot find dead thread after new