File: TraceEventWriter.cpp

package info (click to toggle)
freespace2 24.0.2%2Brepack-1
  • links: PTS, VCS
  • area: non-free
  • in suites: trixie
  • size: 43,188 kB
  • sloc: cpp: 583,107; ansic: 21,729; python: 1,174; sh: 464; makefile: 248; xml: 181
file content (125 lines) | stat: -rw-r--r-- 2,599 bytes parent folder | download | duplicates (4)
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

#include "tracing/TraceEventWriter.h"

#include <iomanip>

namespace
{
using namespace tracing;

const char* getTypeStr(tracing::EventType type) {
	switch(type) {
		case tracing::EventType::Complete:
			return "X";
		case tracing::EventType::Begin:
			return "B";
		case tracing::EventType::End:
			return "E";
		case EventType::AsyncBegin:
			return "b";
		case EventType::AsyncStep:
			return "n";
		case EventType::AsyncEnd:
			return "e";
		case EventType::Counter:
			return "C";
		default: 
			UNREACHABLE("Invalid enum value!");
			return "";
	}
}

void writeTime(std::ofstream& out, std::uint64_t time) {
	// Save stream state
	auto flags = out.flags();
	out << std::fixed << std::setprecision(3);

	out << (time / 1000.);

	// and now restore it
	out.flags(flags);
}

void writeCompleteEvent(std::ofstream& out_str, const trace_event* evt) {
	Assertion(evt->type == EventType::Complete, "Event must be a complete event!");

	out_str << ",\"dur\":";
	writeTime(out_str, evt->duration);
}
}

namespace tracing
{

TraceEventWriter::TraceEventWriter() : _out("tracing/trace.json") {
	_out << "[";
}

TraceEventWriter::~TraceEventWriter() {
	_out << "]\n";
	_out.close();
}

void TraceEventWriter::processEvent(const trace_event* event) {
	if (event->type == EventType::Complete) {
		if (event->duration < 1000) {
			// Discard events that are less than a millisecond long
			return;
		}
	}

	if (!_first_line) {
		_out << ",";
	}
	_out << "\n{\"tid\": " << event->tid << ",\"ts\":";

	writeTime(_out, event->timestamp);

	_out << ",\"pid\":";
	if (event->pid == GPU_PID) {
		_out << "\"GPU\"";
	}
	else {
		_out << event->pid;
	}

	if (event->scope != nullptr) {
		_out << ",\"cat\":\"" << event->scope->getName() << "\"";
		_out << ",\"id\":\"" << reinterpret_cast<const void*>(event->scope) << "\"";
	}

	_out << ",\"name\":\"" << event->category->getName() << "\",\"ph\":\"" << getTypeStr(event->type) << "\"";

	switch (event->type) {
		case EventType::Complete:
			writeCompleteEvent(_out, event);
			break;
		case EventType::Begin:
		case EventType::End:
			// Nothing to do here
			break;
		case EventType::AsyncBegin:
		case EventType::AsyncStep:
		case EventType::AsyncEnd:
			// Nothing to do here...
			break;
		case EventType::Counter: {
			auto flags = _out.flags();
			_out << std::fixed;

			_out << ",\"args\": {\"value\": " << event->value << "}";

			// and now restore it
			_out.flags(flags);
			break;
		}
		default:
			UNREACHABLE("Unhandled enum value! This function should not have been called with this value!");
			break;
	}

	_out << "}";

	_first_line = false;
}
}