xref: /openbmc/qemu/tests/tcg/multiarch/threadcount.c (revision c86274bc2e34295764fb44c2aef3cf29623f9b4b)
1*919bfbf5SAlex Bennée /*
2*919bfbf5SAlex Bennée  * Thread Exerciser
3*919bfbf5SAlex Bennée  *
4*919bfbf5SAlex Bennée  * Unlike testthread which is mainly concerned about testing thread
5*919bfbf5SAlex Bennée  * semantics this test is used to exercise the thread creation and
6*919bfbf5SAlex Bennée  * accounting. A version of this test found a problem with clashing
7*919bfbf5SAlex Bennée  * cpu_indexes which caused a break in plugin handling.
8*919bfbf5SAlex Bennée  *
9*919bfbf5SAlex Bennée  * Based on the original test case by Nikolay Igotti.
10*919bfbf5SAlex Bennée  *
11*919bfbf5SAlex Bennée  * Copyright (c) 2020 Linaro Ltd
12*919bfbf5SAlex Bennée  *
13*919bfbf5SAlex Bennée  * SPDX-License-Identifier: GPL-2.0-or-later
14*919bfbf5SAlex Bennée  */
15*919bfbf5SAlex Bennée 
16*919bfbf5SAlex Bennée #include <stdint.h>
17*919bfbf5SAlex Bennée #include <stdio.h>
18*919bfbf5SAlex Bennée #include <stdlib.h>
19*919bfbf5SAlex Bennée #include <unistd.h>
20*919bfbf5SAlex Bennée #include <pthread.h>
21*919bfbf5SAlex Bennée 
22*919bfbf5SAlex Bennée int max_threads = 10;
23*919bfbf5SAlex Bennée 
24*919bfbf5SAlex Bennée typedef struct {
25*919bfbf5SAlex Bennée     int delay;
26*919bfbf5SAlex Bennée } ThreadArg;
27*919bfbf5SAlex Bennée 
thread_fn(void * varg)28*919bfbf5SAlex Bennée static void *thread_fn(void* varg)
29*919bfbf5SAlex Bennée {
30*919bfbf5SAlex Bennée     ThreadArg *arg = varg;
31*919bfbf5SAlex Bennée     usleep(arg->delay);
32*919bfbf5SAlex Bennée     free(arg);
33*919bfbf5SAlex Bennée     return NULL;
34*919bfbf5SAlex Bennée }
35*919bfbf5SAlex Bennée 
main(int argc,char ** argv)36*919bfbf5SAlex Bennée int main(int argc, char **argv)
37*919bfbf5SAlex Bennée {
38*919bfbf5SAlex Bennée     int i;
39*919bfbf5SAlex Bennée     pthread_t *threads;
40*919bfbf5SAlex Bennée 
41*919bfbf5SAlex Bennée     if (argc > 1) {
42*919bfbf5SAlex Bennée         max_threads = atoi(argv[1]);
43*919bfbf5SAlex Bennée     }
44*919bfbf5SAlex Bennée     threads = calloc(sizeof(pthread_t), max_threads);
45*919bfbf5SAlex Bennée 
46*919bfbf5SAlex Bennée     for (i = 0; i < max_threads; i++) {
47*919bfbf5SAlex Bennée         ThreadArg *arg = calloc(sizeof(ThreadArg), 1);
48*919bfbf5SAlex Bennée         arg->delay = i * 100;
49*919bfbf5SAlex Bennée         pthread_create(threads + i, NULL, thread_fn, arg);
50*919bfbf5SAlex Bennée     }
51*919bfbf5SAlex Bennée 
52*919bfbf5SAlex Bennée     printf("Created %d threads\n", max_threads);
53*919bfbf5SAlex Bennée 
54*919bfbf5SAlex Bennée     /* sleep until roughly half the threads have "finished" */
55*919bfbf5SAlex Bennée     usleep(max_threads * 50);
56*919bfbf5SAlex Bennée 
57*919bfbf5SAlex Bennée     for (i = 0; i < max_threads; i++) {
58*919bfbf5SAlex Bennée         pthread_join(threads[i], NULL);
59*919bfbf5SAlex Bennée     }
60*919bfbf5SAlex Bennée 
61*919bfbf5SAlex Bennée     printf("Done\n");
62*919bfbf5SAlex Bennée 
63*919bfbf5SAlex Bennée     return 0;
64*919bfbf5SAlex Bennée }
65