From 1aeb272cf09f9e2cbc62163b9f37a9b4d1c7e81d Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Tue, 29 Apr 2008 00:59:25 -0700 Subject: kernel: explicitly include required header files under kernel/ Following an experimental deletion of the unnecessary directive #include from the header file , these files under kernel/ were exposed as needing to include one of or , so explicit includes were added where necessary. Signed-off-by: Robert P. J. Day Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/time.c | 1 + 1 file changed, 1 insertion(+) (limited to 'kernel/time.c') diff --git a/kernel/time.c b/kernel/time.c index 35d373a98782..86729042e4cd 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From 71abb3af62dfa52930755f3b6497eafbe1d6ec85 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 1 May 2008 04:34:26 -0700 Subject: convert a few do_div users This converts a few users of do_div to div_[su]64 and this demonstrates nicely how it can reduce some expressions to one-liners. Signed-off-by: Roman Zippel Cc: john stultz Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/time.c | 29 +++++++++-------------------- kernel/time/ntp.c | 25 ++++++------------------- 2 files changed, 15 insertions(+), 39 deletions(-) (limited to 'kernel/time.c') diff --git a/kernel/time.c b/kernel/time.c index 86729042e4cd..343e2515375a 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -587,9 +588,7 @@ clock_t jiffies_to_clock_t(long x) return x / (HZ / USER_HZ); # endif #else - u64 tmp = (u64)x * TICK_NSEC; - do_div(tmp, (NSEC_PER_SEC / USER_HZ)); - return (long)tmp; + return div_u64((u64)x * TICK_NSEC, NSEC_PER_SEC / USER_HZ); #endif } EXPORT_SYMBOL(jiffies_to_clock_t); @@ -601,16 +600,12 @@ unsigned long clock_t_to_jiffies(unsigned long x) return ~0UL; return x * (HZ / USER_HZ); #else - u64 jif; - /* Don't worry about loss of precision here .. */ if (x >= ~0UL / HZ * USER_HZ) return ~0UL; /* .. but do try to contain it here */ - jif = x * (u64) HZ; - do_div(jif, USER_HZ); - return jif; + return div_u64((u64)x * HZ, USER_HZ); #endif } EXPORT_SYMBOL(clock_t_to_jiffies); @@ -619,10 +614,9 @@ u64 jiffies_64_to_clock_t(u64 x) { #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 # if HZ < USER_HZ - x *= USER_HZ; - do_div(x, HZ); + x = div_u64(x * USER_HZ, HZ); # elif HZ > USER_HZ - do_div(x, HZ / USER_HZ); + x = div_u64(x, HZ / USER_HZ); # else /* Nothing to do */ # endif @@ -632,8 +626,7 @@ u64 jiffies_64_to_clock_t(u64 x) * but even this doesn't overflow in hundreds of years * in 64 bits, so.. */ - x *= TICK_NSEC; - do_div(x, (NSEC_PER_SEC / USER_HZ)); + x = div_u64(x * TICK_NSEC, (NSEC_PER_SEC / USER_HZ)); #endif return x; } @@ -642,21 +635,17 @@ EXPORT_SYMBOL(jiffies_64_to_clock_t); u64 nsec_to_clock_t(u64 x) { #if (NSEC_PER_SEC % USER_HZ) == 0 - do_div(x, (NSEC_PER_SEC / USER_HZ)); + return div_u64(x, NSEC_PER_SEC / USER_HZ); #elif (USER_HZ % 512) == 0 - x *= USER_HZ/512; - do_div(x, (NSEC_PER_SEC / 512)); + return div_u64(x * USER_HZ / 512, NSEC_PER_SEC / 512); #else /* * max relative error 5.7e-8 (1.8s per year) for USER_HZ <= 1024, * overflow after 64.99 years. * exact for HZ=60, 72, 90, 120, 144, 180, 300, 600, 900, ... */ - x *= 9; - do_div(x, (unsigned long)((9ull * NSEC_PER_SEC + (USER_HZ/2)) / - USER_HZ)); + return div_u64(x * 9, (9ull * NSEC_PER_SEC + (USER_HZ / 2)) / USER_HZ); #endif - return x; } #if (BITS_PER_LONG < 64) diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 5fd9b9469770..a4492f3d64db 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include /* @@ -53,10 +53,8 @@ static void ntp_update_frequency(void) tick_length_base = second_length; - do_div(second_length, HZ); - tick_nsec = second_length >> TICK_LENGTH_SHIFT; - - do_div(tick_length_base, NTP_INTERVAL_FREQ); + tick_nsec = div_u64(second_length, HZ) >> TICK_LENGTH_SHIFT; + tick_length_base = div_u64(tick_length_base, NTP_INTERVAL_FREQ); } /** @@ -237,7 +235,7 @@ static inline void notify_cmos_timer(void) { } int do_adjtimex(struct timex *txc) { long mtemp, save_adjust, rem; - s64 freq_adj, temp64; + s64 freq_adj; int result; /* In order to modify anything, you gotta be super-user! */ @@ -342,19 +340,8 @@ int do_adjtimex(struct timex *txc) freq_adj = time_offset * mtemp; freq_adj = shift_right(freq_adj, time_constant * 2 + (SHIFT_PLL + 2) * 2 - SHIFT_NSEC); - if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) { - u64 utemp64; - temp64 = time_offset << (SHIFT_NSEC - SHIFT_FLL); - if (time_offset < 0) { - utemp64 = -temp64; - do_div(utemp64, mtemp); - freq_adj -= utemp64; - } else { - utemp64 = temp64; - do_div(utemp64, mtemp); - freq_adj += utemp64; - } - } + if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) + freq_adj += div_s64(time_offset << (SHIFT_NSEC - SHIFT_FLL), mtemp); freq_adj += time_freq; freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC); time_freq = max(freq_adj, (s64)-MAXFREQ_NSEC); -- cgit v1.2.3 From f8bd2258e2d520dff28c855658bd24bdafb5102d Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 1 May 2008 04:34:31 -0700 Subject: remove div_long_long_rem x86 is the only arch right now, which provides an optimized for div_long_long_rem and it has the downside that one has to be very careful that the divide doesn't overflow. The API is a little akward, as the arguments for the unsigned divide are signed. The signed version also doesn't handle a negative divisor and produces worse code on 64bit archs. There is little incentive to keep this API alive, so this converts the few users to the new API. Signed-off-by: Roman Zippel Cc: Ralf Baechle Cc: Ingo Molnar Cc: Thomas Gleixner Cc: john stultz Cc: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/kernel/binfmt_elfn32.c | 5 ++-- arch/mips/kernel/binfmt_elfo32.c | 5 ++-- drivers/char/mmtimer.c | 24 +++++++++----------- include/asm-x86/div64.h | 18 --------------- include/linux/calc64.h | 49 ---------------------------------------- include/linux/jiffies.h | 2 +- kernel/posix-cpu-timers.c | 11 ++++----- kernel/time.c | 25 ++++++++++++-------- kernel/time/ntp.c | 6 ++--- mm/slub.c | 9 ++++---- 10 files changed, 44 insertions(+), 110 deletions(-) delete mode 100644 include/linux/calc64.h (limited to 'kernel/time.c') diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c index 77db3473deab..9fdd8bcdd21e 100644 --- a/arch/mips/kernel/binfmt_elfn32.c +++ b/arch/mips/kernel/binfmt_elfn32.c @@ -54,6 +54,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; #include #include #include +#include #define elf_prstatus elf_prstatus32 struct elf_prstatus32 @@ -102,8 +103,8 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) * one divide. */ u64 nsec = (u64)jiffies * TICK_NSEC; - long rem; - value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &rem); + u32 rem; + value->tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem); value->tv_usec = rem / NSEC_PER_USEC; } diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index 08f4cd781ee3..e1333d7319e2 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c @@ -56,6 +56,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; #include #include #include +#include #define elf_prstatus elf_prstatus32 struct elf_prstatus32 @@ -104,8 +105,8 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) * one divide. */ u64 nsec = (u64)jiffies * TICK_NSEC; - long rem; - value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &rem); + u32 rem; + value->tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem); value->tv_usec = rem / NSEC_PER_USEC; } diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index d83db5d880e0..192961fd7173 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include @@ -472,8 +474,8 @@ static int sgi_clock_get(clockid_t clockid, struct timespec *tp) nsec = rtc_time() * sgi_clock_period + sgi_clock_offset.tv_nsec; - tp->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tp->tv_nsec) - + sgi_clock_offset.tv_sec; + *tp = ns_to_timespec(nsec); + tp->tv_sec += sgi_clock_offset.tv_sec; return 0; }; @@ -481,11 +483,11 @@ static int sgi_clock_set(clockid_t clockid, struct timespec *tp) { u64 nsec; - u64 rem; + u32 rem; nsec = rtc_time() * sgi_clock_period; - sgi_clock_offset.tv_sec = tp->tv_sec - div_long_long_rem(nsec, NSEC_PER_SEC, &rem); + sgi_clock_offset.tv_sec = tp->tv_sec - div_u64_rem(nsec, NSEC_PER_SEC, &rem); if (rem <= tp->tv_nsec) sgi_clock_offset.tv_nsec = tp->tv_sec - rem; @@ -644,9 +646,6 @@ static int sgi_timer_del(struct k_itimer *timr) return 0; } -#define timespec_to_ns(x) ((x).tv_nsec + (x).tv_sec * NSEC_PER_SEC) -#define ns_to_timespec(ts, nsec) (ts).tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &(ts).tv_nsec) - /* Assumption: it_lock is already held with irq's disabled */ static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) { @@ -659,9 +658,8 @@ static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) return; } - ns_to_timespec(cur_setting->it_interval, timr->it.mmtimer.incr * sgi_clock_period); - ns_to_timespec(cur_setting->it_value, (timr->it.mmtimer.expires - rtc_time())* sgi_clock_period); - return; + cur_setting->it_interval = ns_to_timespec(timr->it.mmtimer.incr * sgi_clock_period); + cur_setting->it_value = ns_to_timespec((timr->it.mmtimer.expires - rtc_time()) * sgi_clock_period); } @@ -679,8 +677,8 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, sgi_timer_get(timr, old_setting); sgi_timer_del(timr); - when = timespec_to_ns(new_setting->it_value); - period = timespec_to_ns(new_setting->it_interval); + when = timespec_to_ns(&new_setting->it_value); + period = timespec_to_ns(&new_setting->it_interval); if (when == 0) /* Clear timer */ @@ -695,7 +693,7 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, unsigned long now; getnstimeofday(&n); - now = timespec_to_ns(n); + now = timespec_to_ns(&n); if (when > now) when -= now; else diff --git a/include/asm-x86/div64.h b/include/asm-x86/div64.h index 32fdbddaae55..9a2d644c08ef 100644 --- a/include/asm-x86/div64.h +++ b/include/asm-x86/div64.h @@ -33,24 +33,6 @@ __mod; \ }) -/* - * (long)X = ((long long)divs) / (long)div - * (long)rem = ((long long)divs) % (long)div - * - * Warning, this will do an exception if X overflows. - */ -#define div_long_long_rem(a, b, c) div_ll_X_l_rem(a, b, c) - -static inline long div_ll_X_l_rem(long long divs, long div, long *rem) -{ - long dum2; - asm("divl %2":"=a"(dum2), "=d"(*rem) - : "rm"(div), "A"(divs)); - - return dum2; - -} - static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) { union { diff --git a/include/linux/calc64.h b/include/linux/calc64.h deleted file mode 100644 index ebf4b8f38d88..000000000000 --- a/include/linux/calc64.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _LINUX_CALC64_H -#define _LINUX_CALC64_H - -#include -#include - -/* - * This is a generic macro which is used when the architecture - * specific div64.h does not provide a optimized one. - * - * The 64bit dividend is divided by the divisor (data type long), the - * result is returned and the remainder stored in the variable - * referenced by remainder (data type long *). In contrast to the - * do_div macro the dividend is kept intact. - */ -#ifndef div_long_long_rem -#define div_long_long_rem(dividend, divisor, remainder) \ - do_div_llr((dividend), divisor, remainder) - -static inline unsigned long do_div_llr(const long long dividend, - const long divisor, long *remainder) -{ - u64 result = dividend; - - *(remainder) = do_div(result, divisor); - return (unsigned long) result; -} -#endif - -/* - * Sign aware variation of the above. On some architectures a - * negative dividend leads to an divide overflow exception, which - * is avoided by the sign check. - */ -static inline long div_long_long_rem_signed(const long long dividend, - const long divisor, long *remainder) -{ - long res; - - if (unlikely(dividend < 0)) { - res = -div_long_long_rem(-dividend, divisor, remainder); - *remainder = -(*remainder); - } else - res = div_long_long_rem(dividend, divisor, remainder); - - return res; -} - -#endif diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index 33ef710dac24..abb6ac639e8e 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h @@ -1,7 +1,7 @@ #ifndef _LINUX_JIFFIES_H #define _LINUX_JIFFIES_H -#include +#include #include #include #include diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index ae5c6c147c4b..f1525ad06cb3 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -4,8 +4,9 @@ #include #include -#include #include +#include +#include static int check_clock(const clockid_t which_clock) { @@ -47,12 +48,10 @@ static void sample_to_timespec(const clockid_t which_clock, union cpu_time_count cpu, struct timespec *tp) { - if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) { - tp->tv_sec = div_long_long_rem(cpu.sched, - NSEC_PER_SEC, &tp->tv_nsec); - } else { + if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) + *tp = ns_to_timespec(cpu.sched); + else cputime_to_timespec(cpu.cpu, tp); - } } static inline int cpu_time_before(const clockid_t which_clock, diff --git a/kernel/time.c b/kernel/time.c index 343e2515375a..cbe0d5a222ff 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -392,13 +392,17 @@ EXPORT_SYMBOL(set_normalized_timespec); struct timespec ns_to_timespec(const s64 nsec) { struct timespec ts; + s32 rem; if (!nsec) return (struct timespec) {0, 0}; - ts.tv_sec = div_long_long_rem_signed(nsec, NSEC_PER_SEC, &ts.tv_nsec); - if (unlikely(nsec < 0)) - set_normalized_timespec(&ts, ts.tv_sec, ts.tv_nsec); + 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; } @@ -528,8 +532,10 @@ jiffies_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); + u32 rem; + value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC, + NSEC_PER_SEC, &rem); + value->tv_nsec = rem; } EXPORT_SYMBOL(jiffies_to_timespec); @@ -567,12 +573,11 @@ void jiffies_to_timeval(const unsigned long jiffies, struct timeval *value) * Convert jiffies to nanoseconds and separate with * one divide. */ - u64 nsec = (u64)jiffies * TICK_NSEC; - long tv_usec; + u32 rem; - value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tv_usec); - tv_usec /= NSEC_PER_USEC; - value->tv_usec = tv_usec; + value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC, + NSEC_PER_SEC, &rem); + value->tv_usec = rem / NSEC_PER_USEC; } EXPORT_SYMBOL(jiffies_to_timeval); diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index a4492f3d64db..dbd6f8905614 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -234,7 +234,7 @@ static inline void notify_cmos_timer(void) { } */ int do_adjtimex(struct timex *txc) { - long mtemp, save_adjust, rem; + long mtemp, save_adjust; s64 freq_adj; int result; @@ -345,9 +345,7 @@ int do_adjtimex(struct timex *txc) freq_adj += time_freq; freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC); time_freq = max(freq_adj, (s64)-MAXFREQ_NSEC); - time_offset = div_long_long_rem_signed(time_offset, - NTP_INTERVAL_FREQ, - &rem); + time_offset = div_s64(time_offset, NTP_INTERVAL_FREQ); time_offset <<= SHIFT_UPDATE; } /* STA_PLL */ } /* txc->modes & ADJ_OFFSET */ diff --git a/mm/slub.c b/mm/slub.c index 70db2897c1ea..32b62623846a 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -22,6 +22,7 @@ #include #include #include +#include /* * Lock order: @@ -3621,12 +3622,10 @@ static int list_locations(struct kmem_cache *s, char *buf, len += sprintf(buf + len, ""); if (l->sum_time != l->min_time) { - unsigned long remainder; - len += sprintf(buf + len, " age=%ld/%ld/%ld", - l->min_time, - div_long_long_rem(l->sum_time, l->count, &remainder), - l->max_time); + l->min_time, + (long)div_u64(l->sum_time, l->count), + l->max_time); } else len += sprintf(buf + len, " age=%ld", l->min_time); -- cgit v1.2.3 From b9095fd8a7f41dc7ac0b0b7864f74766a3056f96 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 2 May 2008 16:18:42 -0700 Subject: Make constants in kernel/timeconst.h fixed 64 bits Force constants in kernel/timeconst.h (except shift counts) to be 64 bits, using U64_C() constructor macros, and eliminate constants that cannot be represented at all in 64 bits. This avoids warnings with some gcc versions. Drop generating 64-bit constants, since we have no real hope of getting a full set (operation on 64-bit values requires a 128-bit intermediate result, which gcc only supports on 64-bit platforms, and only with libgcc support on some.) Note that the use of these constants does not depend on if we are on a 32- or 64-bit architecture. This resolves Bugzilla 10153. Signed-off-by: H. Peter Anvin --- kernel/time.c | 8 ++-- kernel/timeconst.pl | 120 +++++++++++++++++++++------------------------------- 2 files changed, 52 insertions(+), 76 deletions(-) (limited to 'kernel/time.c') diff --git a/kernel/time.c b/kernel/time.c index cbe0d5a222ff..6a08660b4fac 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -246,7 +246,7 @@ unsigned int inline jiffies_to_msecs(const unsigned long j) return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC); #else # if BITS_PER_LONG == 32 - return ((u64)HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32; + return (HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32; # else return (j * HZ_TO_MSEC_NUM) / HZ_TO_MSEC_DEN; # endif @@ -262,7 +262,7 @@ unsigned int inline jiffies_to_usecs(const unsigned long j) return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC); #else # if BITS_PER_LONG == 32 - return ((u64)HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32; + return (HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32; # else return (j * HZ_TO_USEC_NUM) / HZ_TO_USEC_DEN; # endif @@ -476,7 +476,7 @@ unsigned long msecs_to_jiffies(const unsigned int m) if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) return MAX_JIFFY_OFFSET; - return ((u64)MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32) + return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32) >> MSEC_TO_HZ_SHR32; #endif } @@ -491,7 +491,7 @@ unsigned long usecs_to_jiffies(const unsigned int u) #elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC) return u * (HZ / USEC_PER_SEC); #else - return ((u64)USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32) + return (USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32) >> USEC_TO_HZ_SHR32; #endif } diff --git a/kernel/timeconst.pl b/kernel/timeconst.pl index 41468035473c..eb51d76e058a 100644 --- a/kernel/timeconst.pl +++ b/kernel/timeconst.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl # ----------------------------------------------------------------------- # -# Copyright 2007 rPath, Inc. - All Rights Reserved +# Copyright 2007-2008 rPath, Inc. - All Rights Reserved # # This file is part of the Linux kernel, and is made available under # the terms of the GNU General Public License version 2 or (at your @@ -20,198 +20,138 @@ %canned_values = ( 24 => [ '0xa6aaaaab','0x2aaaaaa',26, - '0xa6aaaaaaaaaaaaab','0x2aaaaaaaaaaaaaa',58, 125,3, '0xc49ba5e4','0x1fbe76c8b4',37, - '0xc49ba5e353f7ceda','0x1fbe76c8b439581062',69, 3,125, '0xa2c2aaab','0xaaaa',16, - '0xa2c2aaaaaaaaaaab','0xaaaaaaaaaaaa',48, 125000,3, '0xc9539b89','0x7fffbce4217d',47, - '0xc9539b8887229e91','0x7fffbce4217d2849cb25',79, 3,125000, ], 32 => [ '0xfa000000','0x6000000',27, - '0xfa00000000000000','0x600000000000000',59, 125,4, '0x83126e98','0xfdf3b645a',36, - '0x83126e978d4fdf3c','0xfdf3b645a1cac0831',68, 4,125, '0xf4240000','0x0',17, - '0xf424000000000000','0x0',49, 31250,1, '0x8637bd06','0x3fff79c842fa',46, - '0x8637bd05af6c69b6','0x3fff79c842fa5093964a',78, 1,31250, ], 48 => [ '0xa6aaaaab','0x6aaaaaa',27, - '0xa6aaaaaaaaaaaaab','0x6aaaaaaaaaaaaaa',59, 125,6, '0xc49ba5e4','0xfdf3b645a',36, - '0xc49ba5e353f7ceda','0xfdf3b645a1cac0831',68, 6,125, '0xa2c2aaab','0x15555',17, - '0xa2c2aaaaaaaaaaab','0x1555555555555',49, 62500,3, '0xc9539b89','0x3fffbce4217d',46, - '0xc9539b8887229e91','0x3fffbce4217d2849cb25',78, 3,62500, ], 64 => [ '0xfa000000','0xe000000',28, - '0xfa00000000000000','0xe00000000000000',60, 125,8, '0x83126e98','0x7ef9db22d',35, - '0x83126e978d4fdf3c','0x7ef9db22d0e560418',67, 8,125, '0xf4240000','0x0',18, - '0xf424000000000000','0x0',50, 15625,1, '0x8637bd06','0x1fff79c842fa',45, - '0x8637bd05af6c69b6','0x1fff79c842fa5093964a',77, 1,15625, ], 100 => [ '0xa0000000','0x0',28, - '0xa000000000000000','0x0',60, 10,1, '0xcccccccd','0x733333333',35, - '0xcccccccccccccccd','0x73333333333333333',67, 1,10, '0x9c400000','0x0',18, - '0x9c40000000000000','0x0',50, 10000,1, '0xd1b71759','0x1fff2e48e8a7',45, - '0xd1b71758e219652c','0x1fff2e48e8a71de69ad4',77, 1,10000, ], 122 => [ '0x8325c53f','0xfbcda3a',28, - '0x8325c53ef368eb05','0xfbcda3ac10c9714',60, 500,61, '0xf9db22d1','0x7fbe76c8b',35, - '0xf9db22d0e560418a','0x7fbe76c8b43958106',67, 61,500, '0x8012e2a0','0x3ef36',18, - '0x8012e29f79b47583','0x3ef368eb04325',50, 500000,61, '0xffda4053','0x1ffffbce4217',45, - '0xffda4052d666a983','0x1ffffbce4217d2849cb2',77, 61,500000, ], 128 => [ '0xfa000000','0x1e000000',29, - '0xfa00000000000000','0x1e00000000000000',61, 125,16, '0x83126e98','0x3f7ced916',34, - '0x83126e978d4fdf3c','0x3f7ced916872b020c',66, 16,125, '0xf4240000','0x40000',19, - '0xf424000000000000','0x4000000000000',51, 15625,2, '0x8637bd06','0xfffbce4217d',44, - '0x8637bd05af6c69b6','0xfffbce4217d2849cb25',76, 2,15625, ], 200 => [ '0xa0000000','0x0',29, - '0xa000000000000000','0x0',61, 5,1, '0xcccccccd','0x333333333',34, - '0xcccccccccccccccd','0x33333333333333333',66, 1,5, '0x9c400000','0x0',19, - '0x9c40000000000000','0x0',51, 5000,1, '0xd1b71759','0xfff2e48e8a7',44, - '0xd1b71758e219652c','0xfff2e48e8a71de69ad4',76, 1,5000, ], 250 => [ '0x80000000','0x0',29, - '0x8000000000000000','0x0',61, 4,1, '0x80000000','0x180000000',33, - '0x8000000000000000','0x18000000000000000',65, 1,4, '0xfa000000','0x0',20, - '0xfa00000000000000','0x0',52, 4000,1, '0x83126e98','0x7ff7ced9168',43, - '0x83126e978d4fdf3c','0x7ff7ced916872b020c4',75, 1,4000, ], 256 => [ '0xfa000000','0x3e000000',30, - '0xfa00000000000000','0x3e00000000000000',62, 125,32, '0x83126e98','0x1fbe76c8b',33, - '0x83126e978d4fdf3c','0x1fbe76c8b43958106',65, 32,125, '0xf4240000','0xc0000',20, - '0xf424000000000000','0xc000000000000',52, 15625,4, '0x8637bd06','0x7ffde7210be',43, - '0x8637bd05af6c69b6','0x7ffde7210be9424e592',75, 4,15625, ], 300 => [ '0xd5555556','0x2aaaaaaa',30, - '0xd555555555555556','0x2aaaaaaaaaaaaaaa',62, 10,3, '0x9999999a','0x1cccccccc',33, - '0x999999999999999a','0x1cccccccccccccccc',65, 3,10, '0xd0555556','0xaaaaa',20, - '0xd055555555555556','0xaaaaaaaaaaaaa',52, 10000,3, '0x9d495183','0x7ffcb923a29',43, - '0x9d495182a9930be1','0x7ffcb923a29c779a6b5',75, 3,10000, ], 512 => [ '0xfa000000','0x7e000000',31, - '0xfa00000000000000','0x7e00000000000000',63, 125,64, '0x83126e98','0xfdf3b645',32, - '0x83126e978d4fdf3c','0xfdf3b645a1cac083',64, 64,125, '0xf4240000','0x1c0000',21, - '0xf424000000000000','0x1c000000000000',53, 15625,8, '0x8637bd06','0x3ffef39085f',42, - '0x8637bd05af6c69b6','0x3ffef39085f4a1272c9',74, 8,15625, ], 1000 => [ '0x80000000','0x0',31, - '0x8000000000000000','0x0',63, 1,1, '0x80000000','0x0',31, - '0x8000000000000000','0x0',63, 1,1, '0xfa000000','0x0',22, - '0xfa00000000000000','0x0',54, 1000,1, '0x83126e98','0x1ff7ced9168',41, - '0x83126e978d4fdf3c','0x1ff7ced916872b020c4',73, 1,1000, ], 1024 => [ '0xfa000000','0xfe000000',32, - '0xfa00000000000000','0xfe00000000000000',64, 125,128, '0x83126e98','0x7ef9db22',31, - '0x83126e978d4fdf3c','0x7ef9db22d0e56041',63, 128,125, '0xf4240000','0x3c0000',22, - '0xf424000000000000','0x3c000000000000',54, 15625,16, '0x8637bd06','0x1fff79c842f',41, - '0x8637bd05af6c69b6','0x1fff79c842fa5093964',73, 16,15625, ], 1200 => [ '0xd5555556','0xd5555555',32, - '0xd555555555555556','0xd555555555555555',64, 5,6, '0x9999999a','0x66666666',31, - '0x999999999999999a','0x6666666666666666',63, 6,5, '0xd0555556','0x2aaaaa',22, - '0xd055555555555556','0x2aaaaaaaaaaaaa',54, 2500,3, '0x9d495183','0x1ffcb923a29',41, - '0x9d495182a9930be1','0x1ffcb923a29c779a6b5',73, 3,2500, ] ); @@ -264,6 +204,15 @@ sub fmuls($$$) { return 0; } +# Generate a hex value if the result fits in 64 bits; +# otherwise skip. +sub bignum_hex($) { + my($x) = @_; + my $s = $x->as_hex(); + + return (length($s) > 18) ? undef : $s; +} + # Provides mul, adj, and shr factors for a specific # (bit, time, hz) combination sub muladj($$$) { @@ -271,7 +220,7 @@ sub muladj($$$) { my $s = fmuls($b, $t, $hz); my $m = fmul($s, $t, $hz); my $a = fadj($s, $t, $hz); - return ($m->as_hex(), $a->as_hex(), $s); + return (bignum_hex($m), bignum_hex($a), $s); } # Provides numerator, denominator values @@ -288,12 +237,10 @@ sub conversions($$) { # HZ_TO_xx push(@val, muladj(32, $t, $hz)); - push(@val, muladj(64, $t, $hz)); push(@val, numden($t, $hz)); # xx_TO_HZ push(@val, muladj(32, $hz, $t)); - push(@val, muladj(64, $hz, $t)); push(@val, numden($hz, $t)); return @val; @@ -318,6 +265,19 @@ sub compute_values($) { return @val; } +sub outputval($$) +{ + my($name, $val) = @_; + my $csuf; + + if (defined($val)) { + if ($name !~ /SHR/) { + $val = "U64_C($val)"; + } + printf "#define %-23s %s\n", $name.$csuf, $val.$csuf; + } +} + sub output($@) { my($hz, @val) = @_; @@ -331,6 +291,7 @@ sub output($@) print "\n"; print "#include \n"; + print "#include \n"; print "\n"; print "#if HZ != $hz\n"; @@ -340,15 +301,13 @@ sub output($@) foreach $pfx ('HZ_TO_MSEC','MSEC_TO_HZ', 'HZ_TO_USEC','USEC_TO_HZ') { - foreach $bit (32, 64) { + foreach $bit (32) { foreach $suf ('MUL', 'ADJ', 'SHR') { - printf "#define %-23s %s\n", - "${pfx}_$suf$bit", shift(@val); + outputval("${pfx}_$suf$bit", shift(@val)); } } foreach $suf ('NUM', 'DEN') { - printf "#define %-23s %s\n", - "${pfx}_$suf", shift(@val); + outputval("${pfx}_$suf", shift(@val)); } } @@ -356,6 +315,23 @@ sub output($@) print "#endif /* KERNEL_TIMECONST_H */\n"; } +# Pretty-print Perl values +sub perlvals(@) { + my $v; + my @l = (); + + foreach $v (@_) { + if (!defined($v)) { + push(@l, 'undef'); + } elsif ($v =~ /^0x/) { + push(@l, "\'".$v."\'"); + } else { + push(@l, $v.''); + } + } + return join(',', @l); +} + ($hz) = @ARGV; # Use this to generate the %canned_values structure @@ -373,15 +349,15 @@ if ($hz eq '--can') { print "$pf$hz => [\n"; while (scalar(@values)) { my $bit; - foreach $bit (32, 64) { + foreach $bit (32) { my $m = shift(@values); my $a = shift(@values); my $s = shift(@values); - print "\t\t\'",$m,"\',\'",$a,"\',",$s,",\n"; + print "\t\t", perlvals($m,$a,$s), ",\n"; } my $n = shift(@values); my $d = shift(@values); - print "\t\t",$n,',',$d,",\n"; + print "\t\t", perlvals($n,$d), ",\n"; } print "\t]"; $pf = ', '; -- cgit v1.2.3