File trace.h
File List > include > simtix > trace.h
Go to the documentation of this file
#pragma once
#include <fmt/format.h>
#include <fmt/ostream.h>
#include <fmt/printf.h>
#include <simtix/clocked.h>
#include <simtix/macro.h>
#include <cstdio>
#include <iostream>
#include <string>
#ifndef MAX_FLAG_LENGTH
#define MAX_FLAG_LENGTH 10
#endif
#define FLAG_FMT(length) "{:<" STRINGIFY(length) "}"
inline const char *TRACE_FMT = "[{:d}\t" FLAG_FMT(MAX_FLAG_LENGTH) "] {}";
namespace simtix {
namespace trace {
class OstreamTracer {
public:
// Cannot be copied.
OstreamTracer(const OstreamTracer &) = delete;
OstreamTracer &operator=(const OstreamTracer &) = delete;
void DumpTrace(std::string_view msg) { fmt::print(os_, msg); }
void DumpTraceFlag(const char *flag, const std::string &msg) {
fmt::print(os_, TRACE_FMT, sim::CurTick(), flag, msg);
}
static void Init(std::ostream &os) { OstreamTracer::GetInstanceImpl(&os); }
static OstreamTracer &GetInstance() {
return OstreamTracer::GetInstanceImpl();
}
private:
explicit OstreamTracer(std::ostream &os) : os_(os) {
if (DEFINED_MACRO(NDEBUG) && &os == &std::cout) {
std::ios_base::sync_with_stdio(false);
std::cin.tie(0);
}
}
static OstreamTracer &GetInstanceImpl(std::ostream *os = &std::cout) {
static OstreamTracer instance(*os);
return instance;
}
std::ostream &os_;
};
class KonataTracer {
public:
// Cannot be copied.
KonataTracer(const KonataTracer &) = delete;
KonataTracer &operator=(const KonataTracer &) = delete;
inline void Dump(char cmd, uint64_t a) {
fmt::print(os_, "{}\t{}\n", cmd, a);
}
inline void Dump(char cmd, uint64_t a, uint32_t b, uint32_t c) {
fmt::print(os_, "{}\t{}\t{}\t{}\n", cmd, a, b, c);
}
inline void Dump(char cmd, uint64_t a, uint32_t b, std::string_view c) {
fmt::print(os_, "{}\t{}\t{}\t{}\n", cmd, a, b, c);
}
static void Init(std::ostream &os) { KonataTracer::GetInstanceImpl(&os); }
static KonataTracer &GetInstance() { return KonataTracer::GetInstanceImpl(); }
private:
explicit KonataTracer(std::ostream &os) : os_(os) {
os << "Kanata\t0004\n";
os << "C=\t-1\n";
}
static KonataTracer &GetInstanceImpl(std::ostream *os = &std::cout) {
static KonataTracer instance(*os);
return instance;
}
std::ostream &os_;
};
} // namespace trace
} // namespace simtix
// Section: Tracing APIs
#define TRACE_ENABLED(flag) DEFINED_MACRO(flag##_TRACE_ENABLED)
#define DDUMP(flag, ...) \
do { \
if constexpr (TRACE_ENABLED(flag)) { \
simtix::trace::OstreamTracer::GetInstance().DumpTrace( \
fmt::sprintf(__VA_ARGS__)); \
} \
} while (0)
#define DPRINTF(flag, ...) \
do { \
if constexpr (TRACE_ENABLED(flag)) { \
simtix::trace::OstreamTracer::GetInstance().DumpTraceFlag( \
#flag, fmt::sprintf(__VA_ARGS__)); \
} \
} while (0)
#define DPRINT(flag, ...) \
do { \
if constexpr (TRACE_ENABLED(flag)) { \
simtix::trace::OstreamTracer::GetInstance().DumpTraceFlag( \
#flag, fmt::format(__VA_ARGS__)); \
} \
} while (0)
#define KONATA(cmd, ...) \
do { \
if constexpr (TRACE_ENABLED(Konata)) { \
constexpr char c = #cmd[0]; \
simtix::trace::KonataTracer::GetInstance().Dump(c, __VA_ARGS__); \
} \
} while (0)