📄 time.c
字号:
tv->tv_usec = usec;}EXPORT_SYMBOL(do_gettimeofday);#else#ifndef CONFIG_GENERIC_TIME/* * Simulate gettimeofday using do_gettimeofday which only allows a timeval * and therefore only yields usec accuracy */void getnstimeofday(struct timespec *tv){ struct timeval x; do_gettimeofday(&x); tv->tv_sec = x.tv_sec; tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;}EXPORT_SYMBOL_GPL(getnstimeofday);#endif#endif/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. * * [For the Julian calendar (which was used in Russia before 1917, * Britain & colonies before 1752, anywhere else before 1582, * and is still in use by some communities) leave out the * -year/100+year/400 terms, and add 10.] * * This algorithm was first published by Gauss (I think). * * WARNING: this function will overflow on 2106-02-07 06:28:16 on * machines were long is 32-bit! (However, as time_t is signed, we * will already get problems at other places on 2038-01-19 03:14:08) */unsigned longmktime(const unsigned int year0, const unsigned int mon0, const unsigned int day, const unsigned int hour, const unsigned int min, const unsigned int sec){ unsigned int mon = mon0, year = year0; /* 1..12 -> 11,12,1..10 */ if (0 >= (int) (mon -= 2)) { mon += 12; /* Puts Feb last since it has leap day */ year -= 1; } return ((((unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) + year*365 - 719499 )*24 + hour /* now have hours */ )*60 + min /* now have minutes */ )*60 + sec; /* finally seconds */}EXPORT_SYMBOL(mktime);/** * set_normalized_timespec - set timespec sec and nsec parts and normalize * * @ts: pointer to timespec variable to be set * @sec: seconds to set * @nsec: nanoseconds to set * * Set seconds and nanoseconds field of a timespec variable and * normalize to the timespec storage format * * Note: The tv_nsec part is always in the range of * 0 <= tv_nsec < NSEC_PER_SEC * For negative values only the tv_sec field is negative ! */void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec){ while (nsec >= NSEC_PER_SEC) { nsec -= NSEC_PER_SEC; ++sec; } while (nsec < 0) { nsec += NSEC_PER_SEC; --sec; } ts->tv_sec = sec; ts->tv_nsec = nsec;}/** * ns_to_timespec - Convert nanoseconds to timespec * @nsec: the nanoseconds value to be converted * * Returns the timespec representation of the nsec parameter. */struct timespec ns_to_timespec(const s64 nsec){ struct timespec ts; if (!nsec) return (struct timespec) {0, 0}; ts.tv_sec = div_long_long_rem_signed(nsec, NSEC_PER_SEC, &ts.tv_nsec); if (unlikely(nsec < 0)) set_normalized_timespec(&ts, ts.tv_sec, ts.tv_nsec); return ts;}EXPORT_SYMBOL(ns_to_timespec);/** * ns_to_timeval - Convert nanoseconds to timeval * @nsec: the nanoseconds value to be converted * * Returns the timeval representation of the nsec parameter. */struct timeval ns_to_timeval(const s64 nsec){ struct timespec ts = ns_to_timespec(nsec); struct timeval tv; tv.tv_sec = ts.tv_sec; tv.tv_usec = (suseconds_t) ts.tv_nsec / 1000; return tv;}EXPORT_SYMBOL(ns_to_timeval);/* * When we convert to jiffies then we interpret incoming values * the following way: * * - negative values mean 'infinite timeout' (MAX_JIFFY_OFFSET) * * - 'too large' values [that would result in larger than * MAX_JIFFY_OFFSET values] mean 'infinite timeout' too. * * - all other values are converted to jiffies by either multiplying * the input value by a factor or dividing it with a factor * * We must also be careful about 32-bit overflows. */unsigned long msecs_to_jiffies(const unsigned int m){ /* * Negative value, means infinite timeout: */ if ((int)m < 0) return MAX_JIFFY_OFFSET;#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) /* * HZ is equal to or smaller than 1000, and 1000 is a nice * round multiple of HZ, divide with the factor between them, * but round upwards: */ return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) /* * HZ is larger than 1000, and HZ is a nice round multiple of * 1000 - simply multiply with the factor between them. * * But first make sure the multiplication result cannot * overflow: */ if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) return MAX_JIFFY_OFFSET; return m * (HZ / MSEC_PER_SEC);#else /* * Generic case - multiply, round and divide. But first * check that if we are doing a net multiplication, that * we wouldnt overflow: */ if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) return MAX_JIFFY_OFFSET; return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC;#endif}EXPORT_SYMBOL(msecs_to_jiffies);unsigned long usecs_to_jiffies(const unsigned int u){ if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET)) return MAX_JIFFY_OFFSET;#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ) return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ);#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC) return u * (HZ / USEC_PER_SEC);#else return (u * HZ + USEC_PER_SEC - 1) / USEC_PER_SEC;#endif}EXPORT_SYMBOL(usecs_to_jiffies);/* * The TICK_NSEC - 1 rounds up the value to the next resolution. Note * that a remainder subtract here would not do the right thing as the * resolution values don't fall on second boundries. I.e. the line: * nsec -= nsec % TICK_NSEC; is NOT a correct resolution rounding. * * Rather, we just shift the bits off the right. * * The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec * value to a scaled second value. */unsigned longtimespec_to_jiffies(const struct timespec *value){ unsigned long sec = value->tv_sec; long nsec = value->tv_nsec + TICK_NSEC - 1; if (sec >= MAX_SEC_IN_JIFFIES){ sec = MAX_SEC_IN_JIFFIES; nsec = 0; } return (((u64)sec * SEC_CONVERSION) + (((u64)nsec * NSEC_CONVERSION) >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;}EXPORT_SYMBOL(timespec_to_jiffies);voidjiffies_to_timespec(const unsigned long jiffies, struct timespec *value){ /* * Convert jiffies to nanoseconds and separate with * one divide. */ u64 nsec = (u64)jiffies * TICK_NSEC; value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_nsec);}EXPORT_SYMBOL(jiffies_to_timespec);/* Same for "timeval" * * Well, almost. The problem here is that the real system resolution is * in nanoseconds and the value being converted is in micro seconds. * Also for some machines (those that use HZ = 1024, in-particular), * there is a LARGE error in the tick size in microseconds. * The solution we use is to do the rounding AFTER we convert the * microsecond part. Thus the USEC_ROUND, the bits to be shifted off. * Instruction wise, this should cost only an additional add with carry * instruction above the way it was done above. */unsigned longtimeval_to_jiffies(const struct timeval *value){ unsigned long sec = value->tv_sec; long usec = value->tv_usec; if (sec >= MAX_SEC_IN_JIFFIES){ sec = MAX_SEC_IN_JIFFIES; usec = 0; } return (((u64)sec * SEC_CONVERSION) + (((u64)usec * USEC_CONVERSION + USEC_ROUND) >> (USEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;}EXPORT_SYMBOL(timeval_to_jiffies);void jiffies_to_timeval(const unsigned long jiffies, struct timeval *value){ /* * Convert jiffies to nanoseconds and separate with * one divide. */ u64 nsec = (u64)jiffies * TICK_NSEC; long tv_usec; value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tv_usec); tv_usec /= NSEC_PER_USEC; value->tv_usec = tv_usec;}EXPORT_SYMBOL(jiffies_to_timeval);/* * Convert jiffies/jiffies_64 to clock_t and back. */clock_t jiffies_to_clock_t(long x){#if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 return x / (HZ / USER_HZ);#else u64 tmp = (u64)x * TICK_NSEC; do_div(tmp, (NSEC_PER_SEC / USER_HZ)); return (long)tmp;#endif}EXPORT_SYMBOL(jiffies_to_clock_t);unsigned long clock_t_to_jiffies(unsigned long x){#if (HZ % USER_HZ)==0 if (x >= ~0UL / (HZ / USER_HZ)) return ~0UL; return x * (HZ / USER_HZ);#else u64 jif; /* Don't worry about loss of precision here .. */ if (x >= ~0UL / HZ * USER_HZ) return ~0UL; /* .. but do try to contain it here */ jif = x * (u64) HZ; do_div(jif, USER_HZ); return jif;#endif}EXPORT_SYMBOL(clock_t_to_jiffies);u64 jiffies_64_to_clock_t(u64 x){#if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 do_div(x, HZ / USER_HZ);#else /* * There are better ways that don't overflow early, * but even this doesn't overflow in hundreds of years * in 64 bits, so.. */ x *= TICK_NSEC; do_div(x, (NSEC_PER_SEC / USER_HZ));#endif return x;}EXPORT_SYMBOL(jiffies_64_to_clock_t);u64 nsec_to_clock_t(u64 x){#if (NSEC_PER_SEC % USER_HZ) == 0 do_div(x, (NSEC_PER_SEC / USER_HZ));#elif (USER_HZ % 512) == 0 x *= USER_HZ/512; do_div(x, (NSEC_PER_SEC / 512));#else /* * max relative error 5.7e-8 (1.8s per year) for USER_HZ <= 1024, * overflow after 64.99 years. * exact for HZ=60, 72, 90, 120, 144, 180, 300, 600, 900, ... */ x *= 9; do_div(x, (unsigned long)((9ull * NSEC_PER_SEC + (USER_HZ/2)) / USER_HZ));#endif return x;}#if (BITS_PER_LONG < 64)u64 get_jiffies_64(void){ unsigned long seq; u64 ret; do { seq = read_seqbegin(&xtime_lock); ret = jiffies_64; } while (read_seqretry(&xtime_lock, seq)); return ret;}EXPORT_SYMBOL(get_jiffies_64);#endifEXPORT_SYMBOL(jiffies);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -