aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Stoelp <johannes.stoelp@gmail.com>2023-07-03 22:17:34 +0200
committerJohannes Stoelp <johannes.stoelp@gmail.com>2023-07-03 22:17:34 +0200
commit005cd3b630fcf0f3870f426a0db5e54400a59ef9 (patch)
tree76bc9add7aa46a7ac61c072e5f1fe1b0d1551a01
parent6b062584e56fe395be723220324ea384bf447971 (diff)
downloadcpp-utils-005cd3b630fcf0f3870f426a0db5e54400a59ef9.tar.gz
cpp-utils-005cd3b630fcf0f3870f426a0db5e54400a59ef9.zip
timer: add simple linux watchclock timer
-rw-r--r--Makefile1
-rw-r--r--test/timer.cc28
-rw-r--r--timer.h52
3 files changed, 81 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 97ca475..ceaa80e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,6 @@
TEST += bitfield
TEST += option
+TEST += timer
# -- INTERNALS -----------------------------------------------------------------
diff --git a/test/timer.cc b/test/timer.cc
new file mode 100644
index 0000000..078c4bb
--- /dev/null
+++ b/test/timer.cc
@@ -0,0 +1,28 @@
+#include <timer.h>
+#include <unistd.h>
+#include <cstdio>
+
+int main() {
+ timer::timer T;
+
+ const auto show_time = [&T]() {
+ std::fprintf(stderr, "usec=%f msec=%f sec=%f\n", T.as_usec(), T.as_msec(),
+ T.as_sec());
+ };
+
+ {
+ puts("Sleep 100ms");
+ timer::scoped_timer s{T};
+ usleep(100 * 1000);
+ }
+ show_time();
+
+ {
+ puts("Sleep 500ms");
+ timer::scoped_timer s{T};
+ usleep(500 * 1000);
+ }
+ show_time();
+
+ return 0;
+}
diff --git a/timer.h b/timer.h
new file mode 100644
index 0000000..933c02c
--- /dev/null
+++ b/timer.h
@@ -0,0 +1,52 @@
+#include <cstdint>
+#include <ctime>
+
+namespace timer {
+struct timer {
+ constexpr timer() = default;
+
+ void start() {
+ clock_gettime(kClock, &m_start);
+ }
+
+ void stop() {
+ timespec end;
+ clock_gettime(kClock, &end);
+
+ m_nanos += ((end.tv_sec - m_start.tv_sec) * 1000000000ull) +
+ (end.tv_nsec - m_start.tv_nsec);
+ }
+
+ constexpr double as_sec() const {
+ return as_msec() / 1000.0;
+ }
+
+ constexpr double as_msec() const {
+ return as_usec() / 1000.0;
+ }
+
+ constexpr double as_usec() const {
+ return static_cast<double>(m_nanos) / 1000.0;
+ }
+
+ private:
+ static constexpr clockid_t kClock = CLOCK_MONOTONIC_RAW;
+
+ timespec m_start{};
+ std::uint64_t m_nanos{0};
+};
+
+struct scoped_timer {
+ explicit scoped_timer(timer& t) : m_timer(t) {
+ m_timer.start();
+ }
+
+ ~scoped_timer() {
+ m_timer.stop();
+ }
+
+ private:
+ timer& m_timer;
+};
+
+} // namespace timer