| 1 | |
| 2 | #include <errno.h>
|
| 3 | #include <limits.h>
|
| 4 | #include <pthread.h>
|
| 5 | #include <stdio.h>
|
| 6 | #include <stdlib.h>
|
| 7 | #include <string.h>
|
| 8 | #include <linux/compiler.h>
|
| 9 | #include "../tests.h"
|
| 10 |
|
| 11 | #define MAX_THREADS 25
|
| 12 |
|
| 13 | static int iterations = 500;
|
| 14 | int named_threads_work = 1234;
|
| 15 |
|
| 16 | typedef void *(*thread_fn_t)(void *);
|
| 17 |
|
| 18 | #define DEFINE_THREAD(n) \
|
| 19 | noinline void *named_threads_thread##n(void *arg __maybe_unused) \
|
| 20 | { \
|
| 21 | pthread_setname_np(pthread_self(), "thread" #n); \
|
| 22 | for (int i = 0; i < iterations; i++) \
|
| 23 | named_threads_work += 3; \
|
| 24 | \
|
| 25 | return NULL; \
|
| 26 | }
|
| 27 |
|
| 28 | #define THREAD_LIST(macro) \
|
| 29 | macro(1) \
|
| 30 | macro(2) \
|
| 31 | macro(3) \
|
| 32 | macro(4) \
|
| 33 | macro(5) \
|
| 34 | macro(6) \
|
| 35 | macro(7) \
|
| 36 | macro(8) \
|
| 37 | macro(9) \
|
| 38 | macro(10) \
|
| 39 | macro(11) \
|
| 40 | macro(12) \
|
| 41 | macro(13) \
|
| 42 | macro(14) \
|
| 43 | macro(15) \
|
| 44 | macro(16) \
|
| 45 | macro(17) \
|
| 46 | macro(18) \
|
| 47 | macro(19) \
|
| 48 | macro(20) \
|
| 49 | macro(21) \
|
| 50 | macro(22) \
|
| 51 | macro(23) \
|
| 52 | macro(24) \
|
| 53 | macro(25)
|
| 54 |
|
| 55 | #define DECLARE_THREAD(n) void *named_threads_thread##n(void *arg);
|
| 56 |
|
| 57 | THREAD_LIST(DECLARE_THREAD)
|
| 58 | THREAD_LIST(DEFINE_THREAD)
|
| 59 |
|
| 60 | #define THREAD_ENTRY(n) named_threads_thread##n,
|
| 61 |
|
| 62 | static thread_fn_t thread_fns[MAX_THREADS] = {
|
| 63 | THREAD_LIST(THREAD_ENTRY)
|
| 64 | };
|
| 65 |
|
| 66 | |
| 67 | * Creates argv[0] threads that run a unique function named "thread[x]" which performs
|
| 68 | * a multiplication in a loop for argv[1] loops.
|
| 69 |
|
| 70 | static int named_threads(int argc, const char **argv)
|
| 71 | {
|
| 72 | pthread_t threads[MAX_THREADS];
|
| 73 | int nr_threads = 1;
|
| 74 | int err = 0;
|
| 75 |
|
| 76 | if (argc > 0)
|
| 77 | nr_threads = atoi(argv[0]);
|
| 78 |
|
| 79 | if (nr_threads <= 0 || nr_threads > MAX_THREADS) {
|
| 80 | fprintf(stderr, "Error: num threads must be 1 - %d\n", MAX_THREADS);
|
| 81 | return 1;
|
| 82 | }
|
| 83 |
|
| 84 | if (argc > 1)
|
| 85 | iterations = atoi(argv[1]);
|
| 86 |
|
| 87 | if (iterations < 0) {
|
| 88 | fprintf(stderr, "Error: iterations must be non-negative\n");
|
| 89 | return 1;
|
| 90 | }
|
| 91 |
|
| 92 | for (int i = 0; i < nr_threads; i++) {
|
| 93 | int ret;
|
| 94 |
|
| 95 | ret = pthread_create(&threads[i], NULL, thread_fns[i], NULL);
|
| 96 | if (ret) {
|
| 97 | fprintf(stderr, "Error: failed to create thread%d: %s\n",
|
| 98 | i + 1, strerror(ret));
|
| 99 | return 1;
|
| 100 | }
|
| 101 | }
|
| 102 |
|
| 103 | for (int i = 0; i < nr_threads; i++)
|
| 104 | pthread_join(threads[i], NULL);
|
| 105 |
|
| 106 | return err;
|
| 107 | }
|
| 108 |
|
| 109 | DEFINE_WORKLOAD(named_threads);
|