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, ¤t_ts);
+ osaf_millis_to_timespec(i_millis, &millis_to_add_ts);
+ osaf_timespec_add(¤t_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, ¤t_ts);
+ if (osaf_timespec_compare(¤t_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, ¤t_ts);
+ if (osaf_timespec_compare(¤t_ts, i_ts) < 0) {
+ osaf_timespec_subtract(i_ts, ¤t_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