-
Notifications
You must be signed in to change notification settings - Fork 13
/
bench.cc
113 lines (86 loc) · 2.48 KB
/
bench.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <sys/resource.h>
#include <unistd.h>
#include <chrono>
#include <iostream>
#include <core/epoll.hh>
#include <core/poll.hh>
#include <core/select.hh>
#include <model/reactor.hh>
using namespace std;
using namespace chrono;
using Clock = chrono::high_resolution_clock;
static int num_pipes, num_active, num_writes;
static int *pipes;
static wxg::reactor<wxg::epoll> re;
static int countread = 0, fired = 0, writes = 0;
void readcb(int i) {
u_char ch;
countread += read(pipes[2 * i], &ch, sizeof(ch));
if (writes) {
int nexti = i + 1;
if (nexti >= num_pipes) nexti -= num_pipes;
write(pipes[2 * nexti + 1], "a", 1);
writes--, fired++;
}
}
int run_once() {
cout << __func__ << endl;
countread = fired = 0, writes = num_writes;
int space = num_pipes / num_active;
space *= 2;
re.loop(true, true);
for (int i = 0; i < num_active; i++, fired++) {
write(pipes[i * space + 1], "a", 1);
}
auto t1 = Clock::now();
int xcount = 0;
do {
re.loop(true, true);
xcount++;
} while (countread != fired);
auto t2 = Clock::now();
auto time_span = duration_cast<duration<double>>(t2 - t1);
if (xcount != countread)
cerr << "Xcount: " << xcount << ", Rcount: " << countread << endl;
return 1000 * 1000 * time_span.count();
}
int main(int argc, char *const argv[]) {
num_pipes = 100;
num_active = 1;
num_writes = num_pipes / 2;
int c;
extern char *optarg;
while ((c = getopt(argc, argv, "n:a:w:")) != -1) {
switch (c) {
case 'n':
num_pipes = atoi(optarg);
break;
case 'a':
num_active = atoi(optarg);
break;
case 'w':
num_writes = atoi(optarg);
break;
default:
cerr << "illegal argument" << endl;
break;
}
}
struct rlimit rl;
rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50;
if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
cerr << "setrlimit\n";
exit(1);
}
pipes = new int[num_pipes * 2];
for (int *cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
if (pipe(cp) == -1) {
cerr << "error pipe errno=" << errno << endl;
exit(-1);
}
re.set_read_handler(pipes[2 * i], [=]() { readcb(i); });
}
for (int i = 0; i < 25; i++) cout << run_once() << endl;
delete[] pipes;
return 0;
}