osaf/libs/core/common/include/osaf_time.h               |   51 ++++
 osaf/libs/core/common/tests/Makefile.am                 |    1 +
 osaf/libs/core/common/tests/osaf_millis_timeout_test.cc |  170 ++++++++++++++++
 osaf/libs/core/cplusplus/base/time.h                    |   35 +++
 4 files changed, 257 insertions(+), 0 deletions(-)


Create functions primary for handling timeout of loops and add to
osaf_time. C++ wrapper class is added to time.h in cplusplus/base

diff --git a/osaf/libs/core/common/include/osaf_time.h 
b/osaf/libs/core/common/include/osaf_time.h
--- a/osaf/libs/core/common/include/osaf_time.h
+++ b/osaf/libs/core/common/include/osaf_time.h
@@ -35,6 +35,7 @@
 #include <stdint.h>
 #include <time.h>
 #include <sys/time.h>
+#include <stdbool.h>
 #include "osaf_utility.h"
 
 #ifdef  __cplusplus
@@ -252,6 +253,23 @@ static inline uint64_t osaf_timespec_to_
  */
 static inline double osaf_timespec_to_double(const struct timespec* i_ts);
 
+/**
+ * @brief Set a time @a i_millis in the future. To be used with
+ * osaf_is_timeout()
+ *
+ * Read current time and add @a i_millis in @a o_ts
+ */
+static inline void osaf_set_millis_timeout(uint64_t i_millis,
+                                           struct timespec* o_ts);
+/**
+ * @brief Inform if the time given in @a i_ts is passed
+ *
+ * Read current time and compare with the given timeout time.
+ * The return value will be -1, 0 or 1, if @a timeout time not passed,
+ * time equal to @a timeout time, or greater than @a timeout time, 
respectively.
+ */
+static inline bool osaf_is_timeout(const struct timespec* i_ts);
+
 static inline void osaf_clock_gettime(clockid_t i_clk_id, struct timespec* 
o_ts) {
   if (clock_gettime(i_clk_id, o_ts) != 0) osaf_abort(i_clk_id);
 }
@@ -369,6 +387,39 @@ static inline double osaf_timespec_to_do
   return i_ts->tv_sec + i_ts->tv_nsec / (double) kNanosPerSec;
 }
 
+static inline void osaf_set_millis_timeout(uint64_t i_millis,
+                                           struct timespec* o_ts) {
+  struct timespec current_ts;
+  struct timespec millis_to_add_ts;
+  osaf_clock_gettime(CLOCK_MONOTONIC, &current_ts);
+  osaf_millis_to_timespec(i_millis, &millis_to_add_ts);
+  osaf_timespec_add(&current_ts, &millis_to_add_ts, o_ts);
+}
+
+static inline bool osaf_is_timeout(const struct timespec* i_ts) {
+  struct timespec current_ts;
+  osaf_clock_gettime(CLOCK_MONOTONIC, &current_ts);
+  if (osaf_timespec_compare(&current_ts, i_ts) < 0)
+    return false;
+  else
+    return true;
+}
+
+static inline uint64_t osaf_timeout_time_left(const struct timespec* i_ts) {
+  struct timespec current_ts;
+  uint64_t time_left = 0;
+  struct timespec diff_ts;
+  osaf_clock_gettime(CLOCK_MONOTONIC, &current_ts);
+  if (osaf_timespec_compare(&current_ts, i_ts) < 0) {
+    osaf_timespec_subtract(i_ts, &current_ts, &diff_ts);
+    time_left = osaf_timespec_to_millis(&diff_ts);
+  } else {
+    time_left = 0;
+  }
+
+  return time_left;
+}
+
 #ifdef  __cplusplus
 }
 #endif
diff --git a/osaf/libs/core/common/tests/Makefile.am 
b/osaf/libs/core/common/tests/Makefile.am
--- a/osaf/libs/core/common/tests/Makefile.am
+++ b/osaf/libs/core/common/tests/Makefile.am
@@ -42,6 +42,7 @@ core_common_test_SOURCES = \
        osaf_timespec_compare_test.cc \
        osaf_timespec_convert_test.cc \
        osaf_timespec_subtract_test.cc \
+       osaf_millis_timeout_test.cc \
        mock_clock_gettime.cc \
        mock_clock_nanosleep.cc \
        mock_syslog.cc
