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 9struct args { 10 pthread_t th; 11 unsigned int in; 12 void *ret; 13}; 14 15static 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 41static 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 51int main(int argc, char **argv) 52{ 53 unsigned int i, thr; 54 struct args args[256]; 55 56 if (argc < 2) { 57 printf("ERR: %s [numthreads]\n", argv[0]); 58 exit(1); 59 } 60 61 thr = atoi(argv[1]); 62 if ((thr > 256) || (thr < 1)) { 63 printf("ERR: threads 1-256\n"); 64 exit(1); 65 } 66 for (i = 0; i < thr; i++) { 67 args[i].in = rand(); 68 args[i].th = new_thr(thrfn, &(args[i])); 69 } 70 for (i = 0; i < thr; i++) 71 pthread_join(args[i].th, &(args[i].ret)); 72 return 0; 73} 74