~siborgium/prelockdpp

0b03575b672a2a637be278d06cb219133aa6afe7 — Sergey Smirnykh 2 years ago 1555ef8
DRY code a bit
1 files changed, 57 insertions(+), 21 deletions(-)

M main.cpp
M main.cpp => main.cpp +57 -21
@@ 70,6 70,18 @@ struct process_lookup_error: public std::runtime_error {
    using std::runtime_error::runtime_error;
};

constexpr auto tspec_diff(const timespec& t0, const timespec& t1) {
    timespec t {
        .tv_sec = t1.tv_sec - t0.tv_sec,
        .tv_nsec = t1.tv_nsec - t0.tv_nsec
    };
    if (t.tv_nsec < 0) {
        --t.tv_sec;
        t.tv_nsec += 1000000000;
    }
    return t;
}

struct config {
#if 0 // unused for now
    fs::path dump_path{ "/var/lib/prelockdpp/dump.json" };


@@ 181,6 193,27 @@ struct context {
        }
        return t;
    }
    auto tspec_from_ticks(auto ticks) {
        timespec tspec;
        tspec.tv_sec = ticks / info.sc_clk_tck;
        tspec.tv_nsec = ticks % info.sc_clk_tck;
        return tspec;
    }
    auto parse_timespec(auto begin, auto end) {
        auto from_chars = [&](auto begin, auto end, auto& out) {
            if (auto [_, ec] = std::from_chars(begin, end, out); ec != std::errc()) {
                throw std::runtime_error{ "Failed to read timespec value" };
            }
        };
        auto end1 = std::find(begin, end, '.');
        if (end1 == end) {
            throw std::logic_error{ "Unexpected timespec fmt" };
        }
        timespec t;
        from_chars(begin, end1, t.tv_sec);
        from_chars(end1 + 1, end, t.tv_nsec);
        return t;
    }
    auto get_uptime() {
        int fd = open("/proc/uptime", O_RDONLY);
        if (fd == -1) {


@@ 205,34 238,20 @@ struct context {
            total += r;
        }

        auto from_chars = [&](auto begin, auto end, auto& out) {
            if (auto [_, ec] = std::from_chars(begin, end, out); ec != std::errc()) {
                throw std::runtime_error{ "Failed to read /proc/uptime value" };
            }
        };

        if (total > 0) {
            auto begin = buffer;
            auto end = begin + total;

            auto end1 = std::find(begin, end, '.');
            if (end1 == end) {
                throw std::logic_error{ "Unexpected /proc/uptime fmt" };
            }

            timespec uptime;
            from_chars(begin, end1, uptime.tv_sec);
            from_chars(end1 + 1, begin, uptime.tv_nsec);
            return uptime;
            return parse_timespec(buffer, buffer + total);
        }
        throw std::logic_error{ "read(/proc/uptime) was empty" };
    }
    // replace FILE part of path_buf with `file`
    constexpr auto fmt_proc_pid_file(std::string_view file) {
        auto end = std::copy(file.begin(), file.end(), pid_end);
        assert(end < std::end(path_buf));
        *end = '\0';
        return end;
    }
    // return whether cgroup matches on any of specified regexes
    auto match_cgroup(std::string_view cgroup) {
        std::cout << "match_cgroup(" << cgroup << "): unimplemented\n";
        return true;


@@ 331,17 350,34 @@ struct context {

            std::cout << pid << '\n';
            with_uniq_id(path_buf, [&](auto start_time, auto prefix){
                std::cout << "start_time: " << start_time << '\n';
                std::cout << "prefix:     " << prefix << '\n';
                auto start_time_ = [=,this] {
                    unsigned long long ticks;
                    auto [p, ec] = std::from_chars(
                        start_time.begin(),
                        start_time.end(),
                        ticks
                    );
                    if (ec != std::errc()) {
                        throw std::logic_error{ "Failed to parse start_time value" };
                    }
                    return tspec_from_ticks(ticks);
                }();

                std::cout << "prefix:            " << prefix << '\n';
                std::cout << "start_time:        " << start_time << '\n';
                std::cout << "start_time (tspc): " << start_time_.tv_sec << '.' << start_time_.tv_nsec << '\n';
            });
        }
        if (errno) {
            throw errno_exception("readdir(proc) failed", errno);
        }

        auto m = tspec_diff(m0, get_clock_time(CLOCK_MONOTONIC));
        auto p = tspec_diff(p0, get_clock_time(CLOCK_PROCESS_CPUTIME_ID));

        std::cout << "Uptime:         " << uptime.tv_sec << '.' << uptime.tv_nsec << '\n';
        std::cout << "Monotonic time: " << m0.tv_sec << '.' << m0.tv_nsec << '\n';
        std::cout << "Proc CPU  time: " << p0.tv_sec << '.' << p0.tv_nsec << '\n';
        std::cout << "Monotonic time: " << m.tv_sec << '.' << m.tv_nsec << '\n';
        std::cout << "Proc CPU  time: " << p.tv_sec << '.' << p.tv_nsec << '\n';
    }

    context(config& cfg):