1 // SPDX-License-Identifier: GPL-2.0 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); 110