at master 1.6 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2#include <pthread.h> 3#include <stdlib.h> 4#include <signal.h> 5#include <unistd.h> 6#include <linux/compiler.h> 7#include "../tests.h" 8 9static volatile sig_atomic_t done; 10 11/* We want to check this symbol in perf report */ 12noinline void test_loop(void); 13 14static void sighandler(int sig __maybe_unused) 15{ 16 done = 1; 17} 18 19noinline void test_loop(void) 20{ 21 while (!done); 22} 23 24static void *thfunc(void *arg) 25{ 26 void (*loop_fn)(void) = arg; 27 28 loop_fn(); 29 return NULL; 30} 31 32static int thloop(int argc, const char **argv) 33{ 34 int nt = 2, sec = 1, err = 1; 35 pthread_t *thread_list = NULL; 36 37 if (argc > 0) 38 sec = atoi(argv[0]); 39 40 if (sec <= 0) { 41 fprintf(stderr, "Error: seconds (%d) must be >= 1\n", sec); 42 return 1; 43 } 44 45 if (argc > 1) 46 nt = atoi(argv[1]); 47 48 if (nt <= 0) { 49 fprintf(stderr, "Error: thread count (%d) must be >= 1\n", nt); 50 return 1; 51 } 52 53 signal(SIGINT, sighandler); 54 signal(SIGALRM, sighandler); 55 56 thread_list = calloc(nt, sizeof(pthread_t)); 57 if (thread_list == NULL) { 58 fprintf(stderr, "Error: malloc failed for %d threads\n", nt); 59 goto out; 60 } 61 for (int i = 1; i < nt; i++) { 62 int ret = pthread_create(&thread_list[i], NULL, thfunc, test_loop); 63 64 if (ret) { 65 fprintf(stderr, "Error: failed to create thread %d\n", i); 66 done = 1; // Ensure started threads terminate. 67 goto out; 68 } 69 } 70 alarm(sec); 71 test_loop(); 72 err = 0; 73out: 74 for (int i = 1; i < nt; i++) { 75 if (thread_list && thread_list[i]) 76 pthread_join(thread_list[i], /*retval=*/NULL); 77 } 78 free(thread_list); 79 return err; 80} 81 82DEFINE_WORKLOAD(thloop);