1 diff -ruN linux-2.6.30/kernel/Makefile linux-2.6.30.new/kernel/Makefile
2 --- linux-2.6.30/kernel/Makefile 2009-06-09 22:05:27.000000000 -0500
3 +++ linux-2.6.30.new/kernel/Makefile 2009-06-22 14:29:16.000000000 -0500
5 $(obj)/time.o: $(obj)/timeconst.h
7 quiet_cmd_timeconst = TIMEC $@
8 - cmd_timeconst = $(PERL) $< $(CONFIG_HZ) > $@
9 + cmd_timeconst = $(CONFIG_SHELL) $< $(CONFIG_HZ) $@
10 targets += timeconst.h
11 -$(obj)/timeconst.h: $(src)/timeconst.pl FORCE
12 +$(obj)/timeconst.h: $(src)/timeconst.sh FORCE
13 $(call if_changed,timeconst)
14 diff -ruN linux-2.6.30/kernel/timeconst.pl linux-2.6.30.new/kernel/timeconst.pl
15 --- linux-2.6.30/kernel/timeconst.pl 2009-06-09 22:05:27.000000000 -0500
16 +++ linux-2.6.30.new/kernel/timeconst.pl 1969-12-31 18:00:00.000000000 -0600
19 -# -----------------------------------------------------------------------
21 -# Copyright 2007-2008 rPath, Inc. - All Rights Reserved
23 -# This file is part of the Linux kernel, and is made available under
24 -# the terms of the GNU General Public License version 2 or (at your
25 -# option) any later version; incorporated herein by reference.
27 -# -----------------------------------------------------------------------
31 -# Usage: timeconst.pl HZ > timeconst.h
34 -# Precomputed values for systems without Math::BigInt
36 -# timeconst.pl --can 24 32 48 64 100 122 128 200 250 256 300 512 1000 1024 1200
39 - '0xa6aaaaab','0x2aaaaaa',26,
41 - '0xc49ba5e4','0x1fbe76c8b4',37,
43 - '0xa2c2aaab','0xaaaa',16,
45 - '0xc9539b89','0x7fffbce4217d',47,
48 - '0xfa000000','0x6000000',27,
50 - '0x83126e98','0xfdf3b645a',36,
52 - '0xf4240000','0x0',17,
54 - '0x8637bd06','0x3fff79c842fa',46,
57 - '0xa6aaaaab','0x6aaaaaa',27,
59 - '0xc49ba5e4','0xfdf3b645a',36,
61 - '0xa2c2aaab','0x15555',17,
63 - '0xc9539b89','0x3fffbce4217d',46,
66 - '0xfa000000','0xe000000',28,
68 - '0x83126e98','0x7ef9db22d',35,
70 - '0xf4240000','0x0',18,
72 - '0x8637bd06','0x1fff79c842fa',45,
75 - '0xa0000000','0x0',28,
77 - '0xcccccccd','0x733333333',35,
79 - '0x9c400000','0x0',18,
81 - '0xd1b71759','0x1fff2e48e8a7',45,
84 - '0x8325c53f','0xfbcda3a',28,
86 - '0xf9db22d1','0x7fbe76c8b',35,
88 - '0x8012e2a0','0x3ef36',18,
90 - '0xffda4053','0x1ffffbce4217',45,
93 - '0xfa000000','0x1e000000',29,
95 - '0x83126e98','0x3f7ced916',34,
97 - '0xf4240000','0x40000',19,
99 - '0x8637bd06','0xfffbce4217d',44,
102 - '0xa0000000','0x0',29,
104 - '0xcccccccd','0x333333333',34,
106 - '0x9c400000','0x0',19,
108 - '0xd1b71759','0xfff2e48e8a7',44,
111 - '0x80000000','0x0',29,
113 - '0x80000000','0x180000000',33,
115 - '0xfa000000','0x0',20,
117 - '0x83126e98','0x7ff7ced9168',43,
120 - '0xfa000000','0x3e000000',30,
122 - '0x83126e98','0x1fbe76c8b',33,
124 - '0xf4240000','0xc0000',20,
126 - '0x8637bd06','0x7ffde7210be',43,
129 - '0xd5555556','0x2aaaaaaa',30,
131 - '0x9999999a','0x1cccccccc',33,
133 - '0xd0555556','0xaaaaa',20,
135 - '0x9d495183','0x7ffcb923a29',43,
138 - '0xfa000000','0x7e000000',31,
140 - '0x83126e98','0xfdf3b645',32,
142 - '0xf4240000','0x1c0000',21,
144 - '0x8637bd06','0x3ffef39085f',42,
147 - '0x80000000','0x0',31,
149 - '0x80000000','0x0',31,
151 - '0xfa000000','0x0',22,
153 - '0x83126e98','0x1ff7ced9168',41,
156 - '0xfa000000','0xfe000000',32,
158 - '0x83126e98','0x7ef9db22',31,
160 - '0xf4240000','0x3c0000',22,
162 - '0x8637bd06','0x1fff79c842f',41,
165 - '0xd5555556','0xd5555555',32,
167 - '0x9999999a','0x66666666',31,
169 - '0xd0555556','0x2aaaaa',22,
171 - '0x9d495183','0x1ffcb923a29',41,
176 -$has_bigint = eval 'use Math::BigInt qw(bgcd); 1;';
181 - return Math::BigInt->new($x);
185 -# Constants for division by reciprocal multiplication.
186 -# (bits, numerator, denominator)
190 - my ($b,$n,$d) = @_;
195 - return scalar (($n << $b)+$d-bint(1))/$d;
205 - $d = $d/bgcd($n, $d);
206 - return scalar (($d-bint(1)) << $b)/$d;
212 - my($thres) = bint(1) << ($b-1);
217 - for ($s = 0; 1; $s++) {
218 - $m = fmul($s,$n,$d);
219 - return $s if ($m >= $thres);
224 -# Generate a hex value if the result fits in 64 bits;
228 - my $s = $x->as_hex();
230 - return (length($s) > 18) ? undef : $s;
233 -# Provides mul, adj, and shr factors for a specific
234 -# (bit, time, hz) combination
236 - my($b, $t, $hz) = @_;
237 - my $s = fmuls($b, $t, $hz);
238 - my $m = fmul($s, $t, $hz);
239 - my $a = fadj($s, $t, $hz);
240 - return (bignum_hex($m), bignum_hex($a), $s);
243 -# Provides numerator, denominator values
246 - my $g = bgcd($n, $d);
247 - return ($n/$g, $d/$g);
250 -# All values for a specific (time, hz) combo
251 -sub conversions($$) {
256 - push(@val, muladj(32, $t, $hz));
257 - push(@val, numden($t, $hz));
260 - push(@val, muladj(32, $hz, $t));
261 - push(@val, numden($hz, $t));
266 -sub compute_values($) {
271 - if (!$has_bigint) {
272 - die "$0: HZ == $hz not canned and ".
273 - "Math::BigInt not available\n";
277 - push(@val, conversions(1000, $hz));
280 - push(@val, conversions(1000000, $hz));
287 - my($name, $val) = @_;
290 - if (defined($val)) {
291 - if ($name !~ /SHR/) {
292 - $val = "U64_C($val)";
294 - printf "#define %-23s %s\n", $name.$csuf, $val.$csuf;
300 - my($hz, @val) = @_;
301 - my $pfx, $bit, $suf, $s, $m, $a;
303 - print "/* Automatically generated by kernel/timeconst.pl */\n";
304 - print "/* Conversion constants for HZ == $hz */\n";
306 - print "#ifndef KERNEL_TIMECONST_H\n";
307 - print "#define KERNEL_TIMECONST_H\n";
310 - print "#include <linux/param.h>\n";
311 - print "#include <linux/types.h>\n";
314 - print "#if HZ != $hz\n";
315 - print "#error \"kernel/timeconst.h has the wrong HZ value!\"\n";
319 - foreach $pfx ('HZ_TO_MSEC','MSEC_TO_HZ',
320 - 'HZ_TO_USEC','USEC_TO_HZ') {
321 - foreach $bit (32) {
322 - foreach $suf ('MUL', 'ADJ', 'SHR') {
323 - outputval("${pfx}_$suf$bit", shift(@val));
326 - foreach $suf ('NUM', 'DEN') {
327 - outputval("${pfx}_$suf", shift(@val));
332 - print "#endif /* KERNEL_TIMECONST_H */\n";
335 -# Pretty-print Perl values
341 - if (!defined($v)) {
343 - } elsif ($v =~ /^0x/) {
344 - push(@l, "\'".$v."\'");
349 - return join(',', @l);
354 -# Use this to generate the %canned_values structure
355 -if ($hz eq '--can') {
357 - @hzlist = sort {$a <=> $b} (@ARGV);
359 - print "# Precomputed values for systems without Math::BigInt\n";
360 - print "# Generated by:\n";
361 - print "# timeconst.pl --can ", join(' ', @hzlist), "\n";
362 - print "\%canned_values = (\n";
364 - foreach $hz (@hzlist) {
365 - my @values = compute_values($hz);
366 - print "$pf$hz => [\n";
367 - while (scalar(@values)) {
369 - foreach $bit (32) {
370 - my $m = shift(@values);
371 - my $a = shift(@values);
372 - my $s = shift(@values);
373 - print "\t\t", perlvals($m,$a,$s), ",\n";
375 - my $n = shift(@values);
376 - my $d = shift(@values);
377 - print "\t\t", perlvals($n,$d), ",\n";
384 - $hz += 0; # Force to number
386 - die "Usage: $0 HZ\n";
389 - @val = @{$canned_values{$hz}};
390 - if (!defined(@val)) {
391 - @val = compute_values($hz);
396 diff -ruN linux-2.6.30/kernel/timeconst.sh linux-2.6.30.new/kernel/timeconst.sh
397 --- linux-2.6.30/kernel/timeconst.sh 1969-12-31 18:00:00.000000000 -0600
398 +++ linux-2.6.30.new/kernel/timeconst.sh 2009-06-22 14:29:16.000000000 -0500
404 + echo "Usage: timeconst.sh HZ FILENAME"
406 + echo "Generate a header file with constants for coverting between"
407 + echo "decimal HZ timer ticks and milisecond or microsecond delays."
416 +# Sanity test: even the shell in Red Hat 9 (circa 2003) supported 64 bit math.
418 +if [ $((1 << 32)) -lt 0 ]
420 + echo "timeconst.sh needs a shell with 64 bit math, such as bash,"
421 + echo "busybox ash, or dash running on a 64 bit host."
425 +# If this script exits for any reason before this trap is removed,
426 +# delete the output file so a partial file won't confuse the build.
428 +trap "rm $FILENAME" EXIT
430 +# Output start of header file
432 +cat > $FILENAME << EOF || exit 1
433 +/* Automatically generated by kernel/timeconst.sh */
434 +/* Conversion constants for HZ == $HZ */
436 +#ifndef __KERNEL_TIMECONST_H
437 +#define __KERNEL_TIMECONST_H
439 +#include <linux/param.h>
440 +#include <linux/types.h>
443 +#error "kernel/timeconst.h has the wrong HZ value!"
448 +# For both Milliseconds and Microseconds
454 +while read NAME PERIOD
456 + # Find greatest common denominator (using Euclid's algorithm)
470 + # Do this for each direction (HZ_TO_PERIOD and PERIOD_TO_HZ)
472 + for DIRECTION in 0 1
474 + if [ $DIRECTION -eq 0 ]
476 + CONVERT="HZ_TO_${NAME}"
480 + CONVERT="${NAME}_TO_HZ"
485 + # Calculate 32 significant bits of MUL32 data.
490 + # This can't overflow 64 bit math. Pathological case
491 + # (TO=1, FROM=1000000) uses around 32+20=52 bits.
493 + MUL32=$(( ( ( $TO << $SHIFT ) + $FROM - 1 ) / $FROM ))
495 + # Keep increasing $SHIFT until we've got 32 bits.
497 + [ $MUL32 -gt $(( 1 << 31 )) ] && break
498 + SHIFT=$(( $SHIFT + 1 ))
500 + MUL32=$( printf %x $MUL32 )
502 + # ADJ32 is just (((FROM/GCD)-1)<<SHIFT)/(FROM/GCD) but this
503 + # can overflow 64 bit math (examples, HZ=24 or HZ=122).
504 + # Pathological case could use 32+20+20=72 bits. (And this is
505 + # the pathological case because a larger $HZ results in a
506 + # smaller $SHIFT, so even insane HZ>USEC cases should be ok.)
508 + # To get around this, we chop the bottom 32 bits off the
509 + # calculation and then reassemble it to avoid overflow:
510 + # 32+64=96, which is > 72.
512 + ADJ32=$(( $FROM / $GCD ))
513 + if [ $SHIFT -gt 32 ]
515 + UPPER=$(( ( $ADJ32 - 1 ) << ( $SHIFT - 32 ) ))
516 + LOWER=$(( ( $UPPER % $ADJ32 ) << 32 ))
517 + ADJ32=$(( ( ( $UPPER / $ADJ32 ) << 32 ) + ( $LOWER / $ADJ32 )))
519 + ADJ32=$(( ( ( $ADJ32 - 1 ) << $SHIFT) / $ADJ32 ))
521 + ADJ32=$( printf %x $ADJ32 )
523 + NUM=$(( $TO / $GCD ))
524 + DEN=$(( $FROM / $GCD ))
526 + # Output next chunk of header data to file
529 + echo "#define ${CONVERT}_MUL32 U64_C(0x$MUL32)" &&
530 + echo "#define ${CONVERT}_ADJ32 U64_C(0x$ADJ32)" &&
531 + echo "#define ${CONVERT}_SHR32 $SHIFT" &&
532 + echo "#define ${CONVERT}_NUM U64_C($NUM)" &&
533 + echo "#define ${CONVERT}_DEN U64_C($DEN)"
534 + ) >> $FILENAME || exit 1
540 + echo "#endif /* __KERNEL_TIMECHONST_H */"
541 +) >> $FILENAME || exit 1
543 +# Don't rm $FILENAME on exit anymore.