1 // SPDX-License-Identifier: GPL-2.0 2 // Carsten Haitzler <carsten.haitzler@arm.com>, 2021 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <unistd.h> 6 #include <string.h> 7 #include <pthread.h> 8 9 struct args { 10 pthread_t th; 11 unsigned int in; 12 void *ret; 13 }; 14 15 static void *thrfn(void *arg) 16 { 17 struct args *a = arg; 18 unsigned int i, in = a->in; 19 20 for (i = 0; i < 10000; i++) { 21 asm volatile ( 22 // force an unroll of thia add instruction so we can test long runs of code 23 #define SNIP1 "add %[in], %[in], #1\n" 24 // 10 25 #define SNIP2 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 26 // 100 27 #define SNIP3 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 28 // 1000 29 #define SNIP4 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 30 // 10000 31 #define SNIP5 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 32 // 100000 33 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 34 : /* out */ 35 : /* in */ [in] "r" (in) 36 : /* clobber */ 37 ); 38 } 39 } 40 41 static pthread_t new_thr(void *(*fn) (void *arg), void *arg) 42 { 43 pthread_t t; 44 pthread_attr_t attr; 45 46 pthread_attr_init(&attr); 47 pthread_create(&t, &attr, fn, arg); 48 return t; 49 } 50 51 int main(int argc, char **argv) 52 { 53 unsigned int i, thr; 54 pthread_t threads[256]; 55 struct args args[256]; 56 57 if (argc < 2) { 58 printf("ERR: %s [numthreads]\n", argv[0]); 59 exit(1); 60 } 61 62 thr = atoi(argv[1]); 63 if ((thr > 256) || (thr < 1)) { 64 printf("ERR: threads 1-256\n"); 65 exit(1); 66 } 67 for (i = 0; i < thr; i++) { 68 args[i].in = rand(); 69 args[i].th = new_thr(thrfn, &(args[i])); 70 } 71 for (i = 0; i < thr; i++) 72 pthread_join(args[i].th, &(args[i].ret)); 73 return 0; 74 } 75