tests: benchmark: improve benchmark scalability accuracy
[deliverable/lttng-ust.git] / tests / benchmark / bench.c
1 /*
2 * bench.c
3 *
4 * LTTng Userspace Tracer (UST) - benchmark tool
5 *
6 * Copyright 2010 - Douglas Santos <douglas.santos@polymtl.ca>
7 * Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24 #define _GNU_SOURCE
25 #include <stdio.h>
26 #include <pthread.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <sched.h>
30 #include <time.h>
31 #include <urcu/compiler.h>
32
33 #ifdef TRACING
34 #define TRACEPOINT_DEFINE
35 #include "ust_tests_benchmark.h"
36 #endif
37
38 #define printf_verbose(fmt, args...) \
39 do { \
40 if (verbose_mode) \
41 printf(fmt, ## args); \
42 } while (0)
43
44 static int verbose_mode;
45
46 struct thread_counter {
47 unsigned long long nr_loops;
48 };
49
50 static int nr_threads;
51 static unsigned long duration;
52
53 static volatile int test_go, test_stop;
54
55 void do_stuff(void)
56 {
57 int i;
58 #ifdef TRACING
59 int v = 50;
60 #endif
61
62 for (i = 0; i < 100; i++)
63 cmm_barrier();
64 #ifdef TRACING
65 tracepoint(ust_tests_benchmark, tpbench, v);
66 #endif
67 }
68
69 void *function(void *arg)
70 {
71 unsigned long long nr_loops = 0;
72 struct thread_counter *thread_counter = arg;
73
74 while (!test_go)
75 cmm_barrier();
76
77 for (;;) {
78 do_stuff();
79 nr_loops++;
80 if (test_stop)
81 break;
82 }
83 thread_counter->nr_loops = nr_loops;
84 return NULL;
85 }
86
87 void usage(char **argv) {
88 printf("Usage: %s nr_threads duration(s) <OPTIONS>\n", argv[0]);
89 printf("OPTIONS:\n");
90 printf(" [-v] (verbose output)\n");
91 printf("\n");
92 }
93
94 int main(int argc, char **argv)
95 {
96 unsigned long long total_loops = 0;
97 unsigned long i_thr;
98 void *retval;
99 int i;
100
101 if (argc < 3) {
102 usage(argv);
103 exit(1);
104 }
105
106 nr_threads = atoi(argv[1]);
107 duration = atol(argv[2]);
108
109 for (i = 3; i < argc; i++) {
110 if (argv[i][0] != '-')
111 continue;
112 switch (argv[i][1]) {
113 case 'v':
114 verbose_mode = 1;
115 break;
116 }
117 }
118
119 printf_verbose("using %d thread(s)\n", nr_threads);
120 printf_verbose("for a duration of %lds\n", duration);
121
122 pthread_t thread[nr_threads];
123 struct thread_counter thread_counter[nr_threads];
124
125 for (i = 0; i < nr_threads; i++) {
126 thread_counter[i].nr_loops = 0;
127 if (pthread_create(&thread[i], NULL, function, &thread_counter[i])) {
128 fprintf(stderr, "thread create %d failed\n", i);
129 exit(1);
130 }
131 }
132
133 test_go = 1;
134
135 for (i_thr = 0; i_thr < duration; i_thr++) {
136 sleep(1);
137 if (verbose_mode) {
138 fwrite(".", sizeof(char), 1, stdout);
139 fflush(stdout);
140 }
141 }
142 printf_verbose("\n");
143
144 test_stop = 1;
145
146 for (i = 0; i < nr_threads; i++) {
147 if (pthread_join(thread[i], &retval)) {
148 fprintf(stderr, "thread join %d failed\n", i);
149 exit(1);
150 }
151 total_loops += thread_counter[i].nr_loops;
152 }
153 printf("Number of loops: %llu\n", total_loops);
154 return 0;
155 }
This page took 0.03547 seconds and 5 git commands to generate.