source: benchmark/readyQ/rq_bench.hpp@ 91aa5ab

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 91aa5ab was f9b2e73, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Missed file

  • Property mode set to 100644
File size: 9.3 KB
Line 
1#include <cassert>
2#include <climits>
3#include <cstdint>
4#include <cstdio>
5
6#include <time.h> // timespec
7#include <sys/time.h> // timeval
8
9enum { TIMEGRAN = 1000000000LL }; // nanosecond granularity, except for timeval
10
11
12volatile bool stop = false;
13bool clock_mode;
14double duration = -1;
15unsigned long long stop_count = 0;
16unsigned nprocs = 1;
17unsigned nthreads = 1;
18
19volatile unsigned long long threads_left;
20
21#define BENCH_OPT \
22 {'d', "duration", "Duration of the experiments in seconds", duration }, \
23 {'i', "iterations", "Number of iterations of the experiments", stop_count }, \
24 {'t', "nthreads", "Number of threads to use", nthreads }, \
25 {'p', "nprocs", "Number of processors to use", nprocs }
26
27#define BENCH_OPT_PARSE(name) \
28 { \
29 int opt_cnt = sizeof(opt) / sizeof(option_t); \
30 char **left; \
31 parse_args( argc, argv, opt, opt_cnt, "[OPTIONS]...\n" name, &left ); \
32 if(duration > 0 && stop_count > 0) { \
33 fprintf(stderr, "--duration and --iterations cannot be used together\n"); \
34 print_args_usage(argc, argv, opt, opt_cnt, "[OPTIONS]...\n" name, true); \
35 } else if(duration > 0) { \
36 clock_mode = true; \
37 stop_count = 0xFFFFFFFFFFFFFFFF; \
38 printf("Running for %lf seconds\n", duration); \
39 } else if(stop_count > 0) { \
40 clock_mode = false; \
41 printf("Running for %llu iterations\n", stop_count); \
42 } else { \
43 duration = 5; clock_mode = true;\
44 printf("Running for %lf seconds\n", duration); \
45 } \
46 }
47
48uint64_t getTimeNsec() {
49 timespec curr;
50 clock_gettime( CLOCK_REALTIME, &curr );
51 return (int64_t)curr.tv_sec * TIMEGRAN + curr.tv_nsec;
52}
53
54uint64_t to_miliseconds( uint64_t durtn ) { return durtn / (TIMEGRAN / 1000LL); }
55double to_fseconds(uint64_t durtn ) { return durtn / (double)TIMEGRAN; }
56uint64_t from_fseconds(double sec) { return sec * TIMEGRAN; }
57
58template<typename Sleeper>
59void wait(const uint64_t & start, bool is_tty) {
60 for(;;) {
61 Sleeper::usleep(100000);
62 uint64_t end = getTimeNsec();
63 uint64_t delta = end - start;
64 if(is_tty) {
65 printf(" %.1f\r", to_fseconds(delta));
66 fflush(stdout);
67 }
68 if( clock_mode && delta >= from_fseconds(duration) ) {
69 break;
70 }
71 else if( !clock_mode && threads_left == 0 ) {
72 break;
73 }
74 }
75}
76
77// ==========================================================================================
78#include <cstdlib>
79#include <cstring>
80
81#include <algorithm>
82
83//-----------------------------------------------------------------------------
84// Typed argument parsing
85bool parse_yesno(const char * arg, bool & value ) {
86 if(strcmp(arg, "yes") == 0) {
87 value = true;
88 return true;
89 }
90
91 if(strcmp(arg, "no") == 0) {
92 value = false;
93 return true;
94 }
95
96 return false;
97}
98
99bool parse_settrue (const char *, bool & value ) {
100 value = true;
101 return true;
102}
103
104bool parse_setfalse(const char *, bool & value ) {
105 value = false;
106 return true;
107}
108
109bool parse(const char * arg, const char * & value ) {
110 value = arg;
111 return true;
112}
113
114bool parse(const char * arg, int & value) {
115 char * end;
116 int r = strtoll(arg, &end, 10);
117 if(*end != '\0') return false;
118
119 value = r;
120 return true;
121}
122
123bool parse(const char * arg, unsigned & value) {
124 char * end;
125 unsigned long long int r = strtoull(arg, &end, 10);
126 if(*end != '\0') return false;
127 if(r > UINT_MAX) return false;
128
129 value = r;
130 return true;
131}
132
133bool parse(const char * arg, unsigned long & value) {
134 char * end;
135 unsigned long long int r = strtoull(arg, &end, 10);
136 if(*end != '\0') return false;
137 if(r > ULONG_MAX) return false;
138
139 value = r;
140 return true;
141}
142
143bool parse(const char * arg, unsigned long long & value) {
144 char * end;
145 unsigned long long int r = strtoull(arg, &end, 10);
146 if(*end != '\0') return false;
147 if(r > ULLONG_MAX) return false;
148
149 value = r;
150 return true;
151}
152
153bool parse(const char * arg, double & value) {
154 char * end;
155 double r = strtod(arg, &end);
156 if(*end != '\0') return false;
157
158 value = r;
159 return true;
160}
161
162//-----------------------------------------------------------------------------
163struct option_t {
164 char short_name;
165 const char * long_name;
166 const char * help;
167 void * variable;
168 bool (*parse_fun)(const char *, void * );
169
170 template<typename T>
171 inline option_t( char short_name, const char * long_name, const char * help, T & variable ) {
172 this->short_name = short_name;
173 this->long_name = long_name;
174 this->help = help;
175 this->variable = reinterpret_cast<void*>(&variable);
176 this->parse_fun = reinterpret_cast<bool (*)(const char *, void * )>(static_cast<bool (*)(const char *, T & )>(parse));
177 }
178
179 template<typename T>
180 inline option_t( char short_name, const char * long_name, const char * help, T & variable, bool (*parse)(const char *, T & )) {
181 this->short_name = short_name;
182 this->long_name = long_name;
183 this->help = help;
184 this->variable = reinterpret_cast<void*>(&variable);
185 this->parse_fun = reinterpret_cast<bool (*)(const char *, void * )>(parse);
186 }
187};
188
189extern option_t last_option;
190
191
192//-----------------------------------------------------------------------------
193#include <cstdint>
194#include <climits>
195#include <errno.h>
196#include <unistd.h>
197extern "C" {
198 #include <getopt.h>
199 #include <sys/ioctl.h>
200
201 extern FILE * stderr;
202 extern FILE * stdout;
203
204 extern int fileno(FILE *stream);
205
206 extern int fprintf ( FILE * stream, const char * format, ... );
207
208 extern long long int strtoll (const char* str, char** endptr, int base);
209 extern unsigned long long int strtoull(const char* str, char** endptr, int base);
210 extern double strtod (const char* str, char** endptr);
211}
212
213static void usage(char * cmd, option_t options[], size_t opt_count, const char * usage, FILE * out) __attribute__ ((noreturn));
214
215//-----------------------------------------------------------------------------
216// getopt_long wrapping
217void parse_args(
218 int argc,
219 char * argv[],
220 option_t options[],
221 size_t opt_count,
222 const char * usage_msg,
223 char ** * left
224) {
225 struct option optarr[opt_count + 2];
226 {
227 int idx = 0;
228 for(int i = 0; i < opt_count; i++) {
229 if(options[i].long_name) {
230 optarr[idx].name = options[i].long_name;
231 optarr[idx].flag = nullptr;
232 optarr[idx].val = options[i].short_name;
233 if( ((intptr_t)options[i].parse_fun) == ((intptr_t)parse_settrue)
234 || ((intptr_t)options[i].parse_fun) == ((intptr_t)parse_setfalse) ) {
235 optarr[idx].has_arg = no_argument;
236 } else {
237 optarr[idx].has_arg = required_argument;
238 }
239 idx++;
240 }
241 }
242 optarr[idx+0].name = "help";
243 optarr[idx+0].has_arg = no_argument;
244 optarr[idx+0].flag = 0;
245 optarr[idx+0].val = 'h';
246 optarr[idx+1].name = 0;
247 optarr[idx+1].has_arg = no_argument;
248 optarr[idx+1].flag = 0;
249 optarr[idx+1].val = 0;
250 }
251
252 char optstring[opt_count * 3];
253 for(auto & o : optstring) {
254 o = '\0';
255 }
256 {
257 int idx = 0;
258 for(int i = 0; i < opt_count; i++) {
259 optstring[idx] = options[i].short_name;
260 idx++;
261 if( ((intptr_t)options[i].parse_fun) != ((intptr_t)parse_settrue)
262 && ((intptr_t)options[i].parse_fun) != ((intptr_t)parse_setfalse) ) {
263 optstring[idx] = ':';
264 idx++;
265 }
266 }
267 optstring[idx+0] = 'h';
268 optstring[idx+1] = '\0';
269 }
270
271 FILE * out = stderr;
272 for(;;) {
273 int idx = 0;
274 int opt = getopt_long(argc, argv, optstring, optarr, &idx);
275 switch(opt) {
276 case -1:
277 if(left != nullptr) *left = argv + optind;
278 return;
279 case 'h':
280 out = stdout;
281 case '?':
282 usage(argv[0], options, opt_count, usage_msg, out);
283 default:
284 for(int i = 0; i < opt_count; i++) {
285 if(opt == options[i].short_name) {
286 const char * arg = optarg ? optarg : "";
287 bool success = options[i].parse_fun( arg, options[i].variable );
288 if(success) goto NEXT_ARG;
289
290 fprintf(out, "Argument '%s' for option %c could not be parsed\n\n", arg, (char)opt);
291 usage(argv[0], options, opt_count, usage_msg, out);
292 }
293 }
294 std::abort();
295 }
296 NEXT_ARG:;
297 }
298}
299
300//-----------------------------------------------------------------------------
301// Print usage
302static void printopt(FILE * out, int width, int max, char sn, const char * ln, const char * help) {
303 int hwidth = max - (11 + width);
304 if(hwidth <= 0) hwidth = max;
305
306 fprintf(out, " -%c, --%-*s %.*s\n", sn, width, ln, hwidth, help);
307 for(;;) {
308 help += std::min(strlen(help), (unsigned long)hwidth);
309 if('\0' == *help) break;
310 fprintf(out, "%*s%.*s\n", width + 11, "", hwidth, help);
311 }
312}
313
314__attribute__((noreturn)) void print_args_usage(int , char * argv[], option_t options[], size_t opt_count, const char * usage_msg, bool error) {
315 usage(argv[0], options, opt_count, usage_msg, error ? stderr : stdout);
316}
317
318static __attribute__((noreturn)) void usage(char * cmd, option_t options[], size_t opt_count, const char * help, FILE * out) {
319 int width = 0;
320 {
321 for(int i = 0; i < opt_count; i++) {
322 if(options[i].long_name) {
323 int w = strlen(options[i].long_name);
324 if(w > width) width = w;
325 }
326 }
327 }
328
329 int max_width = 1000000;
330 int outfd = fileno(out);
331 if(isatty(outfd)) {
332 struct winsize size;
333 int ret = ioctl(outfd, TIOCGWINSZ, &size);
334 if(ret < 0) abort(); // "ioctl error: (%d) %s\n", (int)errno, strerror(errno)
335 max_width = size.ws_col;
336 }
337
338 fprintf(out, "Usage:\n %s %s\n", cmd, help);
339
340 for(int i = 0; i < opt_count; i++) {
341 printopt(out, width, max_width, options[i].short_name, options[i].long_name, options[i].help);
342 }
343 fprintf(out, " -%c, --%-*s %s\n", 'h', width, "help", "print this help message");
344 exit(out == stdout ? 0 : 1);
345}
346
Note: See TracBrowser for help on using the repository browser.