diff --git a/osaf/libs/core/common/tests/osaf_millis_timeout_test.cc 
b/osaf/libs/core/common/tests/osaf_millis_timeout_test.cc
new file mode 100644
--- /dev/null
+++ b/osaf/libs/core/common/tests/osaf_millis_timeout_test.cc
@@ -0,0 +1,170 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2016 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include "osaf_time.h"
+#include "gtest/gtest.h"
+#include "mock_clock_gettime.h"
+
+time_t sec = 1000;
+long nsec = 1000;
+struct timespec ts_expresult = {0, 0};
+
+void setupTest(uint64_t timeout_ms) {
+  realtime_clock = { 0, 0 };
+  monotonic_clock = { sec, nsec };
+  mock_clock_gettime.return_value = 0;
+
+  struct timespec ts_add = {0, 0};
+  osaf_millis_to_timespec(timeout_ms, &ts_add);
+  struct timespec ts_cur = {0, 0};
+  osaf_clock_gettime(CLOCK_MONOTONIC, &ts_cur);
+  osaf_timespec_add(&ts_cur, &ts_add, &ts_expresult);
+}
+
+void advanceTime(uint64_t i_millis) {
+  struct timespec ts_cur = {0, 0};
+  osaf_clock_gettime(CLOCK_MONOTONIC, &ts_cur);
+  struct timespec ts_add = {0, 0};
+  osaf_millis_to_timespec(i_millis, &ts_add);
+  osaf_timespec_add(&ts_cur, &ts_add, &monotonic_clock);
+}
+
+TEST(OsafSetMillisTimeout, FiveSecTimeout) {
+  setupTest(5000);
+
+  struct timespec ts_timeout = { 0, 0 };
+  osaf_set_millis_timeout(5000, &ts_timeout);
+
+  EXPECT_EQ(ts_timeout.tv_sec, ts_expresult.tv_sec);
+  EXPECT_EQ(ts_timeout.tv_nsec, ts_expresult.tv_nsec);
+}
+
+TEST(OsafSetMillisTimeout, ZeroSecTimeout) {
+  setupTest(0);
+
+  struct timespec ts_timeout = { 0, 0 };
+  osaf_set_millis_timeout(0, &ts_timeout);
+
+  EXPECT_EQ(ts_timeout.tv_sec, ts_expresult.tv_sec);
+  EXPECT_EQ(ts_timeout.tv_nsec, ts_expresult.tv_nsec);
+}
+
+TEST(OsafSetMillisTimeout, OneMSecTimeout) {
+  setupTest(1);
+
+  struct timespec ts_timeout = { 0, 0 };
+  osaf_set_millis_timeout(1, &ts_timeout);
+
+  EXPECT_EQ(ts_timeout.tv_sec, ts_expresult.tv_sec);
+  EXPECT_EQ(ts_timeout.tv_nsec, ts_expresult.tv_nsec);
+}
+
+TEST(OsafCheckIsTimeout, NotTimeutOneSecLeft) {
+    setupTest(5000);
+
+  struct timespec ts_timeout = { 0, 0 };
+  osaf_set_millis_timeout(5000, &ts_timeout);
+  advanceTime(4000);
+  bool rc_timeout = true;
+  rc_timeout = osaf_is_timeout(&ts_timeout);
+
+  EXPECT_EQ(rc_timeout, false);
+}
+
+TEST(OsafCheckIsTimeout, NotTimeutOneMilliSecLeft) {
+    setupTest(5000);
+
+  struct timespec ts_timeout = { 0, 0 };
+  osaf_set_millis_timeout(5000, &ts_timeout);
+  advanceTime(4999);
+  bool rc_timeout = true;
+  rc_timeout = osaf_is_timeout(&ts_timeout);
+
+  EXPECT_EQ(rc_timeout, false);
+}
+
+TEST(OsafCheckIsTimeout, TimeutZeroMilliSecLeft) {
+    setupTest(5000);
+
+  struct timespec ts_timeout = { 0, 0 };
+  osaf_set_millis_timeout(5000, &ts_timeout);
+  advanceTime(5000);
+  bool rc_timeout = true;
+  rc_timeout = osaf_is_timeout(&ts_timeout);
+
+  EXPECT_EQ(rc_timeout, true);
+}
+
+TEST(OsafCheckIsTimeout, TimeutTimePassed) {
+    setupTest(5000);
+
+  struct timespec ts_timeout = { 0, 0 };
+  osaf_set_millis_timeout(5000, &ts_timeout);
+  advanceTime(5500);
+  bool rc_timeout = true;
+  rc_timeout = osaf_is_timeout(&ts_timeout);
+
+  EXPECT_EQ(rc_timeout, true);
+}
+
+TEST(OsafCheckTimeLeft, TimeutFourSecLeft) {
+    setupTest(5000);
+
+  struct timespec ts_timeout = { 0, 0 };
+  osaf_set_millis_timeout(5000, &ts_timeout);
+  advanceTime(1000);
+  uint64_t time_left = 0;
+  time_left = osaf_timeout_time_left(&ts_timeout);
+
+  EXPECT_EQ(time_left, 4000);
+}
+
+TEST(OsafCheckTimeLeft, TimeutOneMsLeft) {
+    setupTest(5000);
+
+  struct timespec ts_timeout = { 0, 0 };
+  osaf_set_millis_timeout(5000, &ts_timeout);
+  advanceTime(4999);
+  uint64_t time_left = 0;
+  time_left = osaf_timeout_time_left(&ts_timeout);
+
+  EXPECT_EQ(time_left, 1);
+}
+
+TEST(OsafCheckTimeLeft, TimeutZeroMsLeft) {
+    setupTest(5000);
+
+  struct timespec ts_timeout = { 0, 0 };
+  osaf_set_millis_timeout(5000, &ts_timeout);
+  advanceTime(5000);
+  uint64_t time_left = 0;
+  time_left = osaf_timeout_time_left(&ts_timeout);
+
+  EXPECT_EQ(time_left, 0);
+}
+
+TEST(OsafCheckTimeLeft, TimeutPassedTimeout) {
+    setupTest(5000);
+
+  struct timespec ts_timeout = { 0, 0 };
+  osaf_set_millis_timeout(5000, &ts_timeout);
+  advanceTime(5500);
+  uint64_t time_left = 0;
+  time_left = osaf_timeout_time_left(&ts_timeout);
+
+  EXPECT_EQ(time_left, 0);
+}
diff --git a/osaf/libs/core/cplusplus/base/time.h 
b/osaf/libs/core/cplusplus/base/time.h
--- a/osaf/libs/core/cplusplus/base/time.h
+++ b/osaf/libs/core/cplusplus/base/time.h
@@ -24,6 +24,7 @@
 #include <climits>
 #include <ctime>
 #include "osaf_time.h"
