source: benchmark/readyQ/rq_bench.hpp @ 6ae5c22

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 6ae5c22 was f9b2e73, checked in by Thierry Delisle <tdelisle@…>, 4 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.