time.h

来自「Linux Kernel 2.6.9 for OMAP1710」· C头文件 代码 · 共 429 行

H
429
字号
#ifndef _LINUX_TIME_H#define _LINUX_TIME_H#include <asm/param.h>#include <linux/types.h>#ifndef _STRUCT_TIMESPEC#define _STRUCT_TIMESPECstruct timespec {	time_t	tv_sec;		/* seconds */	long	tv_nsec;	/* nanoseconds */};#endif /* _STRUCT_TIMESPEC */struct timeval {	time_t		tv_sec;		/* seconds */	suseconds_t	tv_usec;	/* microseconds */};struct timezone {	int	tz_minuteswest;	/* minutes west of Greenwich */	int	tz_dsttime;	/* type of dst correction */};#ifdef __KERNEL__#include <linux/spinlock.h>#include <linux/seqlock.h>#include <linux/timex.h>#include <asm/div64.h>#ifndef div_long_long_rem#define div_long_long_rem(dividend,divisor,remainder) ({ \		       u64 result = dividend;		\		       *remainder = do_div(result,divisor); \		       result; })#endif/* * Have the 32 bit jiffies value wrap 5 minutes after boot * so jiffies wrap bugs show up earlier. */#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))/* * Change timeval to jiffies, trying to avoid the * most obvious overflows.. * * And some not so obvious. * * Note that we don't want to return MAX_LONG, because * for various timeout reasons we often end up having * to wait "jiffies+1" in order to guarantee that we wait * at _least_ "jiffies" - so "jiffies+1" had better still * be positive. */#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)/* Parameters used to convert the timespec values */#ifndef USEC_PER_SEC#define USEC_PER_SEC (1000000L)#endif#ifndef NSEC_PER_SEC#define NSEC_PER_SEC (1000000000L)#endif#ifndef NSEC_PER_USEC#define NSEC_PER_USEC (1000L)#endif/* * We want to do realistic conversions of time so we need to use the same * values the update wall clock code uses as the jiffies size.  This value * is: TICK_NSEC (which is defined in timex.h).  This * is a constant and is in nanoseconds.  We will used scaled math * with a set of scales defined here as SEC_JIFFIE_SC,  USEC_JIFFIE_SC and * NSEC_JIFFIE_SC.  Note that these defines contain nothing but * constants and so are computed at compile time.  SHIFT_HZ (computed in * timex.h) adjusts the scaling for different HZ values. * Scaled math???  What is that? * * Scaled math is a way to do integer math on values that would, * otherwise, either overflow, underflow, or cause undesired div * instructions to appear in the execution path.  In short, we "scale" * up the operands so they take more bits (more precision, less * underflow), do the desired operation and then "scale" the result back * by the same amount.  If we do the scaling by shifting we avoid the * costly mpy and the dastardly div instructions. * Suppose, for example, we want to convert from seconds to jiffies * where jiffies is defined in nanoseconds as NSEC_PER_JIFFIE.  The * simple math is: jiff = (sec * NSEC_PER_SEC) / NSEC_PER_JIFFIE; We * observe that (NSEC_PER_SEC / NSEC_PER_JIFFIE) is a constant which we * might calculate at compile time, however, the result will only have * about 3-4 bits of precision (less for smaller values of HZ). * * So, we scale as follows: * jiff = (sec) * (NSEC_PER_SEC / NSEC_PER_JIFFIE); * jiff = ((sec) * ((NSEC_PER_SEC * SCALE)/ NSEC_PER_JIFFIE)) / SCALE; * Then we make SCALE a power of two so: * jiff = ((sec) * ((NSEC_PER_SEC << SCALE)/ NSEC_PER_JIFFIE)) >> SCALE; * Now we define: * #define SEC_CONV = ((NSEC_PER_SEC << SCALE)/ NSEC_PER_JIFFIE)) * jiff = (sec * SEC_CONV) >> SCALE; * * Often the math we use will expand beyond 32-bits so we tell C how to * do this and pass the 64-bit result of the mpy through the ">> SCALE" * which should take the result back to 32-bits.  We want this expansion * to capture as much precision as possible.  At the same time we don't * want to overflow so we pick the SCALE to avoid this.  In this file, * that means using a different scale for each range of HZ values (as * defined in timex.h). * * For those who want to know, gcc will give a 64-bit result from a "*" * operator if the result is a long long AND at least one of the * operands is cast to long long (usually just prior to the "*" so as * not to confuse it into thinking it really has a 64-bit operand, * which, buy the way, it can do, but it take more code and at least 2 * mpys). * We also need to be aware that one second in nanoseconds is only a * couple of bits away from overflowing a 32-bit word, so we MUST use * 64-bits to get the full range time in nanoseconds. *//* * Here are the scales we will use.  One for seconds, nanoseconds and * microseconds. * * Within the limits of cpp we do a rough cut at the SEC_JIFFIE_SC and * check if the sign bit is set.  If not, we bump the shift count by 1. * (Gets an extra bit of precision where we can use it.) * We know it is set for HZ = 1024 and HZ = 100 not for 1000. * Haven't tested others. * Limits of cpp (for #if expressions) only long (no long long), but * then we only need the most signicant bit. */#define SEC_JIFFIE_SC (31 - SHIFT_HZ)#if !((((NSEC_PER_SEC << 2) / TICK_NSEC) << (SEC_JIFFIE_SC - 2)) & 0x80000000)#undef SEC_JIFFIE_SC#define SEC_JIFFIE_SC (32 - SHIFT_HZ)#endif#define NSEC_JIFFIE_SC (SEC_JIFFIE_SC + 29)#define USEC_JIFFIE_SC (SEC_JIFFIE_SC + 19)#define SEC_CONVERSION ((unsigned long)((((u64)NSEC_PER_SEC << SEC_JIFFIE_SC) +\                                TICK_NSEC -1) / (u64)TICK_NSEC))#define NSEC_CONVERSION ((unsigned long)((((u64)1 << NSEC_JIFFIE_SC) +\                                        TICK_NSEC -1) / (u64)TICK_NSEC))#define USEC_CONVERSION  \                    ((unsigned long)((((u64)NSEC_PER_USEC << USEC_JIFFIE_SC) +\                                        TICK_NSEC -1) / (u64)TICK_NSEC))/* * USEC_ROUND is used in the timeval to jiffie conversion.  See there * for more details.  It is the scaled resolution rounding value.  Note * that it is a 64-bit value.  Since, when it is applied, we are already * in jiffies (albit scaled), it is nothing but the bits we will shift * off. */#define USEC_ROUND (u64)(((u64)1 << USEC_JIFFIE_SC) - 1)/* * The maximum jiffie value is (MAX_INT >> 1).  Here we translate that * into seconds.  The 64-bit case will overflow if we are not careful, * so use the messy SH_DIV macro to do it.  Still all constants. */#if BITS_PER_LONG < 64# define MAX_SEC_IN_JIFFIES \	(long)((u64)((u64)MAX_JIFFY_OFFSET * TICK_NSEC) / NSEC_PER_SEC)#else	/* take care of overflow on 64 bits machines */# define MAX_SEC_IN_JIFFIES \	(SH_DIV((MAX_JIFFY_OFFSET >> SEC_JIFFIE_SC) * TICK_NSEC, NSEC_PER_SEC, 1) - 1)#endif/* * Convert jiffies to milliseconds and back. * * Avoid unnecessary multiplications/divisions in the * two most common HZ cases: */static inline unsigned int jiffies_to_msecs(const unsigned long j){#if HZ <= 1000 && !(1000 % HZ)	return (1000 / HZ) * j;#elif HZ > 1000 && !(HZ % 1000)	return (j + (HZ / 1000) - 1)/(HZ / 1000);#else	return (j * 1000) / HZ;#endif}static inline unsigned int jiffies_to_usecs(const unsigned long j){#if HZ <= 1000 && !(1000 % HZ)	return (1000000 / HZ) * j;#elif HZ > 1000 && !(HZ % 1000)	return (j*1000 + (HZ - 1000))/(HZ / 1000);#else	return (j * 1000000) / HZ;#endif}static inline unsigned long msecs_to_jiffies(const unsigned int m){	if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))		return MAX_JIFFY_OFFSET;#if HZ <= 1000 && !(1000 % HZ)	return (m + (1000 / HZ) - 1) / (1000 / HZ);#elif HZ > 1000 && !(HZ % 1000)	return m * (HZ / 1000);#else	return (m * HZ + 999) / 1000;#endif}/* * 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. */static __inline__ 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;}static __inline__ 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);}/* 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. */static __inline__ 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;}static __inline__ voidjiffies_to_timeval(const unsigned long jiffies, struct timeval *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_usec);	value->tv_usec /= NSEC_PER_USEC;}static __inline__ int timespec_equal(struct timespec *a, struct timespec *b) { 	return (a->tv_sec == b->tv_sec) && (a->tv_nsec == b->tv_nsec);} /* 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) */static inline unsigned longmktime (unsigned int year, unsigned int mon,	unsigned int day, unsigned int hour,	unsigned int min, unsigned int sec){	if (0 >= (int) (mon -= 2)) {	/* 1..12 -> 11,12,1..10 */		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 */}extern struct timespec xtime;extern struct timespec wall_to_monotonic;extern seqlock_t xtime_lock;static inline unsigned long get_seconds(void){ 	return xtime.tv_sec;}struct timespec current_kernel_time(void);#define CURRENT_TIME (current_kernel_time())#endif /* __KERNEL__ */#define NFDBITS			__NFDBITS#ifdef __KERNEL__extern void do_gettimeofday(struct timeval *tv);extern int do_settimeofday(struct timespec *tv);extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz);extern void clock_was_set(void); // call when ever the clock is setextern int do_posix_clock_monotonic_gettime(struct timespec *tp);extern long do_nanosleep(struct timespec *t);extern long do_utimes(char __user * filename, struct timeval * times);struct itimerval;extern int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue);extern int do_getitimer(int which, struct itimerval *value);extern void getnstimeofday (struct timespec *tv);static inline voidset_normalized_timespec (struct timespec *ts, time_t sec, long nsec){	while (nsec > NSEC_PER_SEC) {		nsec -= NSEC_PER_SEC;		++sec;	}	while (unlikely(nsec < 0)) {		nsec += NSEC_PER_SEC;		--sec;	}	ts->tv_sec = sec;	ts->tv_nsec = nsec;}#define timespec_norm(a) set_normalized_timespec((a), (a)->tv_sec, (a)->tv_nsec)#endif#define FD_SETSIZE		__FD_SETSIZE#define FD_SET(fd,fdsetp)	__FD_SET(fd,fdsetp)#define FD_CLR(fd,fdsetp)	__FD_CLR(fd,fdsetp)#define FD_ISSET(fd,fdsetp)	__FD_ISSET(fd,fdsetp)#define FD_ZERO(fdsetp)		__FD_ZERO(fdsetp)/* * Names of the interval timers, and structure * defining a timer setting. */#define	ITIMER_REAL	0#define	ITIMER_VIRTUAL	1#define	ITIMER_PROF	2struct  itimerspec {        struct  timespec it_interval;    /* timer period */        struct  timespec it_value;       /* timer expiration */};struct	itimerval {	struct	timeval it_interval;	/* timer interval */	struct	timeval it_value;	/* current value */};/* * The IDs of the various system clocks (for POSIX.1b interval timers). */#define CLOCK_REALTIME		  0#define CLOCK_MONOTONIC	  1#define CLOCK_PROCESS_CPUTIME_ID 2#define CLOCK_THREAD_CPUTIME_ID	 3#define CLOCK_REALTIME_HR	 4#define CLOCK_MONOTONIC_HR	  5#define MAX_CLOCKS 6/* * The various flags for setting POSIX.1b interval timers. */#define TIMER_ABSTIME 0x01#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?