diff options
author | Francisco Jerez <currojerez@riseup.net> | 2017-04-07 17:18:00 -0700 |
---|---|---|
committer | Francisco Jerez <currojerez@riseup.net> | 2017-04-07 18:51:41 -0700 |
commit | 0e220c1a765372f7e56b330710585494c0600874 (patch) | |
tree | 3a528c73d3e533546ba32606b8275377589f29a7 | |
parent | 50320f5f5750de45842aaafd553fcf881e9a951b (diff) |
retrace: Split retracing and parsing into separate threads for improved CPU utilization.
-rw-r--r-- | retrace/retrace.cpp | 15 | ||||
-rw-r--r-- | retrace/retrace.hpp | 24 | ||||
-rw-r--r-- | retrace/retrace_main.cpp | 10 |
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; |