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 ts;
|
||||
struct timespec64 ts = { 0, 0 };
|
||||
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;
|
||||
if (likely(nsec > 0)) {
|
||||
ts.tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
|
||||
ts.tv_nsec = rem;
|
||||
} else if (nsec < 0) {
|
||||
/*
|
||||
* With negative times, tv_sec points to the earlier
|
||||
* 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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue