source: benchmark/readyQ/rq_bench.hfa @ 3959595

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 3959595 was 2c7eee0, checked in by Thierry Delisle <tdelisle@…>, 4 years ago

Fixed cycle benchmark to avoid extra unmatched unpark.
Added libfibre implementation.
Split out go common code into bench.go

  • Property mode set to 100644
File size: 3.3 KB
Line 
1#include <clock.hfa>
2#include <kernel.hfa>
3#include <parseargs.hfa>
4#include <stdio.h>
5#include <stdlib.hfa>
6#include <thread.hfa>
7#include <time.hfa>
8#include <unistd.h>
9
10volatile bool stop = false;
11bool clock_mode;
12double duration = -1;
13unsigned long long stop_count = 0;
14unsigned nprocs = 1;
15unsigned nthreads = 1;
16
17volatile unsigned long long threads_left;
18
19#define thread_loop for(this.count = 0;; this.count++)
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(cfa_option); \
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 %lu iterations\n", stop_count); \
42                } else { \
43                        duration = 5; clock_mode = true;\
44                        printf("Running for %lf seconds\n", duration); \
45                } \
46        }
47
48struct cluster & bench_cluster;
49
50struct BenchCluster {
51        cluster cl;
52        processor * procs;
53        unsigned nprocs;
54};
55
56void ?{}( BenchCluster & this, unsigned nprocs ) {
57        (this.cl){ "Benchmark Cluster" };
58        &bench_cluster = &this.cl;
59        this.nprocs = nprocs;
60        this.procs  = alloc( this.nprocs );
61        for(i; this.nprocs){
62                processor * p = &this.procs[i];
63                (*p){ "Benchmark Processor", this.cl };
64        }
65}
66
67void ^?{}( BenchCluster & this ) {
68        adelete( this.procs );
69        ^(this.cl){};
70}
71
72void wait(const Time & start, bool is_tty) {
73        for() {
74                sleep(100`ms);
75                Time end = getTimeNsec();
76                Duration delta = end - start;
77                if(is_tty) {
78                        printf(" %.1f\r", delta`ds);
79                        fflush(stdout);
80                }
81                if( clock_mode && delta >= duration`s ) {
82                        break;
83                }
84                else if( !clock_mode && threads_left == 0 ) {
85                        break;
86                }
87        }
88}
89
90struct bench_sem {
91        struct $thread * volatile ptr;
92};
93
94static inline {
95        void  ?{}(bench_sem & this) {
96                this.ptr = 0p;
97        }
98
99        void ^?{}(bench_sem & this) {}
100
101        bool wait(bench_sem & this) {
102                for() {
103                        struct $thread * expected = this.ptr;
104                        if(expected == 1p) {
105                                if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
106                                        return false;
107                                }
108                        }
109                        else {
110                                /* paranoid */ verify( expected == 0p );
111                                if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
112                                        park();
113                                        return true;
114                                }
115                        }
116
117                }
118        }
119
120        bool post(bench_sem & this) {
121                for() {
122                        struct $thread * expected = this.ptr;
123                        if(expected == 1p) return false;
124                        if(expected == 0p) {
125                                if(__atomic_compare_exchange_n(&this.ptr, &expected, 1p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
126                                        return false;
127                                }
128                        }
129                        else {
130                                if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
131                                        unpark( expected );
132                                        return true;
133                                }
134                        }
135                }
136        }
137}
Note: See TracBrowser for help on using the repository browser.