From 53f4a8826c9002a81f8c37acee13778c3f6674d0 Mon Sep 17 00:00:00 2001 From: INMakrus Date: Mon, 22 Feb 2016 23:17:29 +0100 Subject: Update Time_Value.inl - Handle big positiv and negativ double values by limiting them to possible values for sec and usec - Correct round for negativ double values: -10.5 => -10 -500000 (not -10 -499999) - no normalize needed cause result is already normalized --- ACE/ace/Time_Value.inl | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/ACE/ace/Time_Value.inl b/ACE/ace/Time_Value.inl index a4b095033e7..98459b47713 100644 --- a/ACE/ace/Time_Value.inl +++ b/ACE/ace/Time_Value.inl @@ -70,10 +70,22 @@ ACE_INLINE void ACE_Time_Value::set (double d) { // ACE_OS_TRACE ("ACE_Time_Value::set"); - time_t l = (time_t) d; - this->tv_.tv_sec = l; - this->tv_.tv_usec = (suseconds_t) ((d - (double) l) * ACE_ONE_SECOND_IN_USECS + .5); - this->normalize (); + if (d < ACE_Numeric_Limits::min()) + { + this->tv_.tv_sec = ACE_Numeric_Limits::min(); + this->tv_.tv_usec = -ACE_ONE_SECOND_IN_USECS + 1; + } + else if (d > ACE_Numeric_Limits::max()) + { + this->tv_.tv_sec = ACE_Numeric_Limits::max(); + this->tv_.tv_usec = ACE_ONE_SECOND_IN_USECS - 1; + } + else + { + time_t l = (time_t) d; + this->tv_.tv_sec = l; + this->tv_.tv_usec = (suseconds_t) ((d - (double) l) * ACE_ONE_SECOND_IN_USECS + (d < 0 ? -0.5 : 0.5)); + } } /// Initializes a timespec_t. Note that this approach loses precision -- cgit v1.2.1 From 5f2fcf252b7b9790a2cb27e57f9d90ae7ea32f9e Mon Sep 17 00:00:00 2001 From: INMakrus Date: Mon, 22 Feb 2016 23:18:46 +0100 Subject: Update Time_Value.cpp - Better performance by not using a loop for normalizing time values --- ACE/ace/Time_Value.cpp | 66 +++++++++++++++++--------------------------------- 1 file changed, 22 insertions(+), 44 deletions(-) diff --git a/ACE/ace/Time_Value.cpp b/ACE/ace/Time_Value.cpp index 36ba22b8ae2..b390d815bc4 100644 --- a/ACE/ace/Time_Value.cpp +++ b/ACE/ace/Time_Value.cpp @@ -174,52 +174,30 @@ ACE_Time_Value::dump (void) const void ACE_Time_Value::normalize (bool saturate) { - // // ACE_OS_TRACE ("ACE_Time_Value::normalize"); - // From Hans Rohnert... - - if (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS) - { - /*! \todo This loop needs some optimization. - */ - if (!saturate) // keep the conditionnal expression outside the while loop to minimize performance cost - do - { - ++this->tv_.tv_sec; - this->tv_.tv_usec -= ACE_ONE_SECOND_IN_USECS; - } - while (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS); - else - do - if (this->tv_.tv_sec < ACE_Numeric_Limits::max()) - { - ++this->tv_.tv_sec; - this->tv_.tv_usec -= ACE_ONE_SECOND_IN_USECS; - } - else - this->tv_.tv_usec = ACE_ONE_SECOND_IN_USECS - 1; - while (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS); - } - else if (this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS) + // ACE_OS_TRACE ("ACE_Time_Value::normalize"); + if (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS || + this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS) { - /*! \todo This loop needs some optimization. - */ - if (!saturate) - do - { - --this->tv_.tv_sec; - this->tv_.tv_usec += ACE_ONE_SECOND_IN_USECS; - } - while (this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS); + time_t sec = abs(this->tv_.tv_usec) / ACE_ONE_SECOND_IN_USECS * (this->tv_.tv_usec > 0 ? 1 : -1); + suseconds_t usec = this->tv_.tv_usec - sec * ACE_ONE_SECOND_IN_USECS; + + if (saturate && this->tv_.tv_sec > 0 && sec > 0 && + ACE_Numeric_Limits::max() - this->tv_.tv_sec < sec) + { + this->tv_.tv_sec = ACE_Numeric_Limits::max(); + this->tv_.tv_usec = ACE_ONE_SECOND_IN_USECS - 1; + } + else if (saturate && this->tv_.tv_sec < 0 && sec < 0 && + ACE_Numeric_Limits::min() - this->tv_.tv_sec > sec) + { + this->tv_.tv_sec = ACE_Numeric_Limits::min(); + this->tv_.tv_usec = -ACE_ONE_SECOND_IN_USECS + 1; + } else - do - if (this->tv_.tv_sec > ACE_Numeric_Limits::min()) - { - --this->tv_.tv_sec; - this->tv_.tv_usec += ACE_ONE_SECOND_IN_USECS; - } - else - this->tv_.tv_usec = -ACE_ONE_SECOND_IN_USECS + 1; - while (this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS); + { + this->tv_.tv_sec += sec; + this->tv_.tv_usec = usec; + } } if (this->tv_.tv_sec >= 1 && this->tv_.tv_usec < 0) -- cgit v1.2.1 From 58100d3aeae33252ad12446f620382734e8f02d2 Mon Sep 17 00:00:00 2001 From: INMarkus Date: Tue, 23 Feb 2016 11:39:20 +0100 Subject: Update Time_Value_Test.cpp Added tests for setting of double values and to check performance of normalize for large numbers. --- ACE/tests/Time_Value_Test.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/ACE/tests/Time_Value_Test.cpp b/ACE/tests/Time_Value_Test.cpp index 5806d67179f..04ec4b3f553 100644 --- a/ACE/tests/Time_Value_Test.cpp +++ b/ACE/tests/Time_Value_Test.cpp @@ -115,6 +115,51 @@ run_main (int, ACE_TCHAR *[]) ACE_TEXT ("msec const test failed: %Q should be 42555\n"), ms)); + // Test setting double values + ACE_Time_Value d1(10, 500000); + ACE_Time_Value d2; + d2.set(10.5); + + ACE_Time_Value d3(-10, -500000); + ACE_Time_Value d4; + d4.set(-10.5); + + ACE_TEST_ASSERT (d1 == d2); + ACE_TEST_ASSERT (d3 == d4); + ACE_TEST_ASSERT (d1 + d3 == ACE_Time_Value::zero); + ACE_TEST_ASSERT (d3 + d1 == ACE_Time_Value::zero); + ACE_TEST_ASSERT (d2 + d4 == ACE_Time_Value::zero); + ACE_TEST_ASSERT (d4 + d2 == ACE_Time_Value::zero); + ACE_TEST_ASSERT (ACE_Time_Value::zero - d1 = d3); + ACE_TEST_ASSERT (ACE_Time_Value::zero - d3 = d1); + ACE_TEST_ASSERT (ACE_Time_Value::zero - d2 = d4); + ACE_TEST_ASSERT (ACE_Time_Value::zero - d4 = d2); + + ACE_Time_Value d5; + d5.set(DBL_MAX); + ACE_TEST_ASSERT (d5 == ACE_Time_Value::max_time); + + // Test performance of normalize() + ACE_Time_Value v1(ACE_Numeric_Limits::max(), + ACE_Numeric_Limits::max()); + ACE_Time_Value v2(ACE_Numeric_Limits::min(), + ACE_Numeric_Limits::min()); + ACE_Time_Value v3(ACE_Numeric_Limits::max(), + ACE_Numeric_Limits::min()); + ACE_Time_Value v4(ACE_Numeric_Limits::min(), + ACE_Numeric_Limits::max()); + + v1.set(ACE_Numeric_Limits::max(), + ACE_Numeric_Limits::max()); + v2.set(ACE_Numeric_Limits::min(), + ACE_Numeric_Limits::min()); + v3.set(ACE_Numeric_Limits::max(), + ACE_Numeric_Limits::min()); + v4.set(ACE_Numeric_Limits::min(), + ACE_Numeric_Limits::max()); + + v1.set(DBL_MAX); + // Test setting from ACE_UINT64 ms = 42555; ACE_Time_Value msec_test3; -- cgit v1.2.1