Commit 49f9eb35 by bernhard-gatzhammer

Solved condition timed wait unsigned overflow bug.

The comparison of absolute times was done in a wrong way such that
unsigned int overflows occured in the windows implementation when
the time to wait for had been passed already. A very big time to
wait for resulted, i.e., a deadlock.

EMBB-466
parent 5abeb065
......@@ -83,8 +83,8 @@ int embb_condition_wait_until(embb_condition_t* condition_var,
embb_time_t now;
embb_time_now(&now);
/* Check if absolute timepoint (in milliseconds) still is in the future */
if (time->seconds * 1000 + time->nanoseconds / 1000000
- now.seconds * 1000 - now.nanoseconds / 1000000 > 0) {
if ((time->seconds * 1000 + time->nanoseconds / 1000000)
> (now.seconds * 1000 + now.nanoseconds / 1000000)) {
/* Convert to (unsigned type) milliseconds and round up */
DWORD time_diff = (DWORD) (
time->seconds * 1000 + time->nanoseconds / 1000000
......
......@@ -105,7 +105,7 @@ void ConditionVarTest::TestTimedWaitTimeouts() {
embb_time_t time;
embb_duration_t duration = EMBB_DURATION_INIT;
// Wait for now tests already passed time point
// Wait for "now" tests already passed time point
embb_time_now(&time);
embb_mutex_lock(&mutex);
int status = embb_condition_wait_until(&cond, &mutex, &time);
......
......@@ -36,6 +36,7 @@ namespace test {
TimeTest::TimeTest() {
CreateUnit("Time in duration").Add(&TimeTest::TestTimeInDuration, this);
CreateUnit("Monotonicity").Add(&TimeTest::TestMonotonicity, this, 1, partest::TestSuite::GetDefaultNumIterations() * 10);
}
void TimeTest::TestTimeInDuration() {
......@@ -48,6 +49,18 @@ void TimeTest::TestTimeInDuration() {
PT_EXPECT_EQ(status, EMBB_SUCCESS);
}
void TimeTest::TestMonotonicity() {
embb_time_t first;
embb_time_t second;
int status1 = embb_time_in(&first, embb_duration_zero());
int status2 = embb_time_in(&second, embb_duration_zero());
PT_EXPECT_EQ(status1, EMBB_SUCCESS);
PT_EXPECT_EQ(status2, EMBB_SUCCESS);
unsigned long long first_abs = first.seconds * 1000 + first.nanoseconds / 1000000;
unsigned long long second_abs = second.seconds * 1000 + second.nanoseconds / 1000000;
PT_EXPECT_GE(second_abs, first_abs);
}
} // namespace test
} // namespace base
} // namespace embb
......@@ -42,9 +42,14 @@ class TimeTest : public partest::TestCase {
private:
/**
* Tests time in duration method.
* Tests time-in-duration method.
*/
void TestTimeInDuration();
/**
* Tests that succeedingly taken times are monotonously increasing.
*/
void TestMonotonicity();
};
} // namespace test
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment