time: Optimize ns_to_timespec64()
ns_to_timespec64() calls div_s64_rem(), which is a rather slow function on 32-bit architectures, as it cannot take advantage of the do_div() optimizations for constant arguments. Open-code the div_s64_rem() function in ns_to_timespec64(), so a constant divider can be passed into the optimized div_u64_rem() function. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lkml.kernel.org/r/20191108203435.112759-3-arnd@arndb.de
This commit is contained in:
parent
56144737e6
commit
20d087368d
|
@ -550,18 +550,21 @@ EXPORT_SYMBOL(set_normalized_timespec64);
|
||||||
*/
|
*/
|
||||||
struct timespec64 ns_to_timespec64(const s64 nsec)
|
struct timespec64 ns_to_timespec64(const s64 nsec)
|
||||||
{
|
{
|
||||||
struct timespec64 ts;
|
struct timespec64 ts = { 0, 0 };
|
||||||
s32 rem;
|
s32 rem;
|
||||||
|
|
||||||
if (!nsec)
|
if (likely(nsec > 0)) {
|
||||||
return (struct timespec64) {0, 0};
|
ts.tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
|
||||||
|
ts.tv_nsec = rem;
|
||||||
ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
|
} else if (nsec < 0) {
|
||||||
if (unlikely(rem < 0)) {
|
/*
|
||||||
ts.tv_sec--;
|
* With negative times, tv_sec points to the earlier
|
||||||
rem += NSEC_PER_SEC;
|
* second, and tv_nsec counts the nanoseconds since
|
||||||
|
* then, so tv_nsec is always a positive number.
|
||||||
|
*/
|
||||||
|
ts.tv_sec = -div_u64_rem(-nsec - 1, NSEC_PER_SEC, &rem) - 1;
|
||||||
|
ts.tv_nsec = NSEC_PER_SEC - rem - 1;
|
||||||
}
|
}
|
||||||
ts.tv_nsec = rem;
|
|
||||||
|
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue