time: More core infrastructure for timespec64
Helper and conversion functions for timespec64. Signed-off-by: John Stultz <john.stultz@linaro.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: John Stultz <john.stultz@linaro.org>
This commit is contained in:
parent
361a3bf005
commit
49cd6f8699
|
@ -83,6 +83,12 @@ static inline ktime_t timespec_to_ktime(struct timespec ts)
|
||||||
return ktime_set(ts.tv_sec, ts.tv_nsec);
|
return ktime_set(ts.tv_sec, ts.tv_nsec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* convert a timespec64 to ktime_t format: */
|
||||||
|
static inline ktime_t timespec64_to_ktime(struct timespec64 ts)
|
||||||
|
{
|
||||||
|
return ktime_set(ts.tv_sec, ts.tv_nsec);
|
||||||
|
}
|
||||||
|
|
||||||
/* convert a timeval to ktime_t format: */
|
/* convert a timeval to ktime_t format: */
|
||||||
static inline ktime_t timeval_to_ktime(struct timeval tv)
|
static inline ktime_t timeval_to_ktime(struct timeval tv)
|
||||||
{
|
{
|
||||||
|
@ -92,6 +98,9 @@ static inline ktime_t timeval_to_ktime(struct timeval tv)
|
||||||
/* Map the ktime_t to timespec conversion to ns_to_timespec function */
|
/* Map the ktime_t to timespec conversion to ns_to_timespec function */
|
||||||
#define ktime_to_timespec(kt) ns_to_timespec((kt).tv64)
|
#define ktime_to_timespec(kt) ns_to_timespec((kt).tv64)
|
||||||
|
|
||||||
|
/* Map the ktime_t to timespec conversion to ns_to_timespec function */
|
||||||
|
#define ktime_to_timespec64(kt) ns_to_timespec64((kt).tv64)
|
||||||
|
|
||||||
/* Map the ktime_t to timeval conversion to ns_to_timeval function */
|
/* Map the ktime_t to timeval conversion to ns_to_timeval function */
|
||||||
#define ktime_to_timeval(kt) ns_to_timeval((kt).tv64)
|
#define ktime_to_timeval(kt) ns_to_timeval((kt).tv64)
|
||||||
|
|
||||||
|
@ -213,6 +222,25 @@ static inline __must_check bool ktime_to_timespec_cond(const ktime_t kt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ktime_to_timespec64_cond - convert a ktime_t variable to timespec64
|
||||||
|
* format only if the variable contains data
|
||||||
|
* @kt: the ktime_t variable to convert
|
||||||
|
* @ts: the timespec variable to store the result in
|
||||||
|
*
|
||||||
|
* Return: %true if there was a successful conversion, %false if kt was 0.
|
||||||
|
*/
|
||||||
|
static inline __must_check bool ktime_to_timespec64_cond(const ktime_t kt,
|
||||||
|
struct timespec64 *ts)
|
||||||
|
{
|
||||||
|
if (kt.tv64) {
|
||||||
|
*ts = ktime_to_timespec64(kt);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The resolution of the clocks. The resolution value is returned in
|
* The resolution of the clocks. The resolution value is returned in
|
||||||
* the clock_getres() system call to give application programmers an
|
* the clock_getres() system call to give application programmers an
|
||||||
|
|
|
@ -33,6 +33,16 @@ struct timespec64 {
|
||||||
|
|
||||||
#if __BITS_PER_LONG == 64
|
#if __BITS_PER_LONG == 64
|
||||||
|
|
||||||
|
static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
|
||||||
|
{
|
||||||
|
return ts64;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
|
||||||
|
{
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
# define timespec64_equal timespec_equal
|
# define timespec64_equal timespec_equal
|
||||||
# define timespec64_compare timespec_compare
|
# define timespec64_compare timespec_compare
|
||||||
# define set_normalized_timespec64 set_normalized_timespec
|
# define set_normalized_timespec64 set_normalized_timespec
|
||||||
|
@ -47,6 +57,24 @@ struct timespec64 {
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
|
||||||
|
{
|
||||||
|
struct timespec ret;
|
||||||
|
|
||||||
|
ret.tv_sec = (time_t)ts64.tv_sec;
|
||||||
|
ret.tv_nsec = ts64.tv_nsec;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
|
||||||
|
{
|
||||||
|
struct timespec64 ret;
|
||||||
|
|
||||||
|
ret.tv_sec = ts.tv_sec;
|
||||||
|
ret.tv_nsec = ts.tv_nsec;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int timespec64_equal(const struct timespec64 *a,
|
static inline int timespec64_equal(const struct timespec64 *a,
|
||||||
const struct timespec64 *b)
|
const struct timespec64 *b)
|
||||||
{
|
{
|
||||||
|
|
|
@ -420,6 +420,68 @@ struct timeval ns_to_timeval(const s64 nsec)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ns_to_timeval);
|
EXPORT_SYMBOL(ns_to_timeval);
|
||||||
|
|
||||||
|
#if BITS_PER_LONG == 32
|
||||||
|
/**
|
||||||
|
* 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_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec)
|
||||||
|
{
|
||||||
|
while (nsec >= NSEC_PER_SEC) {
|
||||||
|
/*
|
||||||
|
* The following asm() prevents the compiler from
|
||||||
|
* optimising this loop into a modulo operation. See
|
||||||
|
* also __iter_div_u64_rem() in include/linux/time.h
|
||||||
|
*/
|
||||||
|
asm("" : "+rm"(nsec));
|
||||||
|
nsec -= NSEC_PER_SEC;
|
||||||
|
++sec;
|
||||||
|
}
|
||||||
|
while (nsec < 0) {
|
||||||
|
asm("" : "+rm"(nsec));
|
||||||
|
nsec += NSEC_PER_SEC;
|
||||||
|
--sec;
|
||||||
|
}
|
||||||
|
ts->tv_sec = sec;
|
||||||
|
ts->tv_nsec = nsec;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(set_normalized_timespec64);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ns_to_timespec64 - Convert nanoseconds to timespec64
|
||||||
|
* @nsec: the nanoseconds value to be converted
|
||||||
|
*
|
||||||
|
* Returns the timespec64 representation of the nsec parameter.
|
||||||
|
*/
|
||||||
|
struct timespec64 ns_to_timespec64(const s64 nsec)
|
||||||
|
{
|
||||||
|
struct timespec64 ts;
|
||||||
|
s32 rem;
|
||||||
|
|
||||||
|
if (!nsec)
|
||||||
|
return (struct timespec64) {0, 0};
|
||||||
|
|
||||||
|
ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
|
||||||
|
if (unlikely(rem < 0)) {
|
||||||
|
ts.tv_sec--;
|
||||||
|
rem += NSEC_PER_SEC;
|
||||||
|
}
|
||||||
|
ts.tv_nsec = rem;
|
||||||
|
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ns_to_timespec64);
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* When we convert to jiffies then we interpret incoming values
|
* When we convert to jiffies then we interpret incoming values
|
||||||
* the following way:
|
* the following way:
|
||||||
|
|
Loading…
Reference in a new issue