diff --git a/apps/raw_ofed.cpp b/apps/raw_ofed.cpp index 4e88404..b893b20 100644 --- a/apps/raw_ofed.cpp +++ b/apps/raw_ofed.cpp @@ -28,7 +28,7 @@ class RawProcessor : public Processor RawProcessor() : m_ethto(nullptr) , m_ethfrom(nullptr) - , m_last(system::Clock::read()) + , m_last(system::Clock::now()) , m_lat(0) , m_count(0) {} @@ -43,7 +43,7 @@ class RawProcessor : public Processor * Get the timing data. */ if (m_last > 0) { - m_lat += system::Clock::read() - m_last; + m_lat += system::Clock::instant() - m_last; } /* * Process the response. @@ -62,7 +62,7 @@ class RawProcessor : public Processor { m_ethto->setType(len); memcpy(m_buffer, data, len); - m_last = system::Clock::read(); + m_last = system::Clock::now(); Status ret = m_ethto->commit(len, m_buffer); if (ret != Status::Ok) { return ret; @@ -87,11 +87,11 @@ class RawProcessor : public Processor return *this; } - system::Clock::Value averageLatency() + size_t averageLatency() { uint64_t res = 0; if (m_count > 0) { - res = m_lat / m_count; + res = system::Clock::toNanos(m_lat) / m_count; } m_lat = 0; m_count = 0; @@ -101,8 +101,8 @@ class RawProcessor : public Processor private: ethernet::Producer* m_ethto; ethernet::Processor* m_ethfrom; - system::Clock::Value m_last; - system::Clock::Value m_lat; + system::Clock::Epoch m_last; + system::Clock::Epoch m_lat; size_t m_count; uint8_t* m_buffer; }; diff --git a/docs/topics/User-interface.md b/docs/topics/User-interface.md index 7cff83b..0d129f3 100644 --- a/docs/topics/User-interface.md +++ b/docs/topics/User-interface.md @@ -102,7 +102,7 @@ class Client * * @return the average latency of the connection. */ - virtual system::Clock::Value averageLatency(const ID id) = 0; + virtual size_t averageLatency(const ID id) = 0; } ``` Clients can have multiple connections. The exact amount of connections can be diff --git a/include/tulips/api/Client.h b/include/tulips/api/Client.h index 3c715be..b777899 100644 --- a/include/tulips/api/Client.h +++ b/include/tulips/api/Client.h @@ -102,7 +102,7 @@ class Client final Status send(const ID id, const uint32_t len, const uint8_t* const data, uint32_t& off) override; - system::Clock::Value averageLatency(const ID id) override; + size_t averageLatency(const ID id) override; /* * Client-specific interface. diff --git a/include/tulips/api/Connection.h b/include/tulips/api/Connection.h index a2bee48..e52accc 100644 --- a/include/tulips/api/Connection.h +++ b/include/tulips/api/Connection.h @@ -102,9 +102,9 @@ class Connection */ #ifdef TULIPS_ENABLE_LATENCY_MONITOR - void markOnSent(const system::Clock::Value ts) { m_history.push_back(ts); } + void markOnSent(const system::Clock::Epoch ts) { m_history.push_back(ts); } - void markOnAcked(const system::Clock::Value ts) + void markOnAcked(const system::Clock::Epoch ts) { m_count += 1; m_lat += ts - m_history.front(); @@ -125,7 +125,7 @@ class Connection private: #ifdef TULIPS_ENABLE_LATENCY_MONITOR - using History = std::list; + using History = std::list; #endif State m_state; @@ -134,7 +134,7 @@ class Connection std::optional m_host; #ifdef TULIPS_ENABLE_LATENCY_MONITOR size_t m_count; - system::Clock::Value m_lat; + size_t m_lat; History m_history; #endif }; diff --git a/include/tulips/api/Interface.h b/include/tulips/api/Interface.h index 8360847..d59be78 100644 --- a/include/tulips/api/Interface.h +++ b/include/tulips/api/Interface.h @@ -20,7 +20,7 @@ struct Delegate /** * Timestamp type alias. */ - using Timestamp = system::Clock::Value; + using Timestamp = system::Clock::Epoch; /* * Virtual default destructor. @@ -249,7 +249,7 @@ class Client : public transport::Processor * * @return the average latency of the connection. */ - virtual system::Clock::Value averageLatency(const ID id) = 0; + virtual size_t averageLatency(const ID id) = 0; }; /** diff --git a/include/tulips/ssl/Client.h b/include/tulips/ssl/Client.h index 09859f3..29f2190 100644 --- a/include/tulips/ssl/Client.h +++ b/include/tulips/ssl/Client.h @@ -113,7 +113,7 @@ class Client final Status send(const ID id, const uint32_t len, const uint8_t* const data, uint32_t& off) override; - system::Clock::Value averageLatency(const ID id) override; + size_t averageLatency(const ID id) override; /* * Client delegate. diff --git a/include/tulips/ssl/Connection.h b/include/tulips/ssl/Connection.h index 15853c3..9abec61 100644 --- a/include/tulips/ssl/Connection.h +++ b/include/tulips/ssl/Connection.h @@ -49,13 +49,13 @@ class Connection * Open the connection. */ void open(SSL_CTX* const ctx, const ID id, void* const cookie, - const system::Clock::Value ts, const int keyfd); + const system::Clock::Epoch ts, const int keyfd); /** * Open the connection. */ void accept(SSL_CTX* const ctx, const ID id, void* const cookie, - const system::Clock::Value ts, const int keyfd); + const system::Clock::Epoch ts, const int keyfd); /** * Close the connection. @@ -77,7 +77,7 @@ class Connection * Process pending data on ACK. */ Action onAcked(system::Logger& log, ID const& id, Delegate& delegate, - const system::Clock::Value ts, const uint32_t savl, + const system::Clock::Epoch ts, const uint32_t savl, uint8_t* const sdat, uint32_t& slen); /** @@ -85,7 +85,7 @@ class Connection */ Action onNewData(system::Logger& log, ID const& id, Delegate& delegate, const uint8_t* const rdat, const uint32_t rlen, - const bool pushed, const system::Clock::Value ts, + const bool pushed, const system::Clock::Epoch ts, const uint32_t savl, uint8_t* const sdat, uint32_t& slen); /** @@ -116,7 +116,7 @@ class Connection /** * Return the connection's timestamp. */ - constexpr system::Clock::Value timestamp() const { return m_ts; } + constexpr system::Clock::Epoch timestamp() const { return m_ts; } /** * Return the key file's descriptor. @@ -178,11 +178,11 @@ class Connection * Initialize the connection's state. */ void initialize(SSL_CTX* const ctx, const ID id, void* const cookie, - const system::Clock::Value ts, const int keyfd); + const system::Clock::Epoch ts, const int keyfd); ID m_id; void* m_cookie; - system::Clock::Value m_ts; + system::Clock::Epoch m_ts; int m_keyfd; BIO* m_bin; BIO* m_bout; diff --git a/include/tulips/stack/tcpv4/EventHandler.h b/include/tulips/stack/tcpv4/EventHandler.h index 8a29d59..5b61c97 100644 --- a/include/tulips/stack/tcpv4/EventHandler.h +++ b/include/tulips/stack/tcpv4/EventHandler.h @@ -13,7 +13,7 @@ class EventHandler /** * Timestamp type alias. */ - using Timestamp = system::Clock::Value; + using Timestamp = system::Clock::Epoch; /** * Default destructor. diff --git a/include/tulips/system/Clock.h b/include/tulips/system/Clock.h index 86c397e..bb7f10a 100644 --- a/include/tulips/system/Clock.h +++ b/include/tulips/system/Clock.h @@ -8,10 +8,13 @@ namespace tulips::system { class Clock { public: - using Value = uint64_t; + using Epoch = uint64_t; + using Instant = uint64_t; - static constexpr const Value SECOND = 1000000000ULL; - static constexpr const Value MILLISECOND = 1000000ULL; + static const size_t TICKS_PER_SECOND; + + static constexpr const size_t SECOND = 1000000000ULL; + static constexpr const size_t MILLISECOND = 1000000ULL; inline static Clock& get() { @@ -20,26 +23,44 @@ class Clock } #ifdef TULIPS_CLOCK_HAS_OFFSET - inline static Value read() { return clock() + get().offset(); } - - inline void offsetBy(const Value offset) { m_offset += offset; } + inline static Epoch instant() { return cycles() + toTicks(get().offset()); } + inline static Epoch now() { return clock() + get().offset(); } - inline Value offset() const { return m_offset; } + inline void offsetBy(const size_t offset) { m_offset += offset; } + inline Epoch offset() const { return m_offset; } #else - inline static Value read() { return clock(); } + inline static Instant instant() { return cycles(); } + inline static Epoch now() { return clock(); } #endif + inline static size_t toNanos(const size_t v) + { + return (v * SECOND) / TICKS_PER_SECOND; + } + + inline static size_t toTicks(const size_t v) + { + return (v * TICKS_PER_SECOND) / SECOND; + } + private: - inline static Value clock() + inline static uint64_t clock() { struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); return ts.tv_sec * 1000000000ULL + ts.tv_nsec; } +#if defined(__x86_64__) + inline static Instant cycles() { return __rdtsc(); } +#elif defined(__aarch64__) + inline static Instant cycles() { return clock(); } +#else +#error "Processor architecture not supported" +#endif + #ifdef TULIPS_CLOCK_HAS_OFFSET - Value m_offset = 0; + Epoch m_offset = 0; #endif }; - } diff --git a/include/tulips/system/Timer.h b/include/tulips/system/Timer.h index 540958f..02d47ef 100644 --- a/include/tulips/system/Timer.h +++ b/include/tulips/system/Timer.h @@ -1,33 +1,34 @@ #pragma once #include "Clock.h" +#include namespace tulips::system { class Timer { public: - inline void set(const Clock::Value interval) + inline void set(const size_t interval_ns) { - m_interval = interval; - m_start = Clock::read(); + m_interval = Clock::toTicks(interval_ns); + m_start = Clock::instant(); } - inline void reset(const Clock::Value ts) { m_start = ts; } + inline void reset() { m_start = Clock::instant(); } - inline bool expired(const Clock::Value ts) const + inline bool expired() const { - return ts - m_start >= m_interval; + return Clock::instant() - m_start >= m_interval; } - inline size_t ticks(const Clock::Value ts) const + inline size_t ticks() const { - return (ts - m_start) / m_interval; + return (Clock::instant() - m_start) / m_interval; } private: - Clock::Value m_start = 0; - Clock::Value m_interval = 0; + Clock::Epoch m_start = 0; + size_t m_interval = 0; }; } diff --git a/include/tulips/transport/Processor.h b/include/tulips/transport/Processor.h index 12f3573..e0c03f2 100644 --- a/include/tulips/transport/Processor.h +++ b/include/tulips/transport/Processor.h @@ -9,7 +9,7 @@ namespace tulips::transport { class Processor { public: - using Timestamp = system::Clock::Value; + using Timestamp = system::Clock::Epoch; /** * Virtual destructor. diff --git a/src/api/Client.cpp b/src/api/Client.cpp index f7781b0..a521676 100644 --- a/src/api/Client.cpp +++ b/src/api/Client.cpp @@ -364,7 +364,7 @@ Client::send(const ID id, const uint32_t len, const uint8_t* const data, return m_tcp.send(id, len, data, off); } -system::Clock::Value +size_t Client::averageLatency(UNUSED const ID id) { #ifdef TULIPS_ENABLE_LATENCY_MONITOR diff --git a/src/apps/CMakeLists.txt b/src/apps/CMakeLists.txt index 4fbb361..314c429 100644 --- a/src/apps/CMakeLists.txt +++ b/src/apps/CMakeLists.txt @@ -4,7 +4,7 @@ include_directories(${TCLAP_INCLUDE_DIRS}) set(CMAKE_POSITION_INDEPENDENT_CODE 1) # We need to disable format checking here because various versions of GCC/CLANG -# are not interpreting the Clock::Value type the same way. +# are not interpreting the Clock::Epoch type the same way. # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-format") diff --git a/src/apps/TCPLatency.cpp b/src/apps/TCPLatency.cpp index 110fef9..d62c7b5 100644 --- a/src/apps/TCPLatency.cpp +++ b/src/apps/TCPLatency.cpp @@ -244,11 +244,10 @@ run(Options const& options, transport::Device::Ref dev) * Process the delay. */ if (options.usDelay() != 0) { - auto ts = system::Clock::read(); - if (!timer.expired(ts)) { + if (!timer.expired()) { break; } - timer.reset(ts); + timer.reset(); } /* * Check if we need to stop. @@ -436,11 +435,10 @@ run(Options const& options, transport::Device::Ref dev) * Process the artificial delay. */ if (options.usDelay() != 0) { - auto ts = system::Clock::read(); - if (!timer.expired(ts)) { + if (!timer.expired()) { continue; } - timer.reset(ts); + timer.reset(); } /* * Process the stack diff --git a/src/ssl/Client.cpp b/src/ssl/Client.cpp index 46b0e3f..c5d7d61 100644 --- a/src/ssl/Client.cpp +++ b/src/ssl/Client.cpp @@ -362,7 +362,7 @@ Client::send(const ID id, const uint32_t len, const uint8_t* const data, return flush(id); } -system::Clock::Value +size_t Client::averageLatency(const ID id) { return m_client.averageLatency(id); diff --git a/src/ssl/Connection.cpp b/src/ssl/Connection.cpp index 417d62d..4c58e6c 100644 --- a/src/ssl/Connection.cpp +++ b/src/ssl/Connection.cpp @@ -77,7 +77,7 @@ errorToString(const int err) void Connection::open(SSL_CTX* ctx, const ID id, void* const cookie, - const system::Clock::Value ts, const int keyfd) + const system::Clock::Epoch ts, const int keyfd) { initialize(ctx, id, cookie, ts, keyfd); m_state = State::Open; @@ -85,7 +85,7 @@ Connection::open(SSL_CTX* ctx, const ID id, void* const cookie, void Connection::accept(SSL_CTX* ctx, const ID id, void* const cookie, - const system::Clock::Value ts, const int keyfd) + const system::Clock::Epoch ts, const int keyfd) { initialize(ctx, id, cookie, ts, keyfd); m_state = State::Accepting; @@ -231,7 +231,7 @@ Connection::shutdown(system::Logger& log, ID const& id) Action Connection::onAcked(system::Logger& log, ID const& id, Delegate& delegate, - const system::Clock::Value ts, const uint32_t alen, + const system::Clock::Epoch ts, const uint32_t alen, uint8_t* const sdata, uint32_t& slen) { /* @@ -290,7 +290,7 @@ Action Connection::onNewData(system::Logger& log, ID const& id, api::interface::Delegate& delegate, const uint8_t* const rdat, const uint32_t rlen, - const bool pushed, const system::Clock::Value ts, + const bool pushed, const system::Clock::Epoch ts, const uint32_t savl, uint8_t* const sdat, uint32_t& slen) { /* @@ -639,7 +639,7 @@ Connection::flush(system::Logger& log, const uint32_t savl, uint8_t* const sdat, void Connection::initialize(SSL_CTX* ctx, const ID id, void* const cookie, - const system::Clock::Value ts, const int keyfd) + const system::Clock::Epoch ts, const int keyfd) { /* * Update the state. diff --git a/src/stack/arp/Processor.cpp b/src/stack/arp/Processor.cpp index d3b3283..aef97c2 100644 --- a/src/stack/arp/Processor.cpp +++ b/src/stack/arp/Processor.cpp @@ -28,13 +28,12 @@ Processor::Processor(system::Logger& log, ethernet::Producer& eth, Status Processor::run() { - auto ts = system::Clock::read(); /* * Poll the timer */ - if (m_timer.expired(ts)) { - m_timer.reset(ts); - ++m_time; + if (m_timer.expired()) { + m_time += m_timer.ticks(); + m_timer.reset(); for (auto& e : m_table) { if (e.ipaddr.empty()) { continue; @@ -45,6 +44,9 @@ Processor::run() } } } + /* + * Done. + */ return Status::Ok; } diff --git a/src/stack/tcpv4/Client.cpp b/src/stack/tcpv4/Client.cpp index 8b7690e..c9b3191 100644 --- a/src/stack/tcpv4/Client.cpp +++ b/src/stack/tcpv4/Client.cpp @@ -26,7 +26,7 @@ Processor::findLocalPort() const /* * Compute a local port value. */ - auto lport = (system::Clock::read() & 0x3FFF) + 10000; + auto lport = (system::Clock::instant() & 0x3FFF) + 10000; /* * Find a match. */ @@ -116,7 +116,7 @@ Processor::abort(const Connection::ID id) /* * Notify the handler. */ - m_handler.onAborted(c, system::Clock::read()); + m_handler.onAborted(c, system::Clock::now()); /* * Done. */ diff --git a/src/stack/tcpv4/Processor.cpp b/src/stack/tcpv4/Processor.cpp index 74a4539..6b4311d 100644 --- a/src/stack/tcpv4/Processor.cpp +++ b/src/stack/tcpv4/Processor.cpp @@ -72,16 +72,15 @@ Processor::unlisten(const Port port) Status Processor::run() { - auto ts = system::Clock::read(); /* * Check the fast timer. */ - if (m_fast.expired(ts)) { + if (m_fast.expired()) { /* * Get the ticks and reset the timer. */ - auto ticks = m_fast.ticks(ts); - m_fast.reset(ts); + auto ticks = m_fast.ticks(); + m_fast.reset(); /* * Call the handler. */ @@ -93,12 +92,12 @@ Processor::run() /* * Check the slow timer. */ - if (m_slow.expired(ts)) { + if (m_slow.expired()) { /* * Get the ticks and reset the timer. */ - auto ticks = m_slow.ticks(ts); - m_slow.reset(ts); + auto ticks = m_slow.ticks(); + m_slow.reset(); /* * Call the handler. */ diff --git a/src/stack/tcpv4/Send.cpp b/src/stack/tcpv4/Send.cpp index c1aced6..048672f 100644 --- a/src/stack/tcpv4/Send.cpp +++ b/src/stack/tcpv4/Send.cpp @@ -319,7 +319,7 @@ Processor::abort(Connection& e) /* * Notify the handler and close the connection. */ - m_handler.onAborted(e, system::Clock::read()); + m_handler.onAborted(e, system::Clock::now()); close(e); /* *Done. @@ -337,7 +337,7 @@ Processor::timeOut(Connection& e) /* * Notify the handler and close the connection. */ - m_handler.onTimedOut(e, system::Clock::read()); + m_handler.onTimedOut(e, system::Clock::now()); close(e); /* *Done. @@ -391,7 +391,7 @@ Processor::send(Connection& e, const uint32_t len, Segment& s) if (likely(!rexmit)) { #ifdef TULIPS_ENABLE_LATENCY_MONITOR if (OUTTCP->flags & Flag::PSH) { - m_handler.onSent(e, system::Clock::read()); + m_handler.onSent(e, system::Clock::now()); } #endif e.m_snd_nxt += s.m_len; diff --git a/src/system/Clock.cpp b/src/system/Clock.cpp new file mode 100644 index 0000000..e41f216 --- /dev/null +++ b/src/system/Clock.cpp @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include + +namespace { + +constexpr size_t N_SAMPLES = 100; +constexpr size_t PERIOD_MS = 1; + +long double +tickPeriod() +{ + std::array periods; + /* + * Run the calibration loop. + */ + for (size_t i = 0; i < N_SAMPLES; i += 1) { + /* + * Use C++ "steady_clock" since cppreference.com recommends against using + * hrtime. Busy wait for 5ms based on the std::chrono clock and time that + * with our high reolution low overhead clock. Assuming the steady clock + * has a resonable resolution, 5ms should be long enough to wait. At a 1GHz + * clock, that is still 5MT, and even at a 1MHz clock it's 5kT. + */ + auto start = std::chrono::steady_clock::now(); + asm volatile("" : : : "memory"); + uint64_t startTick = __rdtsc(); + auto end = start + std::chrono::milliseconds(PERIOD_MS); + /* + * Busy wait. + */ + decltype(start) now; + uint64_t endTick = 0; + do { + now = std::chrono::steady_clock::now(); + endTick = __rdtsc(); + } while (now < end); + asm volatile("" : : : "memory"); + /* + * Compute the deltas (second-per-tick). + */ + auto elapsed = static_cast(endTick - startTick) * 1e9L; + auto delay = static_cast((now - start).count()); + periods[i] = delay / elapsed; + } + /* + * Select the median. + */ + std::sort(periods.begin(), periods.end()); + return std::llround(1.0L / periods[N_SAMPLES / 2]); +} + +} + +namespace tulips::system { + +#if defined(__x86_64__) +const size_t Clock::TICKS_PER_SECOND = tickPeriod(); +#elif defined(__aarch64__) +const size_t Clock::TICKS_PER_SECOND = Clock::SECOND; +#else +#error "Processor architecture not supported" +#endif + +} diff --git a/src/transport/ena/Device.cpp b/src/transport/ena/Device.cpp index 34dc467..7e6bbd2 100644 --- a/src/transport/ena/Device.cpp +++ b/src/transport/ena/Device.cpp @@ -142,18 +142,22 @@ Device::unlisten(UNUSED const stack::ipv4::Protocol proto, Status Device::poll(Processor& proc) { - auto now = system::Clock::read(); + using system::Clock; + /* + * Print statistics every 10 seconds. + */ + static const size_t PERIOD = 10 * Clock::toTicks(system::Clock::SECOND); /* * Print the stats every seconds on queue 0. */ - if (m_queueid == 0 && now - m_laststats >= 10 * system::Clock::SECOND) { + if (m_queueid == 0 && Clock::instant() - m_laststats >= PERIOD) { struct rte_eth_stats stats; rte_eth_stats_get(m_portid, &stats); m_log.debug("ENA", "TX: pkts=", stats.opackets, " byts=", stats.obytes, " errs=", stats.oerrors); m_log.debug("ENA", "RX: pkts=", stats.ipackets, " byts=", stats.ibytes, " errs=", stats.ierrors, " miss=", stats.imissed); - m_laststats = now; + m_laststats = Clock::instant(); } /* * Clear buffers sent out-of-band. @@ -167,7 +171,7 @@ Device::poll(Processor& proc) */ if (!m_buffer->empty()) { uint16_t len = 0; - system::Clock::Value ts = 0; + system::Clock::Epoch ts = 0; /* * Read a packet. */ @@ -249,7 +253,7 @@ Device::poll(Processor& proc) * Process the packet. */ m_log.trace("ENA", "processing addr=", (void*)dat, " len=", len); - ret = proc.process(len, dat, system::Clock::read()); + ret = proc.process(len, dat, system::Clock::now()); /* * Check the processor's status. */ diff --git a/src/transport/list/Device.cpp b/src/transport/list/Device.cpp index 491a076..3056bb9 100644 --- a/src/transport/list/Device.cpp +++ b/src/transport/list/Device.cpp @@ -57,7 +57,7 @@ Device::poll(Processor& proc) Packet* packet = m_read.front(); m_log.trace("LIST", "processing packet: ", size_t(packet->len), "B, ", packet); - Status ret = proc.process(packet->len, packet->data, system::Clock::read()); + Status ret = proc.process(packet->len, packet->data, system::Clock::now()); m_read.pop_front(); Packet::release(packet); return ret; diff --git a/src/transport/npipe/Device.cpp b/src/transport/npipe/Device.cpp index 6e53de1..1d15e90 100644 --- a/src/transport/npipe/Device.cpp +++ b/src/transport/npipe/Device.cpp @@ -126,7 +126,7 @@ Device::poll(Processor& proc) * Process the data. */ m_log.debug("NPIPE", "process ", len, "B"); - return proc.process(len, m_read_buffer, system::Clock::read()); + return proc.process(len, m_read_buffer, system::Clock::now()); } Status diff --git a/src/transport/ofed/Device.cpp b/src/transport/ofed/Device.cpp index 84ecc83..cb1997e 100644 --- a/src/transport/ofed/Device.cpp +++ b/src/transport/ofed/Device.cpp @@ -546,7 +546,7 @@ Device::poll(Processor& proc) /* * Process the packet. */ - auto res = proc.process(len, addr, system::Clock::read()); + auto res = proc.process(len, addr, system::Clock::now()); /* * Check the processor's status. */ diff --git a/src/transport/pcap/Device.cpp b/src/transport/pcap/Device.cpp index d913286..180beaf 100644 --- a/src/transport/pcap/Device.cpp +++ b/src/transport/pcap/Device.cpp @@ -7,16 +7,16 @@ namespace tulips::transport::pcap { static void writePacket(pcap_dumper_t* const dumper, const void* const data, - const size_t len, const system::Clock::Value ts) + const size_t len, const system::Clock::Epoch ts) { struct pcap_pkthdr hdr; - system::Clock::Value secs = ts / system::Clock::SECOND; + system::Clock::Epoch secs = ts / system::Clock::SECOND; #ifdef __OpenBSD__ - system::Clock::Value nscs = ts - secs * system::Clock::SECOND; + size_t nscs = ts - secs * system::Clock::SECOND; hdr.ts.tv_sec = secs; hdr.ts.tv_usec = nscs / 1000ULL; #else - system::Clock::Value nscs = ts - secs * system::Clock::SECOND; + size_t nscs = ts - secs * system::Clock::SECOND; hdr.ts.tv_sec = (time_t)secs; hdr.ts.tv_usec = (time_t)nscs; #endif @@ -82,7 +82,7 @@ Device::commit(const uint16_t len, uint8_t* const buf, const uint16_t mss) { Status ret = m_device->commit(len, buf, mss); if (ret == Status::Ok) { - writePacket(m_pcap_dumper, buf, len, system::Clock::read()); + writePacket(m_pcap_dumper, buf, len, system::Clock::now()); } return ret; }