gettimeoftheday, clock_gettime, tick_microsecs, tick_nanosec

Post Reply
Oibaf
Posts: 34
Joined: Mon Jul 04, 2011 1:03 pm

gettimeoftheday, clock_gettime, tick_microsecs, tick_nanosec

Post by Oibaf » Sun Dec 14, 2014 9:21 am

The functions gettimeoftheday(), clock_gettime(), tick_microsecs, tick_nanosecs in libogc are all buggy.

In this post there is a decription of the issues:

http://devkitpro.org/viewtopic.php?f=3&t=3056

To sum up:

In lwp_watchdog.h the macros tick_microsecs and tick_nanosecs should be defined as:

#define tick_microsecs(ticks) ((((u64)(ticks)*8)/(u64)(TB_TIMER_CLOCK/125))%1000000)
#define tick_nanosecs(ticks) ((((u64)(ticks)*8000)/(u64)(TB_TIMER_CLOCK/125))%1000000000)

This partially fixes gettimeoftheday().

Moreover in timesupp.c the function clock_gettime() should be patched as:

-tp->tv_nsec = tick_to_nanosecs(gettick());
+tp->tv_nsec = tick_nanosecs(gettick());

Anyhow also with these fixes gettimeoftheday() and clock_gettime() are not fully correct.

The result of tv_sec is correct for both, reppresenting the number of seconds since 00:00 hours, Jan 1, 1970 UTC.

tv_nsec in clock_gettime and tv_usec in __libogc_gettod_r should be respectively the number of nanoseconds and microseconds expired in the current second but instead they are values taken from the internal CPU timer which is not aligned with the RTC timer of the WII. I do not know any other solution.

tueidj
Posts: 40
Joined: Thu Dec 10, 2009 9:26 am

Re: gettimeoftheday, clock_gettime, tick_microsecs, tick_nan

Post by tueidj » Mon Dec 15, 2014 4:39 am

The RTC does not provide sub-second accuracy so using the CPU timebase is the only logical choice. The fact that they're not aligned is irrelevant; even if they were, they are being accessed separately at different points in time instead of using a single atomic tick value to calculate both tv_sec and tv_nsec/tv_usec.
__SYS_SetBootTime() should be called during system startup and __SYS_GetSystemTime() should be used by any functions that need calender time with sub-second accuracy. There should be no need to access the RTC by any functions once __SYS_SetBootTime() has executed.

Oibaf
Posts: 34
Joined: Mon Jul 04, 2011 1:03 pm

Re: gettimeoftheday, clock_gettime, tick_microsecs, tick_nan

Post by Oibaf » Mon Dec 15, 2014 2:48 pm

Tueidj, I agree with you that he fact that they're not aligned is irrelevant in the majority of the applications.

Anyhow in libogc tick_microsecs and tick_nanosecs should be changed as indicated above since currently they are wrong.

And in timesupp.c the function clock_gettime() should be patched using tick_nanosecs in place of tick_to_nanosecs otherwise tv_nsec could overflow the limit of one second.

Oibaf
Posts: 34
Joined: Mon Jul 04, 2011 1:03 pm

Re: gettimeoftheday, clock_gettime, tick_microsecs, tick_nan

Post by Oibaf » Sun Jan 08, 2017 10:11 am

Regarding this topic I propose this patch

Code: Select all

 libogc/timesupp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libogc/timesupp.c b/libogc/timesupp.c
index 24ab9d7..493f5d1 100644
--- a/libogc/timesupp.c
+++ b/libogc/timesupp.c
@@ -163,7 +163,7 @@ int clock_gettime(struct timespec *tp)
 	gctime += 946684800;
 
 	tp->tv_sec = gctime;
-	tp->tv_nsec = ticks_to_nanosecs(gettick());
+	tp->tv_nsec = ticks_to_nanosecs(gettick())%1000000000;
 
 	return 0;
 }
@@ -319,7 +319,7 @@ int __libogc_gettod_r(struct _reent *ptr, struct timeval *tp, struct timezone *t
 
 	if (tp != NULL) {
 		tp->tv_sec = time(NULL);
-		tp->tv_usec = tick_microsecs(gettick());
+		tp->tv_usec = ticks_to_microsecs(gettick())%1000000;
 	}
 	if (tz != NULL) {
 		tz->tz_minuteswest = 0;

Post Reply

Who is online

Users browsing this forum: No registered users and 5 guests