root/tools/perf/tests/workloads/named_threads.c
// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <limits.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/compiler.h>
#include "../tests.h"

#define MAX_THREADS 25

static int iterations = 500;
int named_threads_work = 1234;

typedef void *(*thread_fn_t)(void *);

#define DEFINE_THREAD(n)                                                \
noinline void *named_threads_thread##n(void *arg __maybe_unused)        \
{                                                                       \
        pthread_setname_np(pthread_self(), "thread" #n);                \
        for (int i = 0; i < iterations; i++)                            \
                named_threads_work += 3;                                \
                                                                        \
        return NULL;                                                    \
}

#define THREAD_LIST(macro)      \
        macro(1)                \
        macro(2)                \
        macro(3)                \
        macro(4)                \
        macro(5)                \
        macro(6)                \
        macro(7)                \
        macro(8)                \
        macro(9)                \
        macro(10)               \
        macro(11)               \
        macro(12)               \
        macro(13)               \
        macro(14)               \
        macro(15)               \
        macro(16)               \
        macro(17)               \
        macro(18)               \
        macro(19)               \
        macro(20)               \
        macro(21)               \
        macro(22)               \
        macro(23)               \
        macro(24)               \
        macro(25)

#define DECLARE_THREAD(n) void *named_threads_thread##n(void *arg);

THREAD_LIST(DECLARE_THREAD)
THREAD_LIST(DEFINE_THREAD)

#define THREAD_ENTRY(n) named_threads_thread##n,

static thread_fn_t thread_fns[MAX_THREADS] = {
        THREAD_LIST(THREAD_ENTRY)
};

/*
 * Creates argv[0] threads that run a unique function named "thread[x]" which performs
 * a multiplication in a loop for argv[1] loops.
 */
static int named_threads(int argc, const char **argv)
{
        pthread_t threads[MAX_THREADS];
        int nr_threads = 1;
        int err = 0;

        if (argc > 0)
                nr_threads = atoi(argv[0]);

        if (nr_threads <= 0 || nr_threads > MAX_THREADS) {
                fprintf(stderr, "Error: num threads must be 1 - %d\n", MAX_THREADS);
                return 1;
        }

        if (argc > 1)
                iterations = atoi(argv[1]);

        if (iterations < 0) {
                fprintf(stderr, "Error: iterations must be non-negative\n");
                return 1;
        }

        for (int i = 0; i < nr_threads; i++) {
                int ret;

                ret = pthread_create(&threads[i], NULL, thread_fns[i], NULL);
                if (ret) {
                        fprintf(stderr, "Error: failed to create thread%d: %s\n",
                                i + 1, strerror(ret));
                        return 1;
                }
        }

        for (int i = 0; i < nr_threads; i++)
                pthread_join(threads[i], NULL);

        return err;
}

DEFINE_WORKLOAD(named_threads);