Merge branch 'bugfix/adjtime_return_outdelta_before_new_delta_set' into 'master'

newlib: Fix adjtime, returns the amount of time remaining from any previous adjustment

Closes IDFGH-3192 and IDFGH-3187

See merge request espressif/esp-idf!9105
This commit is contained in:
Angus Gratton 2020-06-30 13:15:23 +08:00
commit 8912462d95
2 changed files with 29 additions and 24 deletions

View file

@ -81,25 +81,27 @@ TEST_CASE("test adjtime function", "[newlib]")
tv_delta.tv_sec = 0;
tv_delta.tv_usec = -900000;
TEST_ASSERT_EQUAL(adjtime(&tv_delta, &tv_outdelta), 0);
TEST_ASSERT_TRUE(tv_outdelta.tv_usec <= 0);
tv_delta.tv_sec = 0;
tv_delta.tv_usec = 900000;
TEST_ASSERT_EQUAL(adjtime(&tv_delta, &tv_outdelta), 0);
TEST_ASSERT_TRUE(tv_outdelta.tv_usec >= 0);
TEST_ASSERT_EQUAL(tv_outdelta.tv_sec, 0);
TEST_ASSERT_EQUAL(tv_outdelta.tv_usec, 0);
TEST_ASSERT_EQUAL(adjtime(NULL, &tv_outdelta), 0);
TEST_ASSERT_LESS_THAN(-800000, tv_outdelta.tv_usec);
tv_delta.tv_sec = -4;
tv_delta.tv_usec = -900000;
TEST_ASSERT_EQUAL(adjtime(&tv_delta, &tv_outdelta), 0);
TEST_ASSERT_EQUAL(adjtime(&tv_delta, NULL), 0);
TEST_ASSERT_EQUAL(adjtime(NULL, &tv_outdelta), 0);
TEST_ASSERT_EQUAL(tv_outdelta.tv_sec, -4);
TEST_ASSERT_TRUE(tv_outdelta.tv_usec <= 0);
TEST_ASSERT_LESS_THAN(-800000, tv_outdelta.tv_usec);
// after settimeofday() adjtime() is stopped
tv_delta.tv_sec = 15;
tv_delta.tv_usec = 900000;
TEST_ASSERT_EQUAL(adjtime(&tv_delta, &tv_outdelta), 0);
TEST_ASSERT_EQUAL(tv_outdelta.tv_sec, -4);
TEST_ASSERT_LESS_THAN(-800000, tv_outdelta.tv_usec);
TEST_ASSERT_EQUAL(adjtime(NULL, &tv_outdelta), 0);
TEST_ASSERT_EQUAL(tv_outdelta.tv_sec, 15);
TEST_ASSERT_TRUE(tv_outdelta.tv_usec >= 0);
TEST_ASSERT_GREATER_OR_EQUAL(800000, tv_outdelta.tv_usec);
TEST_ASSERT_EQUAL(gettimeofday(&tv_time, NULL), 0);
TEST_ASSERT_EQUAL(settimeofday(&tv_time, NULL), 0);
@ -112,21 +114,24 @@ TEST_CASE("test adjtime function", "[newlib]")
tv_delta.tv_sec = 15;
tv_delta.tv_usec = 900000;
TEST_ASSERT_EQUAL(adjtime(&tv_delta, &tv_outdelta), 0);
TEST_ASSERT_EQUAL(tv_outdelta.tv_sec, 0);
TEST_ASSERT_EQUAL(tv_outdelta.tv_usec, 0);
TEST_ASSERT_EQUAL(adjtime(NULL, &tv_outdelta), 0);
TEST_ASSERT_EQUAL(tv_outdelta.tv_sec, 15);
TEST_ASSERT_TRUE(tv_outdelta.tv_usec >= 0);
TEST_ASSERT_GREATER_OR_EQUAL(800000, tv_outdelta.tv_usec);
TEST_ASSERT_EQUAL(gettimeofday(&tv_time, NULL), 0);
TEST_ASSERT_EQUAL(adjtime(NULL, &tv_outdelta), 0);
TEST_ASSERT_EQUAL(tv_outdelta.tv_sec, 15);
TEST_ASSERT_TRUE(tv_outdelta.tv_usec >= 0);
TEST_ASSERT_GREATER_OR_EQUAL(800000, tv_outdelta.tv_usec);
tv_delta.tv_sec = 1;
tv_delta.tv_usec = 0;
TEST_ASSERT_EQUAL(adjtime(&tv_delta, NULL), 0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
TEST_ASSERT_EQUAL(adjtime(NULL, &tv_outdelta), 0);
TEST_ASSERT_TRUE(tv_outdelta.tv_sec == 0);
TEST_ASSERT_EQUAL(tv_outdelta.tv_sec, 0);
// the correction will be equal to (1_000_000us >> 6) = 15_625 us.
TEST_ASSERT_TRUE(1000000L - tv_outdelta.tv_usec >= 15600);
TEST_ASSERT_TRUE(1000000L - tv_outdelta.tv_usec <= 15650);

View file

@ -193,6 +193,18 @@ static void adjtime_corr_stop (void)
int adjtime(const struct timeval *delta, struct timeval *outdelta)
{
#if defined( WITH_FRC ) || defined( WITH_RTC )
if(outdelta != NULL){
_lock_acquire(&s_adjust_time_lock);
adjust_boot_time();
if (adjtime_start != 0) {
outdelta->tv_sec = adjtime_total_correction / 1000000L;
outdelta->tv_usec = adjtime_total_correction % 1000000L;
} else {
outdelta->tv_sec = 0;
outdelta->tv_usec = 0;
}
_lock_release(&s_adjust_time_lock);
}
if(delta != NULL){
int64_t sec = delta->tv_sec;
int64_t usec = delta->tv_usec;
@ -211,18 +223,6 @@ int adjtime(const struct timeval *delta, struct timeval *outdelta)
adjtime_total_correction = sec * 1000000L + usec;
_lock_release(&s_adjust_time_lock);
}
if(outdelta != NULL){
_lock_acquire(&s_adjust_time_lock);
adjust_boot_time();
if (adjtime_start != 0) {
outdelta->tv_sec = adjtime_total_correction / 1000000L;
outdelta->tv_usec = adjtime_total_correction % 1000000L;
} else {
outdelta->tv_sec = 0;
outdelta->tv_usec = 0;
}
_lock_release(&s_adjust_time_lock);
}
return 0;
#else
return -1;