Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 23141 Details for
Bug 37081
linux-headers-2.6.0: redefinition of struct timespec
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
/usr/include/linux/time.h
time.h (text/plain), 12.55 KB, created by
Udo Beckmann
on 2004-01-04 08:54:32 UTC
(
hide
)
Description:
/usr/include/linux/time.h
Filename:
MIME Type:
Creator:
Udo Beckmann
Created:
2004-01-04 08:54:32 UTC
Size:
12.55 KB
patch
obsolete
>#ifndef _LINUX_TIME_H >#define _LINUX_TIME_H > >#include <asm/param.h> >#include <linux/types.h> > >#ifndef _SYS_TIME_H >#ifndef _STRUCT_TIMESPEC >#ifndef __timespec_defined >#define _STRUCT_TIMESPEC >struct timespec { > time_t tv_sec; /* seconds */ > long tv_nsec; /* nanoseconds */ >}; >#endif /* __timespec_defined */ >#endif /* _STRUCT_TIMESPEC */ > >#ifndef _STRUCT_TIMEVAL >struct timeval { > time_t tv_sec; /* seconds */ > suseconds_t tv_usec; /* microseconds */ >}; >#endif /* _STRUCT_TIMEVAL */ > >struct timezone { > int tz_minuteswest; /* minutes west of Greenwich */ > int tz_dsttime; /* type of dst correction */ >}; > >#endif /* _SYS_TIME_H */ > >#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))\ > / (u64)TICK_NSEC)) > >#define NSEC_CONVERSION ((unsigned long)((((u64)1 << NSEC_JIFFIE_SC))\ > / (u64)TICK_NSEC)) >#define USEC_CONVERSION \ > ((unsigned long)((((u64)NSEC_PER_USEC << USEC_JIFFIE_SC)) \ > / (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 >/* > * 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 long >timespec_to_jiffies(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__ void >jiffies_to_timespec(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 long >timeval_to_jiffies(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__ void >jiffies_to_timeval(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 long >mktime (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 set >extern 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); > >static inline 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; >} >#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 2 > >#ifndef _TIME_H >struct itimerspec { > struct timespec it_interval; /* timer period */ > struct timespec it_value; /* timer expiration */ >}; >#endif /* _TIME_H */ > >#ifndef _SYS_TIME_H >struct itimerval { > struct timeval it_interval; /* timer interval */ > struct timeval it_value; /* current value */ >}; >#endif /* _SYS_TIME_H */ > > >/* > * 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 >#define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC | \ > CLOCK_REALTIME_HR | CLOCK_MONOTONIC_HR) >#define CLOCKS_MONO (CLOCK_MONOTONIC & CLOCK_MONOTONIC_HR) > >/* > * The various flags for setting POSIX.1b interval timers. > */ > >#define TIMER_ABSTIME 0x01 > > >#endif
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 37081
:
23140
| 23141 |
23142
|
23143