+#include "macros.h"
 
 static inline bool operator<(const timespec& ts1, const timespec& ts2) {
   return osaf_timespec_compare(&ts1, &ts2) < 0;
@@ -270,6 +271,40 @@ static inline timespec Max(const timespe
   return osaf_timespec_compare(&ts1, &ts2) >= 0 ? Max(ts1, ts3) : Max(ts2, 
ts3);
 }
 
+/**
+ * Set a timeout in milliseconds and check if that time has elapsed
+ * The time can be set when the object is created and using a set method
+ */
+class Timer {
+ public:
+  // Set time in ms when creating Timer object
+  explicit Timer(uint64_t i_millis)
+    : m_ts_timeout_time({0,0}) {
+    setTimeoutTime(i_millis);
+  }
+  ~Timer() {};
+
+  // Set time after Timer object is created
+  void setTimeoutTime(uint64_t i_millis) {
+    osaf_set_millis_timeout(i_millis, &m_ts_timeout_time);
+  }
+
+  // Return true if on set time or set time has expired
+  bool isTimeout() {
+    return osaf_is_timeout(&m_ts_timeout_time);
+  }
+
+  // Return time left before timeout in ms
+  uint64_t timeLeft() {
+    return osaf_timeout_time_left(&m_ts_timeout_time);
+  }
+
+ private:
+  struct timespec m_ts_timeout_time;
+
+  DELETE_COPY_AND_MOVE_OPERATORS(Timer);
+};
+
 } // namespace base
 
 #endif /* OPENSAF_OSAF_LIBS_CORE_CPLUSPLUS_BASE_TIME_H_ */

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to