-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspy.cpp
170 lines (146 loc) · 4.5 KB
/
spy.cpp
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include "libdd_spy.hpp"
#define CONTENTION_DETECT_COUNT 10
#define LO_DETECT_WAIT 1500
#define HI_DETECT_WAIT 700
#define CONTENTION_WAIT 2000
#define STATE_CHANGE_COUNT 4
#define PERIOD 1300000L
#define PROBE_WAIT 700
#define LARGE_BACK_OFF 3000
#define BACK_OFF 1000
#define SMALL_WAIT 300
uint64_t u64;
unsigned long long t;
inline int rdseed(uint64_t *seed) {
unsigned char ok;
asm volatile ("rdseed %0; setc %1": "=r" (*seed), "=qm" (ok));
return (int)ok;
}
inline void rdtsc_wait(unsigned long long n) {
unsigned long long init = __rdtsc();
while (__rdtsc() - init < n) {
// spin
}
}
int dd_send(const uint8_t* packet, size_t size) {
return EXIT_SUCCESS;
}
int dd_recv(uint8_t *packet, size_t *size, bool fitf) {
int curr_state = 1;
int red_flag = 0;
int bits_recv = 0;
unsigned long long curr, before = 0;
int bits_to_recv;
if (fitf) {
bits_to_recv = FITF_LEN;
} else {
bits_to_recv = CHUNK_ID_LEN + CHUNK_LEN;
}
// detect lo
int miss_counter = 0;
int hit_counter = 0;
while (hit_counter < STATE_CHANGE_COUNT) {
if (rdseed(&u64) == RDSEED_SUCCESS) {
// rdseed accessed --> low contention
hit_counter++;
miss_counter = 0;
} else {
// rdseed missed, indicates high contention
miss_counter++;
hit_counter = 0;
}
if (miss_counter >= 3) {
rdtsc_wait(LO_DETECT_WAIT);
}
}
// detect high contention
for (int i = 0; i < 2; i++) {
miss_counter = 0;
while (miss_counter < STATE_CHANGE_COUNT) {
if (rdseed(&u64) != RDSEED_SUCCESS) {
// rdseed failed
miss_counter++;
} else {
miss_counter = 0;
}
rdtsc_wait(HI_DETECT_WAIT);
}
}
while (bits_recv < bits_to_recv) {
if (rdseed(&u64) == RDSEED_SUCCESS) {
// if zero is received
if (curr_state == 1 && red_flag < STATE_CHANGE_COUNT) {
// could be noise
red_flag++;
} else if (curr_state == 1 && red_flag >= STATE_CHANGE_COUNT) {
// definitely not noise, change state
curr_state = 0;
red_flag = 0;
curr = __rdtsc();
if (curr - before > PERIOD || bits_recv == 0) {
before = curr;
packet[bits_recv] = '1';
bits_recv++;
}
} else if (curr_state == 0 && red_flag <= STATE_CHANGE_COUNT) {
// status-quo
red_flag = 0;
} else {
printf("Weird shit happened, exiting!");
printf("curr_state: %d, red_flag: %d, zero\n", curr_state, red_flag);
return EXIT_FAILURE;
}
} else {
// if one is received
if (curr_state == 0 && red_flag < STATE_CHANGE_COUNT) {
// could be noise
red_flag++;
} else if (curr_state == 0 && red_flag >= STATE_CHANGE_COUNT) {
// definitely not noise, change state
curr_state = 1;
red_flag = 0;
curr = __rdtsc();
if (curr - before > PERIOD || bits_recv == 0) {
before = curr;
packet[bits_recv] = '0';
bits_recv++;
}
} else if (curr_state == 1 && red_flag <= STATE_CHANGE_COUNT) {
// status-quo
red_flag = 0;
} else {
printf("Weird shit happened, exiting!");
printf("curr_state: %d, red_flag: %d, one\n", curr_state, red_flag);
return EXIT_FAILURE;
}
}
rdtsc_wait(PROBE_WAIT);
}
size = (size_t*) &bits_recv;
// for (int i = 0; i < bits_recv; i++) {
// printf("bit: %d\n", packet[i]);
// }
return EXIT_SUCCESS;
}
inline void init_channel() {
int miss_counter = 0;
uint64_t u64;
while (miss_counter < CONTENTION_DETECT_COUNT) {
if (rdseed(&u64) != RDSEED_SUCCESS) {
// rdseed failed
miss_counter++;
} else {
miss_counter = 0;
}
rdtsc_wait(CONTENTION_WAIT);
}
}
int main() {
spy_sess_t sess;
init_spy(&sess, &dd_recv, &dd_send);
while (true) {
init_channel();
start_spy_sess(&sess);
}
return EXIT_SUCCESS;
}