-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathExtractSegment.cc
129 lines (115 loc) · 4.22 KB
/
ExtractSegment.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include <unordered_set>
#include <unordered_map>
#include <vector>
/*
* This hack will be used to extract segments for an Arachne visualizer used for debugging.
* It can either extract the events within a time range or the events that are
* concurrent with a specific event.
* The input order is currently <creation> <start> <endtime> <coreIds> <TID>
*/
enum EventType {
CREATION, // Time that a thread is created
START, // TIme that at thread begins executing user code
END // Time that a thread returns control to Arachne
};
/**
* Objects of this type represent a thread being created, beginning to run,
* and returning control to Arachne. Currently we expect applications to
* perform their own logging. It is not baked into the thread library to avoid
* overheads and complexity.
*
* Arachne provides only the data structures, and will perform logging of its
* own internal threads for consistency.
*/
struct Event {
// Time that this event occurred.
uint64_t time;
// A user-specified thread Id.
uint32_t appThreadId;
int coreId;
EventType type;
};
struct Record {
uint64_t creationTime;
// This may eventually generalize, for this specific application it is
// fine.
uint64_t startTime;
uint64_t endTime;
int coreId;
};
int main(int argc, char** argv){
if (argc < 3) {
fprintf(stderr, "./ExtractSegment <Events> <TID> [Radius]\n");
fprintf(stderr, "Only %d arguments given\n", argc);
for (int i = 0; i < argc; i++) {
printf("%s\n", argv[i]);
}
exit(1);
}
#define BATCH_SIZE 100
Event eventBuffer[BATCH_SIZE];
std::vector<Event> events;
FILE* input = fopen(argv[1], "r");
size_t numItems;
while ((numItems = fread(eventBuffer, sizeof(Event), BATCH_SIZE, input))) {
for (size_t i = 0; i < numItems; i++) events.push_back(eventBuffer[i]);
if (numItems < BATCH_SIZE) break;
}
fclose(input);
// Find the start and end time of TID, and output all activity in between
// by core.
uint32_t targetTid = atoi(argv[2]);
uint64_t targetStartTime = 0;
uint64_t targetEndTime = 0;
uint64_t base = ULLONG_MAX;
// Collect all the events in a more friendly format.
std::unordered_map<uint32_t, Record> recordMap;
for (size_t i = 0; i < events.size(); i++) {
uint32_t appThreadId = events[i].appThreadId;
if (events[i].time < base)
base = events[i].time;
if (appThreadId == targetTid) {
if (events[i].type == CREATION)
targetStartTime = events[i].time;
else if (events[i].type == END)
targetEndTime = events[i].time;
}
if (recordMap.find(appThreadId) == recordMap.end()) {
recordMap[appThreadId] = Record();
}
recordMap[appThreadId].coreId = events[i].coreId;
switch (events[i].type) {
case CREATION:
recordMap[appThreadId].creationTime = events[i].time;
break;
case START:
recordMap[appThreadId].startTime = events[i].time;
break;
case END:
recordMap[appThreadId].endTime = events[i].time;
}
}
if (argc == 4) {
uint64_t cycleRadius = atoll(argv[3]);
targetStartTime -= cycleRadius;
targetEndTime += cycleRadius;
}
// Normalize this trace.
std::unordered_set<uint32_t> relevantEvents;
for (size_t i = 0; i < events.size(); i++) {
if (events[i].time >= targetStartTime && events[i].time <= targetEndTime)
relevantEvents.insert(events[i].appThreadId);
}
puts("ThreadId,CoreId,CreationTime,StartTime,EndTime,CreationToStart,StartToEnd,CreationToEnd");
for (const auto& e: relevantEvents) {
Record& rec = recordMap[e];
// CoreId,CreationTime,StartTime,EndTime,CreationToStart,StartToEnd,CreationToEnd
printf("%u,%d,%lu,%lu,%lu,%lu,%lu,%lu\n", e, rec.coreId, rec.creationTime - base,
rec.startTime - base, rec.endTime - base, rec.startTime -
rec.creationTime, rec.endTime - rec.startTime, rec.endTime - rec.creationTime);
}
}