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	unsigned long loops;
11	unsigned long size;
12	pthread_t th;
13	void *ret;
14};
15
16static void *thrfn(void *arg)
17{
18	struct args *a = arg;
19	unsigned long i, len = a->loops;
20	unsigned char *src, *dst;
21
22	src = malloc(a->size * 1024);
23	dst = malloc(a->size * 1024);
24	if ((!src) || (!dst)) {
25		printf("ERR: Can't allocate memory\n");
26		exit(1);
27	}
28	for (i = 0; i < len; i++)
29		memcpy(dst, src, a->size * 1024);
30}
31
32static pthread_t new_thr(void *(*fn) (void *arg), void *arg)
33{
34	pthread_t t;
35	pthread_attr_t attr;
36
37	pthread_attr_init(&attr);
38	pthread_create(&t, &attr, fn, arg);
39	return t;
40}
41
42int main(int argc, char **argv)
43{
44	unsigned long i, len, size, thr;
45	struct args args[256];
46	long long v;
47
48	if (argc < 4) {
49		printf("ERR: %s [copysize Kb] [numthreads] [numloops (hundreds)]\n", argv[0]);
50		exit(1);
51	}
52
53	v = atoll(argv[1]);
54	if ((v < 1) || (v > (1024 * 1024))) {
55		printf("ERR: max memory 1GB (1048576 KB)\n");
56		exit(1);
57	}
58	size = v;
59	thr = atol(argv[2]);
60	if ((thr < 1) || (thr > 256)) {
61		printf("ERR: threads 1-256\n");
62		exit(1);
63	}
64	v = atoll(argv[3]);
65	if ((v < 1) || (v > 40000000000ll)) {
66		printf("ERR: loops 1-40000000000 (hundreds)\n");
67		exit(1);
68	}
69	len = v * 100;
70	for (i = 0; i < thr; i++) {
71		args[i].loops = len;
72		args[i].size = size;
73		args[i].th = new_thr(thrfn, &(args[i]));
74	}
75	for (i = 0; i < thr; i++)
76		pthread_join(args[i].th, &(args[i].ret));
77	return 0;
78}
79