perf bench messaging: Store chlid process pid when creating worker for process mode
authorYang Jihong <yangjihong1@huawei.com>
Sat, 23 Sep 2023 09:30:36 +0000 (09:30 +0000)
committerNamhyung Kim <namhyung@kernel.org>
Wed, 27 Sep 2023 04:47:12 +0000 (21:47 -0700)
To save pid of child processes when creating worker:
1. The messaging worker is changed to `union` type to store thread id and
   process pid.
2. Save child process pid in create_process_worker().
3. Rename `pth_tab` as `work_tab`.

Test result:

  # perf bench sched messaging
  # Running 'sched/messaging' benchmark:
  # 20 sender and receiver processes per group
  # 10 groups == 400 processes run

       Total time: 6.744 [sec]
  # perf bench sched messaging -t
  # Running 'sched/messaging' benchmark:
  # 20 sender and receiver threads per group
  # 10 groups == 400 threads run

       Total time: 5.788 [sec]

Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20230923093037.961232-4-yangjihong1@huawei.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
tools/perf/bench/sched-messaging.c

index ad8596bed77a279b5f9b7282dacde4a60083229c..04ffaabdd45b8f7c9a46223f5a27ae45f3931bee 100644 (file)
@@ -55,6 +55,11 @@ struct receiver_context {
        int wakefd;
 };
 
+union messaging_worker {
+       pthread_t thread;
+       pid_t pid;
+};
+
 static void fdpair(int fds[2])
 {
        if (use_pipes) {
@@ -139,7 +144,7 @@ again:
        return NULL;
 }
 
-static void create_thread_worker(pthread_t *thread,
+static void create_thread_worker(union messaging_worker *worker,
                                 void *ctx, void *(*func)(void *))
 {
        pthread_attr_t attr;
@@ -153,35 +158,37 @@ static void create_thread_worker(pthread_t *thread,
                err(EXIT_FAILURE, "pthread_attr_setstacksize");
 #endif
 
-       ret = pthread_create(thread, &attr, func, ctx);
+       ret = pthread_create(&worker->thread, &attr, func, ctx);
        if (ret != 0)
                err(EXIT_FAILURE, "pthread_create failed");
 
        pthread_attr_destroy(&attr);
 }
 
-static void create_process_worker(void *ctx, void *(*func)(void *))
+static void create_process_worker(union messaging_worker *worker,
+                                 void *ctx, void *(*func)(void *))
 {
        /* Fork the receiver. */
-       pid_t pid = fork();
+       worker->pid = fork();
 
-       if (pid == -1) {
+       if (worker->pid == -1) {
                err(EXIT_FAILURE, "fork()");
-       } else if (pid == 0) {
+       } else if (worker->pid == 0) {
                (*func) (ctx);
                exit(0);
        }
 }
 
-static void create_worker(pthread_t *thread, void *ctx, void *(*func)(void *))
+static void create_worker(union messaging_worker *worker,
+                         void *ctx, void *(*func)(void *))
 {
        if (!thread_mode)
-               return create_process_worker(ctx, func);
+               return create_process_worker(worker, ctx, func);
        else
-               return create_thread_worker(thread, ctx, func);
+               return create_thread_worker(worker, ctx, func);
 }
 
-static void reap_worker(pthread_t id)
+static void reap_worker(union messaging_worker *worker)
 {
        int proc_status;
        void *thread_status;
@@ -192,12 +199,12 @@ static void reap_worker(pthread_t id)
                if (!WIFEXITED(proc_status))
                        exit(1);
        } else {
-               pthread_join(id, &thread_status);
+               pthread_join(worker->thread, &thread_status);
        }
 }
 
 /* One group of senders and receivers */
-static unsigned int group(pthread_t *pth,
+static unsigned int group(union messaging_worker *worker,
                unsigned int num_fds,
                int ready_out,
                int wakefd)
@@ -228,7 +235,7 @@ static unsigned int group(pthread_t *pth,
                ctx->ready_out = ready_out;
                ctx->wakefd = wakefd;
 
-               create_worker(pth + i, ctx, (void *)receiver);
+               create_worker(worker + i, ctx, (void *)receiver);
 
                snd_ctx->out_fds[i] = fds[1];
                if (!thread_mode)
@@ -241,7 +248,7 @@ static unsigned int group(pthread_t *pth,
                snd_ctx->wakefd = wakefd;
                snd_ctx->num_fds = num_fds;
 
-               create_worker(pth + num_fds + i, snd_ctx, (void *)sender);
+               create_worker(worker + num_fds + i, snd_ctx, (void *)sender);
        }
 
        /* Close the fds we have left */
@@ -275,14 +282,14 @@ int bench_sched_messaging(int argc, const char **argv)
        unsigned int num_fds = 20;
        int readyfds[2], wakefds[2];
        char dummy;
-       pthread_t *pth_tab;
+       union messaging_worker *worker_tab;
        struct sender_context *pos, *n;
 
        argc = parse_options(argc, argv, options,
                             bench_sched_message_usage, 0);
 
-       pth_tab = malloc(num_fds * 2 * num_groups * sizeof(pthread_t));
-       if (!pth_tab)
+       worker_tab = malloc(num_fds * 2 * num_groups * sizeof(union messaging_worker));
+       if (!worker_tab)
                err(EXIT_FAILURE, "main:malloc()");
 
        fdpair(readyfds);
@@ -290,7 +297,7 @@ int bench_sched_messaging(int argc, const char **argv)
 
        total_children = 0;
        for (i = 0; i < num_groups; i++)
-               total_children += group(pth_tab + total_children, num_fds,
+               total_children += group(worker_tab + total_children, num_fds,
                                        readyfds[1], wakefds[0]);
 
        /* Wait for everyone to be ready */
@@ -306,7 +313,7 @@ int bench_sched_messaging(int argc, const char **argv)
 
        /* Reap them all */
        for (i = 0; i < total_children; i++)
-               reap_worker(pth_tab[i]);
+               reap_worker(worker_tab + i);
 
        gettimeofday(&stop, NULL);
 
@@ -334,7 +341,7 @@ int bench_sched_messaging(int argc, const char **argv)
                break;
        }
 
-       free(pth_tab);
+       free(worker_tab);
        list_for_each_entry_safe(pos, n, &sender_contexts, list) {
                list_del_init(&pos->list);
                free(pos);