X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=retrace.cpp;h=d2e6d379b06d283ca729e1712e80a22044103189;hb=67964385bd2abb065787c52625ed19dbe08f2bf8;hp=ef236f45ef79a7f3043ea897ad31bc70f07dbf2e;hpb=45b28c4be657400452daebe585427ee5a7e232be;p=apitrace diff --git a/retrace.cpp b/retrace.cpp index ef236f4..d2e6d37 100644 --- a/retrace.cpp +++ b/retrace.cpp @@ -24,8 +24,11 @@ **************************************************************************/ +#include #include +#include "os_time.hpp" +#include "trace_dump.hpp" #include "retrace.hpp" @@ -33,11 +36,99 @@ namespace retrace { int verbosity = 0; +bool profiling = false; -void retrace_unknown(Trace::Call &call) { - if (verbosity >= 0) { - std::cerr << call.no << ": warning: unknown call " << call.name() << "\n"; +static bool call_dumped = false; + + +static void dumpCall(trace::Call &call) { + if (verbosity >= 0 && !call_dumped) { + std::cout << call; + std::cout.flush(); + call_dumped = true; + } +} + + +std::ostream &warning(trace::Call &call) { + dumpCall(call); + + std::cerr << call.no << ": "; + std::cerr << "warning: "; + + return std::cerr; +} + + +void ignore(trace::Call &call) { + (void)call; +} + +void unsupported(trace::Call &call) { + warning(call) << "unsupported " << call.name() << " call\n"; +} + +inline void Retracer::addCallback(const Entry *entry) { + assert(entry->name); + assert(entry->callback); + map[entry->name] = entry->callback; +} + + +void Retracer::addCallbacks(const Entry *entries) { + while (entries->name && entries->callback) { + addCallback(entries++); + } +} + + +void Retracer::retrace(trace::Call &call) { + call_dumped = false; + + if (verbosity >= 1) { + if (verbosity >= 2 || + !(call.flags & trace::CALL_FLAG_VERBOSE)) { + dumpCall(call); + } + } + + Callback callback = 0; + + trace::Id id = call.sig->id; + if (id >= callbacks.size()) { + callbacks.resize(id + 1); + callback = 0; + } else { + callback = callbacks[id]; + } + + if (!callback) { + Map::const_iterator it = map.find(call.name()); + if (it == map.end()) { + callback = &unsupported; + } else { + callback = it->second; + } + callbacks[id] = callback; + } + + assert(callback); + assert(callbacks[id] == callback); + + if (retrace::profiling) { + long long startTime = os::getTime(); + callback(call); + long long stopTime = os::getTime(); + float timeInterval = (stopTime - startTime) * (1.0E6 / os::timeFrequency); + + std::cout + << call.no << " " + << "[" << timeInterval << " usec] " + ; + trace::dump(call, std::cout, trace::DUMP_FLAG_NO_CALL_NO | trace::DUMP_FLAG_NO_COLOR); + } else { + callback(call); } }