diff --git a/ServerBench.cpp b/ServerBench.cpp index 9237056..4323b53 100644 --- a/ServerBench.cpp +++ b/ServerBench.cpp @@ -164,6 +164,62 @@ double toSeconds(timeval t) { return double(t.tv_sec) + double(t.tv_usec) * 1e-6; } +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __linux__ +struct InstructionCount { + InstructionCount() { + struct perf_event_attr pe; + + memset(&pe, 0, sizeof(pe)); + pe.type = PERF_TYPE_HARDWARE; + pe.size = sizeof(pe); + pe.config = PERF_COUNT_HW_INSTRUCTIONS; + pe.inherit = 1; + pe.exclude_kernel = 1; + pe.exclude_hv = 1; + + fd = perf_event_open(&pe, 0, -1, -1, 0); + if (fd == -1) { + fprintf(stderr, "Error opening leader %llx\n", pe.config); + exit(EXIT_FAILURE); + } + } + + int64_t total() { + int64_t count; + if (read(fd, &count, sizeof(count)) != sizeof(count)) { + perror("read instructions from perf"); + abort(); + } + return count; + } + + ~InstructionCount() { close(fd); } + +private: + int fd; + static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, + int cpu, int group_fd, unsigned long flags) { + int ret; + + ret = syscall(SYS_perf_event_open, hw_event, pid, cpu, group_fd, flags); + return ret; + } +}; +#else +struct InstructionCount { + int64_t total() { return 0; } +}; +#endif + int main(int argc, char **argv) { if (argc != 3) { goto fail; @@ -176,6 +232,7 @@ int main(int argc, char **argv) { int metricsCount; cs.getMetricsV1(&metrics, &metricsCount); + InstructionCount instructions; auto w = std::thread{workload, &cs}; for (;;) { @@ -203,6 +260,11 @@ int main(int argc, char **argv) { "transactions_total "; body += std::to_string(transactions.load(std::memory_order_relaxed)); body += "\n"; + body += "# HELP instructions_total Total number of instructions\n" + "# TYPE instructions_total counter\n" + "instructions_total "; + body += std::to_string(instructions.total()); + body += "\n"; for (int i = 0; i < metricsCount; ++i) { body += "# HELP ";