2
# -----------------------------------------------------------------------
4
# Copyright 2007-2008 rPath, Inc. - All Rights Reserved
6
# This file is part of the Linux kernel, and is made available under
7
# the terms of the GNU General Public License version 2 or (at your
8
# option) any later version; incorporated herein by reference.
10
# -----------------------------------------------------------------------
14
# Usage: timeconst.pl HZ > timeconst.h
17
# Precomputed values for systems without Math::BigInt
19
# timeconst.pl --can 24 32 48 64 100 122 128 200 250 256 300 512 1000 1024 1200
22
'0xa6aaaaab','0x2aaaaaa',26,
24
'0xc49ba5e4','0x1fbe76c8b4',37,
26
'0xa2c2aaab','0xaaaa',16,
28
'0xc9539b89','0x7fffbce4217d',47,
31
'0xfa000000','0x6000000',27,
33
'0x83126e98','0xfdf3b645a',36,
35
'0xf4240000','0x0',17,
37
'0x8637bd06','0x3fff79c842fa',46,
40
'0xa6aaaaab','0x6aaaaaa',27,
42
'0xc49ba5e4','0xfdf3b645a',36,
44
'0xa2c2aaab','0x15555',17,
46
'0xc9539b89','0x3fffbce4217d',46,
49
'0xfa000000','0xe000000',28,
51
'0x83126e98','0x7ef9db22d',35,
53
'0xf4240000','0x0',18,
55
'0x8637bd06','0x1fff79c842fa',45,
58
'0xa0000000','0x0',28,
60
'0xcccccccd','0x733333333',35,
62
'0x9c400000','0x0',18,
64
'0xd1b71759','0x1fff2e48e8a7',45,
67
'0x8325c53f','0xfbcda3a',28,
69
'0xf9db22d1','0x7fbe76c8b',35,
71
'0x8012e2a0','0x3ef36',18,
73
'0xffda4053','0x1ffffbce4217',45,
76
'0xfa000000','0x1e000000',29,
78
'0x83126e98','0x3f7ced916',34,
80
'0xf4240000','0x40000',19,
82
'0x8637bd06','0xfffbce4217d',44,
85
'0xa0000000','0x0',29,
87
'0xcccccccd','0x333333333',34,
89
'0x9c400000','0x0',19,
91
'0xd1b71759','0xfff2e48e8a7',44,
94
'0x80000000','0x0',29,
96
'0x80000000','0x180000000',33,
98
'0xfa000000','0x0',20,
100
'0x83126e98','0x7ff7ced9168',43,
103
'0xfa000000','0x3e000000',30,
105
'0x83126e98','0x1fbe76c8b',33,
107
'0xf4240000','0xc0000',20,
109
'0x8637bd06','0x7ffde7210be',43,
112
'0xd5555556','0x2aaaaaaa',30,
114
'0x9999999a','0x1cccccccc',33,
116
'0xd0555556','0xaaaaa',20,
118
'0x9d495183','0x7ffcb923a29',43,
121
'0xfa000000','0x7e000000',31,
123
'0x83126e98','0xfdf3b645',32,
125
'0xf4240000','0x1c0000',21,
127
'0x8637bd06','0x3ffef39085f',42,
130
'0x80000000','0x0',31,
132
'0x80000000','0x0',31,
134
'0xfa000000','0x0',22,
136
'0x83126e98','0x1ff7ced9168',41,
139
'0xfa000000','0xfe000000',32,
141
'0x83126e98','0x7ef9db22',31,
143
'0xf4240000','0x3c0000',22,
145
'0x8637bd06','0x1fff79c842f',41,
148
'0xd5555556','0xd5555555',32,
150
'0x9999999a','0x66666666',31,
152
'0xd0555556','0x2aaaaa',22,
154
'0x9d495183','0x1ffcb923a29',41,
159
$has_bigint = eval 'use Math::BigInt qw(bgcd); 1;';
164
return Math::BigInt->new($x);
168
# Constants for division by reciprocal multiplication.
169
# (bits, numerator, denominator)
178
return scalar (($n << $b)+$d-bint(1))/$d;
188
$d = $d/bgcd($n, $d);
189
return scalar (($d-bint(1)) << $b)/$d;
195
my($thres) = bint(1) << ($b-1);
200
for ($s = 0; 1; $s++) {
202
return $s if ($m >= $thres);
207
# Generate a hex value if the result fits in 64 bits;
211
my $s = $x->as_hex();
213
return (length($s) > 18) ? undef : $s;
216
# Provides mul, adj, and shr factors for a specific
217
# (bit, time, hz) combination
219
my($b, $t, $hz) = @_;
220
my $s = fmuls($b, $t, $hz);
221
my $m = fmul($s, $t, $hz);
222
my $a = fadj($s, $t, $hz);
223
return (bignum_hex($m), bignum_hex($a), $s);
226
# Provides numerator, denominator values
229
my $g = bgcd($n, $d);
230
return ($n/$g, $d/$g);
233
# All values for a specific (time, hz) combo
234
sub conversions($$) {
239
push(@val, muladj(32, $t, $hz));
240
push(@val, numden($t, $hz));
243
push(@val, muladj(32, $hz, $t));
244
push(@val, numden($hz, $t));
249
sub compute_values($) {
255
die "$0: HZ == $hz not canned and ".
256
"Math::BigInt not available\n";
260
push(@val, conversions(1000, $hz));
263
push(@val, conversions(1000000, $hz));
270
my($name, $val) = @_;
274
if ($name !~ /SHR/) {
275
$val = "U64_C($val)";
277
printf "#define %-23s %s\n", $name.$csuf, $val.$csuf;
284
my $pfx, $bit, $suf, $s, $m, $a;
286
print "/* Automatically generated by kernel/timeconst.pl */\n";
287
print "/* Conversion constants for HZ == $hz */\n";
289
print "#ifndef KERNEL_TIMECONST_H\n";
290
print "#define KERNEL_TIMECONST_H\n";
293
print "#include <linux/param.h>\n";
294
print "#include <linux/types.h>\n";
297
print "#if HZ != $hz\n";
298
print "#error \"kernel/timeconst.h has the wrong HZ value!\"\n";
302
foreach $pfx ('HZ_TO_MSEC','MSEC_TO_HZ',
303
'HZ_TO_USEC','USEC_TO_HZ') {
305
foreach $suf ('MUL', 'ADJ', 'SHR') {
306
outputval("${pfx}_$suf$bit", shift(@val));
309
foreach $suf ('NUM', 'DEN') {
310
outputval("${pfx}_$suf", shift(@val));
315
print "#endif /* KERNEL_TIMECONST_H */\n";
318
# Pretty-print Perl values
326
} elsif ($v =~ /^0x/) {
327
push(@l, "\'".$v."\'");
332
return join(',', @l);
337
# Use this to generate the %canned_values structure
338
if ($hz eq '--can') {
340
@hzlist = sort {$a <=> $b} (@ARGV);
342
print "# Precomputed values for systems without Math::BigInt\n";
343
print "# Generated by:\n";
344
print "# timeconst.pl --can ", join(' ', @hzlist), "\n";
345
print "\%canned_values = (\n";
347
foreach $hz (@hzlist) {
348
my @values = compute_values($hz);
349
print "$pf$hz => [\n";
350
while (scalar(@values)) {
353
my $m = shift(@values);
354
my $a = shift(@values);
355
my $s = shift(@values);
356
print "\t\t", perlvals($m,$a,$s), ",\n";
358
my $n = shift(@values);
359
my $d = shift(@values);
360
print "\t\t", perlvals($n,$d), ",\n";
367
$hz += 0; # Force to number
369
die "Usage: $0 HZ\n";
372
@val = @{$canned_values{$hz}};
373
if (!defined(@val)) {
374
@val = compute_values($hz);