]> git.saurik.com Git - apple/xnu.git/blobdiff - tools/tests/darwintests/perf_exit.c
xnu-4570.41.2.tar.gz
[apple/xnu.git] / tools / tests / darwintests / perf_exit.c
index 052b942c3efd5b8e15968ca905e4cd5cf0010310..0caafdad5c350db88c949c7483d3ab39b9b4f02d 100644 (file)
@@ -4,10 +4,11 @@
 #include <darwintest.h>
 
 #include <sys/kdebug.h>
-#include <ktrace.h>
+#include <ktrace/session.h>
 #include <spawn.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdatomic.h>
 
 T_GLOBAL_META(
        T_META_NAMESPACE("xnu.perf.exit"),
@@ -27,69 +28,72 @@ T_GLOBAL_META(
 #define EXIT_BINARY "perf_exit_proc"
 #define EXIT_BINARY_PATH "./" EXIT_BINARY
 
+static ktrace_session_t session;
+static dispatch_queue_t spawn_queue;
+static uint64_t *begin_ts;
+static dt_stat_time_t s;
+static bool started_tracing = false;
+
 void run_exit_test(int proc_wired_mem, int thread_priority, int nthreads);
 
+static void cleanup(void) {
+       free(begin_ts);
+       dt_stat_finalize(s);
+       dispatch_release(spawn_queue);
+       if (started_tracing) {
+               ktrace_end(session, 1);
+       }
+}
+
 void run_exit_test(int proc_wired_mem, int thread_priority, int nthreads) {
-       _Atomic static int ended = 0;
-       dispatch_queue_t spawn_queue;
+       static atomic_bool ended = false;
 
-       dt_stat_time_t s = dt_stat_time_create("time");
+       s = dt_stat_time_create("time");
+       T_QUIET; T_ASSERT_NOTNULL(s, "created time statistic");
 
-       uint64_t *begin_ts = malloc(sizeof(uint64_t) * PID_MAX);
-       if (begin_ts == NULL) {
-               T_FAIL("Error allocating timestamp array");
-       }
+       begin_ts = malloc(sizeof(uint64_t) * PID_MAX);
+       T_QUIET; T_ASSERT_NOTNULL(begin_ts, "created pid array");
+
+       T_ATEND(cleanup);
 
-       ktrace_session_t session;
        session = ktrace_session_create();
-       if (session == NULL) {
-               T_FAIL("Error creating ktrace session");
-       }
+       T_QUIET; T_ASSERT_NOTNULL(session, "created a trace session");
 
        spawn_queue = dispatch_queue_create("spawn_queue", NULL);
 
        ktrace_set_completion_handler(session, ^{
-               free(begin_ts);
-               dt_stat_finalize(s);
-               dispatch_release(spawn_queue);
+               ktrace_session_destroy(session);
                T_END;
        });
 
        ktrace_set_signal_handler(session);
+       ktrace_set_execnames_enabled(session, KTRACE_FEATURE_ENABLED);
 
-       // We are only interested by the process we launched
+       // We are only interested in the process we launched
        ktrace_filter_process(session, EXIT_BINARY);
 
        ktrace_events_single(session, (BSDDBG_CODE(DBG_BSD_EXCP_SC, 1) | DBG_FUNC_START), ^(ktrace_event_t e) {
-               pid_t pid = ktrace_get_pid_for_thread(session, e->threadid);
-               if (pid > PID_MAX) {
-                       T_FAIL("Invalid pid returned by ktrace_get_pid_for_thread: %d\n", pid);
-               }
-               begin_ts[pid] = e->timestamp;
-
+               T_QUIET; T_ASSERT_LE(e->pid, PID_MAX, "valid pid for tracepoint");
+               begin_ts[e->pid] = e->timestamp;
        });
        ktrace_events_single(session, (BSDDBG_CODE(DBG_BSD_PROC, BSD_PROC_EXIT) | DBG_FUNC_END), ^(ktrace_event_t e) {
-               pid_t pid = ktrace_get_pid_for_thread(session, e->threadid);
-               if (pid > PID_MAX) {
-                       T_FAIL("Invalid pid returned by ktrace_get_pid_for_thread: %d\n", pid);
-               }
-               if (begin_ts[pid] == 0) {
+               T_QUIET; T_ASSERT_LE(e->pid, PID_MAX, "valid pid for tracepoint");
+
+               if (begin_ts[e->pid] == 0) {
                        return;
                }
-               uint64_t delta = e->timestamp - begin_ts[pid];
-               if (!dt_stat_stable(s)) {
-                       dt_stat_mach_time_add(s, delta);
-               }
-               else {
-                       ended = 1;
+               T_QUIET; T_ASSERT_LE(begin_ts[e->pid], e->timestamp, "timestamps are monotonically increasing");
+               dt_stat_mach_time_add(s, e->timestamp - begin_ts[e->pid]);
+
+               if (dt_stat_stable(s)) {
+                       ended = true;
                        ktrace_end(session, 1);
                }
        });
 
        int ret = ktrace_start(session, dispatch_get_main_queue());
-       if (ret != 0) {
-               T_FAIL("Error starting ktrace");
-       }
+       T_ASSERT_POSIX_ZERO(ret, "starting trace");
+       started_tracing = true;
 
        // Spawn processes continuously until the test is over
        dispatch_async(spawn_queue, ^(void) {
@@ -103,13 +107,14 @@ void run_exit_test(int proc_wired_mem, int thread_priority, int nthreads) {
                int status;
                while (!ended) {
                        pid_t pid;
-                       int err = posix_spawn(&pid, args[0], NULL, NULL, args, NULL);
-                       if (err)
-                               T_FAIL("posix_spawn returned %d", err);
+                       int bret = posix_spawn(&pid, args[0], NULL, NULL, args, NULL);
+                       T_QUIET; T_ASSERT_POSIX_ZERO(bret, "spawned process '%s'", args[0]);
+
+                       bret = waitpid(pid, &status, 0);
+                       T_QUIET; T_ASSERT_POSIX_SUCCESS(bret, "waited for process %d\n", pid);
 
-                       waitpid(pid, &status, 0);
                        if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
-                               T_FAIL("Child process of posix_spawn failed to run");
+                               T_ASSERT_FAIL("child process failed to run");
 
                        // Avoid saturating the CPU with new processes
                        usleep(1);
@@ -140,7 +145,6 @@ T_DECL(exit_10_threads, "exit(2) time with 10 threads") {
        run_exit_test(0, BASEPRI_FOREGROUND, 10);
 }
 
-
 T_DECL(exit_1mb, "exit(2) time with 1MB of wired memory") {
        run_exit_test(10000000, BASEPRI_FOREGROUND, 0);
 }
@@ -149,17 +153,14 @@ T_DECL(exit_10mb, "exit(2) time with 10MB of wired memory") {
        run_exit_test(10000000, BASEPRI_FOREGROUND, 0);
 }
 
-/*
-T_DECL(exit_100_threads, "exit(2) time with 100 threads", T_META_TIMEOUT(1800)) {
+T_DECL(exit_100_threads, "exit(2) time with 100 threads", T_META_ENABLED(false), T_META_TIMEOUT(1800)) {
        run_exit_test(0, BASEPRI_FOREGROUND, 100);
 }
 
-T_DECL(exit_1000_threads, "exit(2) time with 1000 threads", T_META_TIMEOUT(1800)) {
+T_DECL(exit_1000_threads, "exit(2) time with 1000 threads", T_META_ENABLED(false), T_META_TIMEOUT(1800)) {
        run_exit_test(0, BASEPRI_FOREGROUND, 1000);
 }
 
-T_DECL(exit_100mb, "exit(2) time with 100MB of wired memory", T_META_TIMEOUT(1800)) {
+T_DECL(exit_100mb, "exit(2) time with 100MB of wired memory", T_META_ENABLED(false), T_META_TIMEOUT(1800)) {
        run_exit_test(100000000, BASEPRI_FOREGROUND, 0);
 }
-*/
-