| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 |
|
| 13 | |
| 14 | |
| 15 | |
| 16 |
|
| 17 | |
| 18 | |
| 19 | |
| 20 | %canned_values = (
|
| 21 | 24 => [
|
| 22 | '0xa6aaaaab','0x2aaaaaa',26,
|
| 23 | '0xa6aaaaaaaaaaaaab','0x2aaaaaaaaaaaaaa',58,
|
| 24 | 125,3,
|
| 25 | '0xc49ba5e4','0x1fbe76c8b4',37,
|
| 26 | '0xc49ba5e353f7ceda','0x1fbe76c8b439581062',69,
|
| 27 | 3,125,
|
| 28 | '0xa2c2aaab','0xaaaa',16,
|
| 29 | '0xa2c2aaaaaaaaaaab','0xaaaaaaaaaaaa',48,
|
| 30 | 125000,3,
|
| 31 | '0xc9539b89','0x7fffbce4217d',47,
|
| 32 | '0xc9539b8887229e91','0x7fffbce4217d2849cb25',79,
|
| 33 | 3,125000,
|
| 34 | ], 32 => [
|
| 35 | '0xfa000000','0x6000000',27,
|
| 36 | '0xfa00000000000000','0x600000000000000',59,
|
| 37 | 125,4,
|
| 38 | '0x83126e98','0xfdf3b645a',36,
|
| 39 | '0x83126e978d4fdf3c','0xfdf3b645a1cac0831',68,
|
| 40 | 4,125,
|
| 41 | '0xf4240000','0x0',17,
|
| 42 | '0xf424000000000000','0x0',49,
|
| 43 | 31250,1,
|
| 44 | '0x8637bd06','0x3fff79c842fa',46,
|
| 45 | '0x8637bd05af6c69b6','0x3fff79c842fa5093964a',78,
|
| 46 | 1,31250,
|
| 47 | ], 48 => [
|
| 48 | '0xa6aaaaab','0x6aaaaaa',27,
|
| 49 | '0xa6aaaaaaaaaaaaab','0x6aaaaaaaaaaaaaa',59,
|
| 50 | 125,6,
|
| 51 | '0xc49ba5e4','0xfdf3b645a',36,
|
| 52 | '0xc49ba5e353f7ceda','0xfdf3b645a1cac0831',68,
|
| 53 | 6,125,
|
| 54 | '0xa2c2aaab','0x15555',17,
|
| 55 | '0xa2c2aaaaaaaaaaab','0x1555555555555',49,
|
| 56 | 62500,3,
|
| 57 | '0xc9539b89','0x3fffbce4217d',46,
|
| 58 | '0xc9539b8887229e91','0x3fffbce4217d2849cb25',78,
|
| 59 | 3,62500,
|
| 60 | ], 64 => [
|
| 61 | '0xfa000000','0xe000000',28,
|
| 62 | '0xfa00000000000000','0xe00000000000000',60,
|
| 63 | 125,8,
|
| 64 | '0x83126e98','0x7ef9db22d',35,
|
| 65 | '0x83126e978d4fdf3c','0x7ef9db22d0e560418',67,
|
| 66 | 8,125,
|
| 67 | '0xf4240000','0x0',18,
|
| 68 | '0xf424000000000000','0x0',50,
|
| 69 | 15625,1,
|
| 70 | '0x8637bd06','0x1fff79c842fa',45,
|
| 71 | '0x8637bd05af6c69b6','0x1fff79c842fa5093964a',77,
|
| 72 | 1,15625,
|
| 73 | ], 100 => [
|
| 74 | '0xa0000000','0x0',28,
|
| 75 | '0xa000000000000000','0x0',60,
|
| 76 | 10,1,
|
| 77 | '0xcccccccd','0x733333333',35,
|
| 78 | '0xcccccccccccccccd','0x73333333333333333',67,
|
| 79 | 1,10,
|
| 80 | '0x9c400000','0x0',18,
|
| 81 | '0x9c40000000000000','0x0',50,
|
| 82 | 10000,1,
|
| 83 | '0xd1b71759','0x1fff2e48e8a7',45,
|
| 84 | '0xd1b71758e219652c','0x1fff2e48e8a71de69ad4',77,
|
| 85 | 1,10000,
|
| 86 | ], 122 => [
|
| 87 | '0x8325c53f','0xfbcda3a',28,
|
| 88 | '0x8325c53ef368eb05','0xfbcda3ac10c9714',60,
|
| 89 | 500,61,
|
| 90 | '0xf9db22d1','0x7fbe76c8b',35,
|
| 91 | '0xf9db22d0e560418a','0x7fbe76c8b43958106',67,
|
| 92 | 61,500,
|
| 93 | '0x8012e2a0','0x3ef36',18,
|
| 94 | '0x8012e29f79b47583','0x3ef368eb04325',50,
|
| 95 | 500000,61,
|
| 96 | '0xffda4053','0x1ffffbce4217',45,
|
| 97 | '0xffda4052d666a983','0x1ffffbce4217d2849cb2',77,
|
| 98 | 61,500000,
|
| 99 | ], 128 => [
|
| 100 | '0xfa000000','0x1e000000',29,
|
| 101 | '0xfa00000000000000','0x1e00000000000000',61,
|
| 102 | 125,16,
|
| 103 | '0x83126e98','0x3f7ced916',34,
|
| 104 | '0x83126e978d4fdf3c','0x3f7ced916872b020c',66,
|
| 105 | 16,125,
|
| 106 | '0xf4240000','0x40000',19,
|
| 107 | '0xf424000000000000','0x4000000000000',51,
|
| 108 | 15625,2,
|
| 109 | '0x8637bd06','0xfffbce4217d',44,
|
| 110 | '0x8637bd05af6c69b6','0xfffbce4217d2849cb25',76,
|
| 111 | 2,15625,
|
| 112 | ], 200 => [
|
| 113 | '0xa0000000','0x0',29,
|
| 114 | '0xa000000000000000','0x0',61,
|
| 115 | 5,1,
|
| 116 | '0xcccccccd','0x333333333',34,
|
| 117 | '0xcccccccccccccccd','0x33333333333333333',66,
|
| 118 | 1,5,
|
| 119 | '0x9c400000','0x0',19,
|
| 120 | '0x9c40000000000000','0x0',51,
|
| 121 | 5000,1,
|
| 122 | '0xd1b71759','0xfff2e48e8a7',44,
|
| 123 | '0xd1b71758e219652c','0xfff2e48e8a71de69ad4',76,
|
| 124 | 1,5000,
|
| 125 | ], 250 => [
|
| 126 | '0x80000000','0x0',29,
|
| 127 | '0x8000000000000000','0x0',61,
|
| 128 | 4,1,
|
| 129 | '0x80000000','0x180000000',33,
|
| 130 | '0x8000000000000000','0x18000000000000000',65,
|
| 131 | 1,4,
|
| 132 | '0xfa000000','0x0',20,
|
| 133 | '0xfa00000000000000','0x0',52,
|
| 134 | 4000,1,
|
| 135 | '0x83126e98','0x7ff7ced9168',43,
|
| 136 | '0x83126e978d4fdf3c','0x7ff7ced916872b020c4',75,
|
| 137 | 1,4000,
|
| 138 | ], 256 => [
|
| 139 | '0xfa000000','0x3e000000',30,
|
| 140 | '0xfa00000000000000','0x3e00000000000000',62,
|
| 141 | 125,32,
|
| 142 | '0x83126e98','0x1fbe76c8b',33,
|
| 143 | '0x83126e978d4fdf3c','0x1fbe76c8b43958106',65,
|
| 144 | 32,125,
|
| 145 | '0xf4240000','0xc0000',20,
|
| 146 | '0xf424000000000000','0xc000000000000',52,
|
| 147 | 15625,4,
|
| 148 | '0x8637bd06','0x7ffde7210be',43,
|
| 149 | '0x8637bd05af6c69b6','0x7ffde7210be9424e592',75,
|
| 150 | 4,15625,
|
| 151 | ], 300 => [
|
| 152 | '0xd5555556','0x2aaaaaaa',30,
|
| 153 | '0xd555555555555556','0x2aaaaaaaaaaaaaaa',62,
|
| 154 | 10,3,
|
| 155 | '0x9999999a','0x1cccccccc',33,
|
| 156 | '0x999999999999999a','0x1cccccccccccccccc',65,
|
| 157 | 3,10,
|
| 158 | '0xd0555556','0xaaaaa',20,
|
| 159 | '0xd055555555555556','0xaaaaaaaaaaaaa',52,
|
| 160 | 10000,3,
|
| 161 | '0x9d495183','0x7ffcb923a29',43,
|
| 162 | '0x9d495182a9930be1','0x7ffcb923a29c779a6b5',75,
|
| 163 | 3,10000,
|
| 164 | ], 512 => [
|
| 165 | '0xfa000000','0x7e000000',31,
|
| 166 | '0xfa00000000000000','0x7e00000000000000',63,
|
| 167 | 125,64,
|
| 168 | '0x83126e98','0xfdf3b645',32,
|
| 169 | '0x83126e978d4fdf3c','0xfdf3b645a1cac083',64,
|
| 170 | 64,125,
|
| 171 | '0xf4240000','0x1c0000',21,
|
| 172 | '0xf424000000000000','0x1c000000000000',53,
|
| 173 | 15625,8,
|
| 174 | '0x8637bd06','0x3ffef39085f',42,
|
| 175 | '0x8637bd05af6c69b6','0x3ffef39085f4a1272c9',74,
|
| 176 | 8,15625,
|
| 177 | ], 1000 => [
|
| 178 | '0x80000000','0x0',31,
|
| 179 | '0x8000000000000000','0x0',63,
|
| 180 | 1,1,
|
| 181 | '0x80000000','0x0',31,
|
| 182 | '0x8000000000000000','0x0',63,
|
| 183 | 1,1,
|
| 184 | '0xfa000000','0x0',22,
|
| 185 | '0xfa00000000000000','0x0',54,
|
| 186 | 1000,1,
|
| 187 | '0x83126e98','0x1ff7ced9168',41,
|
| 188 | '0x83126e978d4fdf3c','0x1ff7ced916872b020c4',73,
|
| 189 | 1,1000,
|
| 190 | ], 1024 => [
|
| 191 | '0xfa000000','0xfe000000',32,
|
| 192 | '0xfa00000000000000','0xfe00000000000000',64,
|
| 193 | 125,128,
|
| 194 | '0x83126e98','0x7ef9db22',31,
|
| 195 | '0x83126e978d4fdf3c','0x7ef9db22d0e56041',63,
|
| 196 | 128,125,
|
| 197 | '0xf4240000','0x3c0000',22,
|
| 198 | '0xf424000000000000','0x3c000000000000',54,
|
| 199 | 15625,16,
|
| 200 | '0x8637bd06','0x1fff79c842f',41,
|
| 201 | '0x8637bd05af6c69b6','0x1fff79c842fa5093964',73,
|
| 202 | 16,15625,
|
| 203 | ], 1200 => [
|
| 204 | '0xd5555556','0xd5555555',32,
|
| 205 | '0xd555555555555556','0xd555555555555555',64,
|
| 206 | 5,6,
|
| 207 | '0x9999999a','0x66666666',31,
|
| 208 | '0x999999999999999a','0x6666666666666666',63,
|
| 209 | 6,5,
|
| 210 | '0xd0555556','0x2aaaaa',22,
|
| 211 | '0xd055555555555556','0x2aaaaaaaaaaaaa',54,
|
| 212 | 2500,3,
|
| 213 | '0x9d495183','0x1ffcb923a29',41,
|
| 214 | '0x9d495182a9930be1','0x1ffcb923a29c779a6b5',73,
|
| 215 | 3,2500,
|
| 216 | ]
|
| 217 | );
|
| 218 |
|
| 219 | $has_bigint = eval 'use Math::BigInt qw(bgcd); 1;';
|
| 220 |
|
| 221 | sub bint($)
|
| 222 | {
|
| 223 | my($x) = @_;
|
| 224 | return Math::BigInt->new($x);
|
| 225 | }
|
| 226 |
|
| 227 | |
| 228 | |
| 229 | |
| 230 | |
| 231 | sub fmul($$$)
|
| 232 | {
|
| 233 | my ($b,$n,$d) = @_;
|
| 234 |
|
| 235 | $n = bint($n);
|
| 236 | $d = bint($d);
|
| 237 |
|
| 238 | return scalar (($n << $b)+$d-bint(1))/$d;
|
| 239 | }
|
| 240 |
|
| 241 | sub fadj($$$)
|
| 242 | {
|
| 243 | my($b,$n,$d) = @_;
|
| 244 |
|
| 245 | $n = bint($n);
|
| 246 | $d = bint($d);
|
| 247 |
|
| 248 | $d = $d/bgcd($n, $d);
|
| 249 | return scalar (($d-bint(1)) << $b)/$d;
|
| 250 | }
|
| 251 |
|
| 252 | sub fmuls($$$) {
|
| 253 | my($b,$n,$d) = @_;
|
| 254 | my($s,$m);
|
| 255 | my($thres) = bint(1) << ($b-1);
|
| 256 |
|
| 257 | $n = bint($n);
|
| 258 | $d = bint($d);
|
| 259 |
|
| 260 | for ($s = 0; 1; $s++) {
|
| 261 | $m = fmul($s,$n,$d);
|
| 262 | return $s if ($m >= $thres);
|
| 263 | }
|
| 264 | return 0;
|
| 265 | }
|
| 266 |
|
| 267 | # Provides mul, adj, and shr factors for a specific
|
| 268 | # (bit, time, hz) combination
|
| 269 | sub muladj($$$) {
|
| 270 | my($b, $t, $hz) = @_;
|
| 271 | my $s = fmuls($b, $t, $hz);
|
| 272 | my $m = fmul($s, $t, $hz);
|
| 273 | my $a = fadj($s, $t, $hz);
|
| 274 | return ($m->as_hex(), $a->as_hex(), $s);
|
| 275 | }
|
| 276 |
|
| 277 | # Provides numerator, denominator values
|
| 278 | sub numden($$) {
|
| 279 | my($n, $d) = @_;
|
| 280 | my $g = bgcd($n, $d);
|
| 281 | return ($n/$g, $d/$g);
|
| 282 | }
|
| 283 |
|
| 284 | # All values for a specific (time, hz) combo
|
| 285 | sub conversions($$) {
|
| 286 | my ($t, $hz) = @_;
|
| 287 | my @val = ();
|
| 288 |
|
| 289 | # HZ_TO_xx
|
| 290 | push(@val, muladj(32, $t, $hz));
|
| 291 | push(@val, muladj(64, $t, $hz));
|
| 292 | push(@val, numden($t, $hz));
|
| 293 |
|
| 294 | # xx_TO_HZ
|
| 295 | push(@val, muladj(32, $hz, $t));
|
| 296 | push(@val, muladj(64, $hz, $t));
|
| 297 | push(@val, numden($hz, $t));
|
| 298 |
|
| 299 | return @val;
|
| 300 | }
|
| 301 |
|
| 302 | sub compute_values($) {
|
| 303 | my($hz) = @_;
|
| 304 | my @val = ();
|
| 305 | my $s, $m, $a, $g;
|
| 306 |
|
| 307 | if (!$has_bigint) {
|
| 308 | die "$0: HZ == $hz not canned and ".
|
| 309 | "Math::BigInt not available\n";
|
| 310 | }
|
| 311 |
|
| 312 | # MSEC conversions
|
| 313 | push(@val, conversions(1000, $hz));
|
| 314 |
|
| 315 | # USEC conversions
|
| 316 | push(@val, conversions(1000000, $hz));
|
| 317 |
|
| 318 | return @val;
|
| 319 | }
|
| 320 |
|
| 321 | sub output($@)
|
| 322 | {
|
| 323 | my($hz, @val) = @_;
|
| 324 | my $pfx, $bit, $suf, $s, $m, $a;
|
| 325 |
|
| 326 | print "/* Automatically generated by kernel/timeconst.pl */\n";
|
| 327 | print "/* Conversion constants for HZ == $hz */\n";
|
| 328 | print "\n";
|
| 329 | print "#ifndef KERNEL_TIMECONST_H\n";
|
| 330 | print "#define KERNEL_TIMECONST_H\n";
|
| 331 | print "\n";
|
| 332 |
|
| 333 | print "#include <linux/param.h>\n";
|
| 334 |
|
| 335 | print "\n";
|
| 336 | print "#if HZ != $hz\n";
|
| 337 | print "#error \"kernel/timeconst.h has the wrong HZ value!\"\n";
|
| 338 | print "#endif\n";
|
| 339 | print "\n";
|
| 340 |
|
| 341 | foreach $pfx ('HZ_TO_MSEC','MSEC_TO_HZ',
|
| 342 | 'HZ_TO_USEC','USEC_TO_HZ') {
|
| 343 | foreach $bit (32, 64) {
|
| 344 | foreach $suf ('MUL', 'ADJ', 'SHR') {
|
| 345 | printf "#define %-23s %s\n",
|
| 346 | "${pfx}_$suf$bit", shift(@val);
|
| 347 | }
|
| 348 | }
|
| 349 | foreach $suf ('NUM', 'DEN') {
|
| 350 | printf "#define %-23s %s\n",
|
| 351 | "${pfx}_$suf", shift(@val);
|
| 352 | }
|
| 353 | }
|
| 354 |
|
| 355 | print "\n";
|
| 356 | print "#endif /* KERNEL_TIMECONST_H */\n";
|
| 357 | }
|
| 358 |
|
| 359 | ($hz) = @ARGV;
|
| 360 |
|
| 361 | # Use this to generate the %canned_values structure
|
| 362 | if ($hz eq '--can') {
|
| 363 | shift(@ARGV);
|
| 364 | @hzlist = sort {$a <=> $b} (@ARGV);
|
| 365 |
|
| 366 | print "# Precomputed values for systems without Math::BigInt\n";
|
| 367 | print "# Generated by:\n";
|
| 368 | print "# timeconst.pl --can ", join(' ', @hzlist), "\n";
|
| 369 | print "\%canned_values = (\n";
|
| 370 | my $pf = "\t";
|
| 371 | foreach $hz (@hzlist) {
|
| 372 | my @values = compute_values($hz);
|
| 373 | print "$pf$hz => [\n";
|
| 374 | while (scalar(@values)) {
|
| 375 | my $bit;
|
| 376 | foreach $bit (32, 64) {
|
| 377 | my $m = shift(@values);
|
| 378 | my $a = shift(@values);
|
| 379 | my $s = shift(@values);
|
| 380 | print "\t\t\'",$m,"\',\'",$a,"\',",$s,",\n";
|
| 381 | }
|
| 382 | my $n = shift(@values);
|
| 383 | my $d = shift(@values);
|
| 384 | print "\t\t",$n,',',$d,",\n";
|
| 385 | }
|
| 386 | print "\t]";
|
| 387 | $pf = ', ';
|
| 388 | }
|
| 389 | print "\n);\n";
|
| 390 | } else {
|
| 391 | $hz += 0; # Force to number
|
| 392 | if ($hz < 1) {
|
| 393 | die "Usage: $0 HZ\n";
|
| 394 | }
|
| 395 |
|
| 396 | @val = @{$canned_values{$hz}};
|
| 397 | if (!defined(@val)) {
|
| 398 | @val = compute_values($hz);
|
| 399 | }
|
| 400 | output($hz, @val);
|
| 401 | }
|
| 402 | exit 0;
|