tests: benchmark: improve benchmark scalability accuracy
[lttng-ust.git] / tests / benchmark / bench.c
1 /*
2 * SPDX-License-Identifier: GPL-2.0-or-later
3 *
4 * Copyright 2010 Douglas Santos <douglas.santos@polymtl.ca>
5 * Copyright 2021 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 *
7 * LTTng Userspace Tracer (UST) - benchmark tool
8 */
9
10 #include <stdio.h>
11 #include <pthread.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <sched.h>
15 #include <time.h>
16 #include <urcu/compiler.h>
17
18 #ifdef TRACING
19 #define TRACEPOINT_DEFINE
20 #include "ust_tests_benchmark.h"
21 #endif
22
23 #define printf_verbose(fmt, args...) \
24 do { \
25 if (verbose_mode) \
26 printf(fmt, ## args); \
27 } while (0)
28
29 static int verbose_mode;
30
31 struct thread_counter {
32 unsigned long long nr_loops;
33 };
34
35 static int nr_threads;
36 static unsigned long duration;
37
38 static volatile int test_go, test_stop;
39
40 void do_stuff(void)
41 {
42 int i;
43 #ifdef TRACING
44 int v = 50;
45 #endif
46
47 for (i = 0; i < 100; i++)
48 cmm_barrier();
49 #ifdef TRACING
50 tracepoint(ust_tests_benchmark, tpbench, v);
51 #endif
52 }
53
54 void *function(void *arg)
55 {
56 unsigned long long nr_loops = 0;
57 struct thread_counter *thread_counter = arg;
58
59 while (!test_go)
60 cmm_barrier();
61
62 for (;;) {
63 do_stuff();
64 nr_loops++;
65 if (test_stop)
66 break;
67 }
68 thread_counter->nr_loops = nr_loops;
69 return NULL;
70 }
71
72 void usage(char **argv) {
73 printf("Usage: %s nr_threads duration(s) <OPTIONS>\n", argv[0]);
74 printf("OPTIONS:\n");
75 printf(" [-v] (verbose output)\n");
76 printf("\n");
77 }
78
79 int main(int argc, char **argv)
80 {
81 unsigned long long total_loops = 0;
82 unsigned long i_thr;
83 void *retval;
84 int i;
85
86 if (argc < 3) {
87 usage(argv);
88 exit(1);
89 }
90
91 nr_threads = atoi(argv[1]);
92 duration = atol(argv[2]);
93
94 for (i = 3; i < argc; i++) {
95 if (argv[i][0] != '-')
96 continue;
97 switch (argv[i][1]) {
98 case 'v':
99 verbose_mode = 1;
100 break;
101 }
102 }
103
104 printf_verbose("using %d thread(s)\n", nr_threads);
105 printf_verbose("for a duration of %lds\n", duration);
106
107 pthread_t thread[nr_threads];
108 struct thread_counter thread_counter[nr_threads];
109
110 for (i = 0; i < nr_threads; i++) {
111 thread_counter[i].nr_loops = 0;
112 if (pthread_create(&thread[i], NULL, function, &thread_counter[i])) {
113 fprintf(stderr, "thread create %d failed\n", i);
114 exit(1);
115 }
116 }
117
118 test_go = 1;
119
120 for (i_thr = 0; i_thr < duration; i_thr++) {
121 sleep(1);
122 if (verbose_mode) {
123 fwrite(".", sizeof(char), 1, stdout);
124 fflush(stdout);
125 }
126 }
127 printf_verbose("\n");
128
129 test_stop = 1;
130
131 for (i = 0; i < nr_threads; i++) {
132 if (pthread_join(thread[i], &retval)) {
133 fprintf(stderr, "thread join %d failed\n", i);
134 exit(1);
135 }
136 total_loops += thread_counter[i].nr_loops;
137 }
138 printf("Number of loops: %llu\n", total_loops);
139 return 0;
140 }
This page took 0.03388 seconds and 5 git commands to generate.