-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMain.cpp
More file actions
163 lines (131 loc) · 3.83 KB
/
Main.cpp
File metadata and controls
163 lines (131 loc) · 3.83 KB
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
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <atomic>
#include "Common/Constants.h"
#include "Common/SharedMemory.h"
#include "Common/Types.h"
#include "Common/Event.h"
using namespace Monitor;
SharedMemory* shm;
u64 num_events = 0;
std::atomic_uint8_t stop;
int pid;
void handle_sigint(int sig) {
stop.store(1);
// printf("Num events: %llu\n", num_events);
// exit(0);
}
u64 off(u32 idx, u32 offset) { return (idx + offset) & BUF_IDX_MASK; }
u64 handle_event(Sid sid, LoggedEvent ev, SharedMemory *shm) {
int steps = 0;
u64 value = 0, counter = 0, old_value = 0, new_value = 0;
switch (ev.event_type) {
case WRITE:
case READ:
steps = 1;
value = shm->Consume(sid).raw;
printf("[MONITOR] #%u/%u: %s %p %#llx\n", sid, ev.lap_num, eventtype_to_string(ev.event_type), ev.addr, value);
break;
case ATOMICLOAD:
case ATOMICSTORE:
steps = 2;
counter = shm->Consume(sid).raw;
value = shm->Consume(sid).raw;
printf("[MONITOR] #%u/%u: %s %p %#llx (#%u)\n", sid, ev.lap_num, eventtype_to_string(ev.event_type), ev.addr, value, counter);
break;
case ATOMICRMW:
case ATOMICCAS:
steps = 3;
counter = shm->Consume(sid).raw;
old_value = shm->Consume(sid).raw;
new_value = shm->Consume(sid).raw;
printf("[MONITOR] #%u/%u: %s %p %#llx %#llx (#%u)\n", sid, ev.lap_num, eventtype_to_string(ev.event_type), ev.addr, old_value, new_value, counter);
break;
default:
printf("[MONITOR] #%u/%u: %s %p\n", sid, ev.lap_num, eventtype_to_string(ev.event_type), ev.addr);
break;
}
return steps;
}
// Thread function
void *worker(void *arg) {
u64* data = (u64*)arg;
Tid tid = *data;
u64 slot_counts[SLOTS_PER_WORKER];
for (u8 i = 0; i < SLOTS_PER_WORKER; ++i) {
Sid sid = i*NUM_WORKERS+tid;
shm->Open(sid);
slot_counts[i] = 0;
}
// Tell the program it can start.
if (tid == 0) shm->Ready();
while (!stop.load()) {
for (u8 i = 0; i < SLOTS_PER_WORKER; ++i) {
Sid sid = i*NUM_WORKERS+tid;
if (!shm->IsOpened(sid)) continue;
do {
LoggedEvent ev = shm->Consume(sid);
if (ev.raw != kEvClear.raw) {
// Handle event
int steps = handle_event(sid, ev, shm);
slot_counts[i]++;
if (HasProgramEnded(ev)) {
shm->Close(sid);
stop.store(1);
printf("[MONITOR] #%u Exit!\n", sid);
}
}
else break; // if data is not ready we dont want to loop
} while (slot_counts[i] % 16 != 0 && !stop); // read up to cache line alignment to maximise throughput
}
}
u64 total_count = 0;
for (u8 i = 0; i < SLOTS_PER_WORKER; ++i) {
total_count += slot_counts[i];
}
*data = total_count;
for (Sid sid = 0; sid < SLOTS_PER_WORKER; ++sid) {
shm->Close(sid);
}
return 0;
}
int main(int argc, char** argv)
{
if (argc < 2) {
printf("[!] Usage: %s <pid>\n", argv[0]);
}
pid = atoi(argv[1]);
shm = new SharedMemory(pid);
printf("[+] Monitor started on pid %d\n", pid);
signal(SIGINT, handle_sigint);
stop.store(0);
pthread_t workers[NUM_WORKERS];
u64 worker_data[NUM_WORKERS];
// Spawn threads
for (int i = 0; i < NUM_WORKERS; i++) {
worker_data[i] = i; // Assign a unique ID to each thread
if (pthread_create(&workers[i], NULL, worker, &worker_data[i]) != 0) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
}
// Wait for all threads to complete
for (int i = 0; i < NUM_WORKERS; i++) {
if (pthread_join(workers[i], NULL) != 0) {
perror("pthread_join");
exit(EXIT_FAILURE);
}
printf("worker #%u: %lu\n", i, worker_data[i]);
num_events += worker_data[i];
}
printf("Num events: %lu\n", num_events);
delete shm;
return 0;
}