summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2017-04-07 17:18:00 -0700
committerFrancisco Jerez <currojerez@riseup.net>2017-04-07 18:51:41 -0700
commit0e220c1a765372f7e56b330710585494c0600874 (patch)
tree3a528c73d3e533546ba32606b8275377589f29a7
parent50320f5f5750de45842aaafd553fcf881e9a951b (diff)
retrace: Split retracing and parsing into separate threads for improved CPU utilization.
-rw-r--r--retrace/retrace.cpp15
-rw-r--r--retrace/retrace.hpp24
-rw-r--r--retrace/retrace_main.cpp10
3 files changed, 34 insertions, 15 deletions
diff --git a/retrace/retrace.cpp b/retrace/retrace.cpp
index d0067c2e..f86ee5b3 100644
--- a/retrace/retrace.cpp
+++ b/retrace/retrace.cpp
@@ -120,12 +120,12 @@ void Retracer::addCallbacks(const Entry *entries) {
}
-void Retracer::retrace(trace::Call &call) {
+void Retracer::retrace(trace::Call *call) {
call_dumped = false;
Callback callback = 0;
- trace::Id id = call.sig->id;
+ trace::Id id = call->sig->id;
if (id >= callbacks.size()) {
callbacks.resize(id + 1);
callback = 0;
@@ -134,7 +134,7 @@ void Retracer::retrace(trace::Call &call) {
}
if (!callback) {
- Map::const_iterator it = map.find(call.name());
+ Map::const_iterator it = map.find(call->name());
if (it == map.end()) {
callback = &unsupported;
} else {
@@ -148,13 +148,16 @@ void Retracer::retrace(trace::Call &call) {
if (verbosity >= 1) {
if (verbosity >= 2 ||
- (!(call.flags & trace::CALL_FLAG_VERBOSE) &&
+ (!(call->flags & trace::CALL_FLAG_VERBOSE) &&
callback != &ignore)) {
- dumpCall(call);
+ dumpCall(*call);
}
}
- callback(call);
+ queue.push(std::make_pair(callback, call));
+
+ while (const auto *call = release_queue.try_pop())
+ pool.free(call);
}
diff --git a/retrace/retrace.hpp b/retrace/retrace.hpp
index d753036c..77d1eade 100644
--- a/retrace/retrace.hpp
+++ b/retrace/retrace.hpp
@@ -44,6 +44,7 @@
#include "trace_dump.hpp"
#include "scoped_allocator.hpp"
+#include "message_queue.hpp"
namespace image {
@@ -211,17 +212,34 @@ class Retracer
std::vector<Callback> callbacks;
+ std::thread worker;
+ message_queue<std::pair<Callback, trace::Call *>, 512> queue;
+ message_queue<trace::Call *, 128 * 1024> release_queue;
+
public:
- Retracer() {
+ Retracer() :
+ worker([&] {
+ while (true) {
+ auto p = queue.pop();
+ if (!p.first || !p.second)
+ break;
+ p.first(*p.second);
+ release_queue.push(std::move(p.second));
+ }
+ })
+ {
addCallbacks(stdc_callbacks);
}
- virtual ~Retracer() {}
+ virtual ~Retracer() {
+ queue.push({});
+ worker.join();
+ }
void addCallback(const Entry *entry);
void addCallbacks(const Entry *entries);
- void retrace(trace::Call &call);
+ void retrace(trace::Call *call);
};
diff --git a/retrace/retrace_main.cpp b/retrace/retrace_main.cpp
index 947bec2d..7207bb3a 100644
--- a/retrace/retrace_main.cpp
+++ b/retrace/retrace_main.cpp
@@ -269,18 +269,18 @@ retraceCall(trace::Call *call) {
}
}
- retracer.retrace(*call);
+ retracer.retrace(call);
if (doSnapshot) {
if (!swapRenderTarget) {
- takeSnapshot(call->no);
+ takeSnapshot(callNo);
}
- if (call->no >= snapshotFrequency.getLast()) {
+ if (callNo >= snapshotFrequency.getLast()) {
exit(0);
}
}
- if (call->no >= dumpStateCallNo &&
+ if (callNo >= dumpStateCallNo &&
dumper->canDump()) {
StateWriter *writer = stateWriterFactory(std::cout);
dumper->dumpState(*writer);
@@ -423,7 +423,6 @@ public:
assert(call->thread_id == leg);
retraceCall(call);
- pool.free(call);
call = parser->parse_call();
} while (call && call->thread_id == leg);
@@ -597,7 +596,6 @@ mainLoop() {
trace::Call *call;
while ((call = parser->parse_call())) {
retraceCall(call);
- pool.free(call);
}
} else {
RelayRace race;