void clockobj_caltime_to_ticks(struct clockobj *clkobj, const struct tm *tm, unsigned long rticks, ticks_t *pticks) { ticks_t t = 0; int n; /* Must be signed. */ /* * We expect tick counts to be based on the time(2) epoch, * i.e. 00:00:00 UTC, January 1, 1970. */ for (n = 1970; n < 1900 + tm->tm_year; n++) t += ((n % 4) ? 365 : 366); if (!(tm->tm_year % 4) && tm->tm_mon >= 2) /* Add one day for leap year after February. */ t++; for (n = tm->tm_mon - 1; n >= 0; n--) t += mdays[n]; t += tm->tm_mday - 1; t *= 24; t += tm->tm_hour; t *= 60; t += tm->tm_min; t *= 60; t += tm->tm_sec; t *= clockobj_get_frequency(clkobj); t += rticks; /* XXX: we currently don't care about DST. */ *pticks = t; }
static int date_to_tmstruct(u_long date, u_long time, u_long ticks, struct tm *tm) { if (ticks > clockobj_get_frequency(&psos_clock)) return ERR_ILLTICKS; memset(tm, 0, sizeof(*tm)); tm->tm_sec = time & 0xff; tm->tm_min = (time >> 8) & 0xff; tm->tm_hour = time >> 16; if (tm->tm_sec > 59 || tm->tm_min > 59 || tm->tm_hour > 23) return ERR_ILLTIME; /* * XXX: we want the calendar time to use the time(2) epoch, * i.e. 00:00:00 UTC, January 1, 1970. */ tm->tm_mday = date & 0xff; tm->tm_mon = ((date >> 8) & 0xff) - 1; tm->tm_year = (date >> 16) - 1900; if (tm->tm_mday < 1 || tm->tm_mday > 31 || tm->tm_mon > 11 || tm->tm_year < 70) return ERR_ILLDATE; return SUCCESS; }
void __clockobj_ticks_to_timespec(struct clockobj *clkobj, ticks_t ticks, struct timespec *ts) { unsigned int freq; if (clockobj_get_resolution(clkobj) > 1) { freq = clockobj_get_frequency(clkobj); ts->tv_sec = ticks / freq; ts->tv_nsec = ticks - (ts->tv_sec * freq); ts->tv_nsec *= clockobj_get_resolution(clkobj); } else clockobj_ns_to_timespec(ticks, ts); }
void clockobj_get_date(struct clockobj *clkobj, ticks_t *pticks) { struct timespec now, date; read_lock_nocancel(&clkobj->lock); __RT(clock_gettime(CLOCK_COPPERPLATE, &now)); /* Add offset from epoch to current system time. */ timespec_add(&date, &clkobj->offset, &now); /* Convert the time value to ticks,. */ *pticks = (ticks_t)date.tv_sec * clockobj_get_frequency(clkobj) + (ticks_t)date.tv_nsec / clockobj_get_resolution(clkobj); read_unlock(&clkobj->lock); }
void clockobj_ticks_to_caltime(struct clockobj *clkobj, ticks_t ticks, struct tm *tm, unsigned long *rticks) { unsigned long year, month, day, hour, min, sec; unsigned int freq; time_t nsecs; freq = clockobj_get_frequency(clkobj); nsecs = ticks / freq; *rticks = ticks % freq; for (year = 1970;; year++) { /* Years since 1970. */ int ysecs = ((year % 4) ? 365 : 366) * SECBYDAY; if (ysecs > nsecs) break; nsecs -= ysecs; } for (month = 0;; month++) { int secbymon = mdays[month] * SECBYDAY; if (month == 1 && (year % 4) == 0) /* Account for leap year on February. */ secbymon += SECBYDAY; if (secbymon > nsecs) break; nsecs -= secbymon; } day = nsecs / SECBYDAY; nsecs -= (day * SECBYDAY); hour = (nsecs / SECBYHOUR); nsecs -= (hour * SECBYHOUR); min = (nsecs / SECBYMIN); nsecs -= (min * SECBYMIN); sec = nsecs; memset(tm, 0, sizeof(*tm)); tm->tm_year = year - 1900; tm->tm_mon = month; tm->tm_mday = day + 1; tm->tm_hour = hour; tm->tm_min = min; tm->tm_sec = sec; }
void clockobj_get_time(struct clockobj *clkobj, ticks_t *pticks, ticks_t *ptsc) { struct timespec now; __RT(clock_gettime(CLOCK_COPPERPLATE, &now)); /* Convert the time value to ticks, with no offset. */ if (clockobj_get_resolution(clkobj) > 1) *pticks = (ticks_t)now.tv_sec * clockobj_get_frequency(clkobj) + (ticks_t)now.tv_nsec / clockobj_get_resolution(clkobj); else *pticks = timespec_scalar(&now); /* * Mercury has a single time source, with TSC == monotonic * time. */ if (ptsc) *ptsc = *pticks; }