From: Ben Gras Date: Mon, 24 Jun 2013 13:46:20 +0000 (+0200) Subject: kernel: high-hz workaround for do_settime X-Git-Tag: v3.3.0~901 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zlib_tech.html?a=commitdiff_plain;h=27f7fd3554a7b7c152029a608aa47d7b34f300d6;p=minix.git kernel: high-hz workaround for do_settime . with hz=1000, clock_t only lasts a few years. whenever we can't express the desired realtime in ticks because the distance with boottime is too high, simply adjust bootime like we do for otherwise negative values. . fixes test 2 on ARM --- diff --git a/kernel/system/do_settime.c b/kernel/system/do_settime.c index bf408ce69..b9116331a 100644 --- a/kernel/system/do_settime.c +++ b/kernel/system/do_settime.c @@ -19,6 +19,7 @@ int do_settime(struct proc * caller, message * m_ptr) { clock_t newclock, ticks; time_t timediff; + signed long long timediff_ticks; if (m_ptr->T_CLOCK_ID != CLOCK_REALTIME) /* only realtime can change */ return EINVAL; @@ -31,8 +32,12 @@ int do_settime(struct proc * caller, message * m_ptr) return(OK); } /* else user wants to set the time */ + timediff = m_ptr->T_TIME_SEC - boottime; + timediff_ticks = (signed long long) timediff * system_hz; + /* prevent a negative value for realtime */ - if (m_ptr->T_TIME_SEC <= boottime) { + if (m_ptr->T_TIME_SEC <= boottime || + timediff_ticks < LONG_MIN/2 || timediff_ticks > LONG_MAX/2) { /* boottime was likely wrong, try to correct it. */ boottime = m_ptr->T_TIME_SEC; set_realtime(1); @@ -40,8 +45,7 @@ int do_settime(struct proc * caller, message * m_ptr) } /* calculate the new value of realtime in ticks */ - timediff = m_ptr->T_TIME_SEC - boottime; - newclock = (timediff*system_hz) + (m_ptr->T_TIME_NSEC/(1000000000/system_hz)); + newclock = timediff_ticks + (m_ptr->T_TIME_NSEC/(1000000000/system_hz)); set_realtime(newclock);