comparison sources/patches/linux-noperl-timeconst.patch @ 1337:1bc0c01950ca

Switch to the noperl patches for 2.6.38.
author Rob Landley <rob@landley.net>
date Fri, 18 Mar 2011 23:02:13 -0500
parents
children ddbd48ced0d7
comparison
equal deleted inserted replaced
1336:c7dfe0e54a80 1337:1bc0c01950ca
1 Message-ID: <4D35FEF3.4070001@parallels.com>
2 Date: Tue, 18 Jan 2011 14:58:27 -0600
3 From: Rob Landley <rlandley@parallels.com>
4 User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101208 Thunderbird/3.1.7
5 To: Jesper Juhl <jj@chaosbits.net>, Ingo Molnar <mingo@elte.hu>, "H. Peter
6 Anvin" <hpa@zytor.com>, Yinghai Lu <yinghai@kernel.org>, Tejun Heo
7 <tj@kernel.org>, Don Zickus <dzickus@redhat.com>,
8 <linux-kernel@vger.kernel.org>
9 Subject: Re: [PATCH] Use sed instead of perl to generate x86/kernel/cpu/capflags.c.
10 References: <4D334E1E.7090708@parallels.com> <alpine.LNX.2.00.1101162103450.13377@swampdragon.chaosbits.net> <4D335554.7020403@parallels.com> <alpine.LNX.2.00.1101162136360.13377@swampdragon.chaosbits.net>
11 In-Reply-To: <alpine.LNX.2.00.1101162136360.13377@swampdragon.chaosbits.net>
12 Content-Type: multipart/mixed;
13 boundary="------------070402000802050303040701"
14 MIME-Version: 1.0
15
16 --------------070402000802050303040701
17 Content-Type: text/plain; charset="ISO-8859-1"
18 Content-Transfer-Encoding: 7bit
19
20
21 From: Rob Landley <rlandley@parallels.com>
22
23 Replace perl header file generator with smaller/faster/simpler C version.
24
25 Signed-off-by: Rob Landley <rlandley@parallels.com>
26 ---
27
28 I ran the attached test script to compare the output of the C program
29 with the output of the perl version for every HZ from 1 to 5000 to make
30 sure it was producing the same constants.
31
32 kernel/Makefile | 10 -
33 kernel/mktimeconst.c | 109 +++++++++++
34 kernel/timeconst.pl | 378 -----------------------------------------
35 3 files changed, 115 insertions(+), 382 deletions(-)
36
37 diff --git a/kernel/Makefile b/kernel/Makefile
38 index 5669f71..ba9ce6d 100644
39 --- a/kernel/Makefile
40 +++ b/kernel/Makefile
41 @@ -133,8 +133,10 @@ $(obj)/config_data.h: $(obj)/config_data.gz FORCE
42
43 $(obj)/time.o: $(obj)/timeconst.h
44
45 -quiet_cmd_timeconst = TIMEC $@
46 - cmd_timeconst = $(PERL) $< $(CONFIG_HZ) > $@
47 +hostprogs-y += mktimeconst
48 +quiet_cmd_mktimeconst = TIMEC $@
49 + cmd_mktimeconst = $(obj)/mktimeconst $(CONFIG_HZ) $@ || ( rm -f $@ && exit 1 )
50 +
51 targets += timeconst.h
52 -$(obj)/timeconst.h: $(src)/timeconst.pl FORCE
53 - $(call if_changed,timeconst)
54 +$(obj)/timeconst.h: $(obj)/mktimeconst FORCE
55 + $(call if_changed,mktimeconst)
56 --- /dev/null 2011-01-13 17:00:36.470564274 -0600
57 +++ b/kernel/mktimeconst.c 2011-01-16 12:44:04.091168778 -0600
58 @@ -0,0 +1,109 @@
59 +/* Copyright 2010 Parallels Inc, licensed under GPLv2 */
60 +
61 +#include <inttypes.h>
62 +#include <stdio.h>
63 +#include <stdlib.h>
64 +
65 +int main(int argc, char *argv[])
66 +{
67 + uint64_t hz, periods[] = {1000, 1000000};
68 + char *names[] = {"MSEC", "USEC"};
69 + FILE *file;
70 + int i, j;
71 +
72 + if (argc != 3 || (hz = atol(argv[1])) < 1
73 + || !(file = fopen(argv[2], "w")))
74 + {
75 + fprintf(stderr, "Usage: mktimeconst HZ FILENAME\n\n");
76 + fprintf(stderr, "Generate a header file with constants to convert between\n");
77 + fprintf(stderr, "decimal HZ timer ticks and milisecond or microsecond delays,\n");
78 + fprintf(stderr, "using reciprocal multiplication to avoid 64 bit division.\n");
79 + exit(1);
80 + }
81 +
82 + fprintf(file,
83 + "/* Automatically generated by kernel/mktimeconst */\n"
84 + "/* Conversion constants for HZ == %"PRIu64" */\n\n"
85 + "#ifndef __KERNEL_TIMECONST_H\n"
86 + "#define __KERNEL_TIMECONST_H\n\n"
87 + "#include <linux/param.h>\n"
88 + "#include <linux/types.h>\n\n"
89 + "#if HZ != %"PRIu64"\n"
90 + "#error \"kernel/timeconst.h has the wrong HZ value!\"\n"
91 + "#endif\n\n", hz, hz);
92 +
93 + /* Repeat for MSEC and USEC */
94 +
95 + for (i = 0; i < 2; i++) {
96 + uint64_t gcd, period;
97 +
98 + /* Find greatest common denominator using Euclid's algorithm. */
99 +
100 + gcd = hz;
101 + period = periods[i];
102 + while (period) {
103 + uint64_t temp = gcd % period;
104 + gcd = period;
105 + period = temp;
106 + }
107 +
108 + /* Output both directions (HZ_TO_PERIOD and PERIOD_TO_HZ) */
109 +
110 + for (j = 0; j < 2; j++) {
111 + char name[16];
112 + uint64_t from = j ? periods[i] : hz;
113 + uint64_t to = j ? hz : periods[i];
114 + uint64_t mul32 = 0, adj32 = 0, shift = 0;
115 +
116 + sprintf(name, j ? "%s_TO_HZ" : "HZ_TO_%s", names[i]);
117 +
118 + /* Figure out what shift value gives 32 significant
119 + bits of MUL32 data. (Worst case to=1 from=1000000
120 + uses 52 bits, to<<shift won't overflow 64 bit math.)
121 + */
122 +
123 + for (;;) {
124 + mul32 = ((to << shift) + from - 1) / from;
125 + if (mul32 >= (1L<<31))
126 + break;
127 + shift++;
128 + }
129 +
130 + /* ADJ32 is is just (((FROM/GCD)-1)<<SHIFT)/(FROM/GCD)
131 + but this can overflow 64 bit math (examples, HZ=24
132 + or HZ=122). Worst case scenario uses 32+20+20=72
133 + bits. Workaround: split off bottom 32 bits and
134 + reassemble after calculation (32+64=96 bits). */
135 +
136 + adj32 = from / gcd;
137 +
138 + if (shift > 32) {
139 + uint64_t upper, lower;
140 +
141 + upper = (adj32 - 1) << (shift - 32);
142 + lower = (upper % adj32) << 32;
143 + adj32 = ((upper/adj32) << 32) + (lower/adj32);
144 + } else
145 + adj32 = ((adj32 - 1) << shift) / adj32;
146 +
147 + /* Emit the constants into the header file. */
148 +
149 + fprintf(file, "#define %s_MUL32\tU64_C(0x%"PRIx64")\n",
150 + name, mul32);
151 + fprintf(file, "#define %s_ADJ32\tU64_C(0x%"PRIx64")\n",
152 + name, adj32);
153 + fprintf(file, "#define %s_SHR32\t%"PRIu64"\n",
154 + name, shift);
155 + fprintf(file, "#define %s_NUM\t\tU64_C(%"PRIu64")\n",
156 + name, to/gcd);
157 + fprintf(file, "#define %s_DEN\t\tU64_C(%"PRIu64")\n\n",
158 + name, from/gcd);
159 + }
160 + }
161 + fprintf(file, "#endif /* __KERNEL_TIMECONST_H */\n");
162 +
163 + /* Notice if the disk fills up. */
164 +
165 + fflush(stdout);
166 + return ferror(stdout);
167 +}
168 --- a/kernel/timeconst.pl 2010-12-19 11:33:53.969732934 -0600
169 +++ /dev/null 2011-01-13 17:00:36.470564274 -0600
170 @@ -1,378 +0,0 @@
171 -#!/usr/bin/perl
172 -# -----------------------------------------------------------------------
173 -#
174 -# Copyright 2007-2008 rPath, Inc. - All Rights Reserved
175 -#
176 -# This file is part of the Linux kernel, and is made available under
177 -# the terms of the GNU General Public License version 2 or (at your
178 -# option) any later version; incorporated herein by reference.
179 -#
180 -# -----------------------------------------------------------------------
181 -#
182 -
183 -#
184 -# Usage: timeconst.pl HZ > timeconst.h
185 -#
186 -
187 -# Precomputed values for systems without Math::BigInt
188 -# Generated by:
189 -# timeconst.pl --can 24 32 48 64 100 122 128 200 250 256 300 512 1000 1024 1200
190 -%canned_values = (
191 - 24 => [
192 - '0xa6aaaaab','0x2aaaaaa',26,
193 - 125,3,
194 - '0xc49ba5e4','0x1fbe76c8b4',37,
195 - 3,125,
196 - '0xa2c2aaab','0xaaaa',16,
197 - 125000,3,
198 - '0xc9539b89','0x7fffbce4217d',47,
199 - 3,125000,
200 - ], 32 => [
201 - '0xfa000000','0x6000000',27,
202 - 125,4,
203 - '0x83126e98','0xfdf3b645a',36,
204 - 4,125,
205 - '0xf4240000','0x0',17,
206 - 31250,1,
207 - '0x8637bd06','0x3fff79c842fa',46,
208 - 1,31250,
209 - ], 48 => [
210 - '0xa6aaaaab','0x6aaaaaa',27,
211 - 125,6,
212 - '0xc49ba5e4','0xfdf3b645a',36,
213 - 6,125,
214 - '0xa2c2aaab','0x15555',17,
215 - 62500,3,
216 - '0xc9539b89','0x3fffbce4217d',46,
217 - 3,62500,
218 - ], 64 => [
219 - '0xfa000000','0xe000000',28,
220 - 125,8,
221 - '0x83126e98','0x7ef9db22d',35,
222 - 8,125,
223 - '0xf4240000','0x0',18,
224 - 15625,1,
225 - '0x8637bd06','0x1fff79c842fa',45,
226 - 1,15625,
227 - ], 100 => [
228 - '0xa0000000','0x0',28,
229 - 10,1,
230 - '0xcccccccd','0x733333333',35,
231 - 1,10,
232 - '0x9c400000','0x0',18,
233 - 10000,1,
234 - '0xd1b71759','0x1fff2e48e8a7',45,
235 - 1,10000,
236 - ], 122 => [
237 - '0x8325c53f','0xfbcda3a',28,
238 - 500,61,
239 - '0xf9db22d1','0x7fbe76c8b',35,
240 - 61,500,
241 - '0x8012e2a0','0x3ef36',18,
242 - 500000,61,
243 - '0xffda4053','0x1ffffbce4217',45,
244 - 61,500000,
245 - ], 128 => [
246 - '0xfa000000','0x1e000000',29,
247 - 125,16,
248 - '0x83126e98','0x3f7ced916',34,
249 - 16,125,
250 - '0xf4240000','0x40000',19,
251 - 15625,2,
252 - '0x8637bd06','0xfffbce4217d',44,
253 - 2,15625,
254 - ], 200 => [
255 - '0xa0000000','0x0',29,
256 - 5,1,
257 - '0xcccccccd','0x333333333',34,
258 - 1,5,
259 - '0x9c400000','0x0',19,
260 - 5000,1,
261 - '0xd1b71759','0xfff2e48e8a7',44,
262 - 1,5000,
263 - ], 250 => [
264 - '0x80000000','0x0',29,
265 - 4,1,
266 - '0x80000000','0x180000000',33,
267 - 1,4,
268 - '0xfa000000','0x0',20,
269 - 4000,1,
270 - '0x83126e98','0x7ff7ced9168',43,
271 - 1,4000,
272 - ], 256 => [
273 - '0xfa000000','0x3e000000',30,
274 - 125,32,
275 - '0x83126e98','0x1fbe76c8b',33,
276 - 32,125,
277 - '0xf4240000','0xc0000',20,
278 - 15625,4,
279 - '0x8637bd06','0x7ffde7210be',43,
280 - 4,15625,
281 - ], 300 => [
282 - '0xd5555556','0x2aaaaaaa',30,
283 - 10,3,
284 - '0x9999999a','0x1cccccccc',33,
285 - 3,10,
286 - '0xd0555556','0xaaaaa',20,
287 - 10000,3,
288 - '0x9d495183','0x7ffcb923a29',43,
289 - 3,10000,
290 - ], 512 => [
291 - '0xfa000000','0x7e000000',31,
292 - 125,64,
293 - '0x83126e98','0xfdf3b645',32,
294 - 64,125,
295 - '0xf4240000','0x1c0000',21,
296 - 15625,8,
297 - '0x8637bd06','0x3ffef39085f',42,
298 - 8,15625,
299 - ], 1000 => [
300 - '0x80000000','0x0',31,
301 - 1,1,
302 - '0x80000000','0x0',31,
303 - 1,1,
304 - '0xfa000000','0x0',22,
305 - 1000,1,
306 - '0x83126e98','0x1ff7ced9168',41,
307 - 1,1000,
308 - ], 1024 => [
309 - '0xfa000000','0xfe000000',32,
310 - 125,128,
311 - '0x83126e98','0x7ef9db22',31,
312 - 128,125,
313 - '0xf4240000','0x3c0000',22,
314 - 15625,16,
315 - '0x8637bd06','0x1fff79c842f',41,
316 - 16,15625,
317 - ], 1200 => [
318 - '0xd5555556','0xd5555555',32,
319 - 5,6,
320 - '0x9999999a','0x66666666',31,
321 - 6,5,
322 - '0xd0555556','0x2aaaaa',22,
323 - 2500,3,
324 - '0x9d495183','0x1ffcb923a29',41,
325 - 3,2500,
326 - ]
327 -);
328 -
329 -$has_bigint = eval 'use Math::BigInt qw(bgcd); 1;';
330 -
331 -sub bint($)
332 -{
333 - my($x) = @_;
334 - return Math::BigInt->new($x);
335 -}
336 -
337 -#
338 -# Constants for division by reciprocal multiplication.
339 -# (bits, numerator, denominator)
340 -#
341 -sub fmul($$$)
342 -{
343 - my ($b,$n,$d) = @_;
344 -
345 - $n = bint($n);
346 - $d = bint($d);
347 -
348 - return scalar (($n << $b)+$d-bint(1))/$d;
349 -}
350 -
351 -sub fadj($$$)
352 -{
353 - my($b,$n,$d) = @_;
354 -
355 - $n = bint($n);
356 - $d = bint($d);
357 -
358 - $d = $d/bgcd($n, $d);
359 - return scalar (($d-bint(1)) << $b)/$d;
360 -}
361 -
362 -sub fmuls($$$) {
363 - my($b,$n,$d) = @_;
364 - my($s,$m);
365 - my($thres) = bint(1) << ($b-1);
366 -
367 - $n = bint($n);
368 - $d = bint($d);
369 -
370 - for ($s = 0; 1; $s++) {
371 - $m = fmul($s,$n,$d);
372 - return $s if ($m >= $thres);
373 - }
374 - return 0;
375 -}
376 -
377 -# Generate a hex value if the result fits in 64 bits;
378 -# otherwise skip.
379 -sub bignum_hex($) {
380 - my($x) = @_;
381 - my $s = $x->as_hex();
382 -
383 - return (length($s) > 18) ? undef : $s;
384 -}
385 -
386 -# Provides mul, adj, and shr factors for a specific
387 -# (bit, time, hz) combination
388 -sub muladj($$$) {
389 - my($b, $t, $hz) = @_;
390 - my $s = fmuls($b, $t, $hz);
391 - my $m = fmul($s, $t, $hz);
392 - my $a = fadj($s, $t, $hz);
393 - return (bignum_hex($m), bignum_hex($a), $s);
394 -}
395 -
396 -# Provides numerator, denominator values
397 -sub numden($$) {
398 - my($n, $d) = @_;
399 - my $g = bgcd($n, $d);
400 - return ($n/$g, $d/$g);
401 -}
402 -
403 -# All values for a specific (time, hz) combo
404 -sub conversions($$) {
405 - my ($t, $hz) = @_;
406 - my @val = ();
407 -
408 - # HZ_TO_xx
409 - push(@val, muladj(32, $t, $hz));
410 - push(@val, numden($t, $hz));
411 -
412 - # xx_TO_HZ
413 - push(@val, muladj(32, $hz, $t));
414 - push(@val, numden($hz, $t));
415 -
416 - return @val;
417 -}
418 -
419 -sub compute_values($) {
420 - my($hz) = @_;
421 - my @val = ();
422 - my $s, $m, $a, $g;
423 -
424 - if (!$has_bigint) {
425 - die "$0: HZ == $hz not canned and ".
426 - "Math::BigInt not available\n";
427 - }
428 -
429 - # MSEC conversions
430 - push(@val, conversions(1000, $hz));
431 -
432 - # USEC conversions
433 - push(@val, conversions(1000000, $hz));
434 -
435 - return @val;
436 -}
437 -
438 -sub outputval($$)
439 -{
440 - my($name, $val) = @_;
441 - my $csuf;
442 -
443 - if (defined($val)) {
444 - if ($name !~ /SHR/) {
445 - $val = "U64_C($val)";
446 - }
447 - printf "#define %-23s %s\n", $name.$csuf, $val.$csuf;
448 - }
449 -}
450 -
451 -sub output($@)
452 -{
453 - my($hz, @val) = @_;
454 - my $pfx, $bit, $suf, $s, $m, $a;
455 -
456 - print "/* Automatically generated by kernel/timeconst.pl */\n";
457 - print "/* Conversion constants for HZ == $hz */\n";
458 - print "\n";
459 - print "#ifndef KERNEL_TIMECONST_H\n";
460 - print "#define KERNEL_TIMECONST_H\n";
461 - print "\n";
462 -
463 - print "#include <linux/param.h>\n";
464 - print "#include <linux/types.h>\n";
465 -
466 - print "\n";
467 - print "#if HZ != $hz\n";
468 - print "#error \"kernel/timeconst.h has the wrong HZ value!\"\n";
469 - print "#endif\n";
470 - print "\n";
471 -
472 - foreach $pfx ('HZ_TO_MSEC','MSEC_TO_HZ',
473 - 'HZ_TO_USEC','USEC_TO_HZ') {
474 - foreach $bit (32) {
475 - foreach $suf ('MUL', 'ADJ', 'SHR') {
476 - outputval("${pfx}_$suf$bit", shift(@val));
477 - }
478 - }
479 - foreach $suf ('NUM', 'DEN') {
480 - outputval("${pfx}_$suf", shift(@val));
481 - }
482 - }
483 -
484 - print "\n";
485 - print "#endif /* KERNEL_TIMECONST_H */\n";
486 -}
487 -
488 -# Pretty-print Perl values
489 -sub perlvals(@) {
490 - my $v;
491 - my @l = ();
492 -
493 - foreach $v (@_) {
494 - if (!defined($v)) {
495 - push(@l, 'undef');
496 - } elsif ($v =~ /^0x/) {
497 - push(@l, "\'".$v."\'");
498 - } else {
499 - push(@l, $v.'');
500 - }
501 - }
502 - return join(',', @l);
503 -}
504 -
505 -($hz) = @ARGV;
506 -
507 -# Use this to generate the %canned_values structure
508 -if ($hz eq '--can') {
509 - shift(@ARGV);
510 - @hzlist = sort {$a <=> $b} (@ARGV);
511 -
512 - print "# Precomputed values for systems without Math::BigInt\n";
513 - print "# Generated by:\n";
514 - print "# timeconst.pl --can ", join(' ', @hzlist), "\n";
515 - print "\%canned_values = (\n";
516 - my $pf = "\t";
517 - foreach $hz (@hzlist) {
518 - my @values = compute_values($hz);
519 - print "$pf$hz => [\n";
520 - while (scalar(@values)) {
521 - my $bit;
522 - foreach $bit (32) {
523 - my $m = shift(@values);
524 - my $a = shift(@values);
525 - my $s = shift(@values);
526 - print "\t\t", perlvals($m,$a,$s), ",\n";
527 - }
528 - my $n = shift(@values);
529 - my $d = shift(@values);
530 - print "\t\t", perlvals($n,$d), ",\n";
531 - }
532 - print "\t]";
533 - $pf = ', ';
534 - }
535 - print "\n);\n";
536 -} else {
537 - $hz += 0; # Force to number
538 - if ($hz < 1) {
539 - die "Usage: $0 HZ\n";
540 - }
541 -
542 - @val = @{$canned_values{$hz}};
543 - if (!defined(@val)) {
544 - @val = compute_values($hz);
545 - }
546 - output($hz, @val);
547 -}
548 -exit 0;
549
550 --------------070402000802050303040701
551 Content-Type: application/x-sh; name="loopy.sh"
552 Content-Transfer-Encoding: 7bit
553 Content-Disposition: attachment; filename="loopy.sh"
554
555 #!/bin/bash
556
557 gcc mktimeconst.c || exit 1
558
559 X=1
560 while [ $X -lt 5000 ]
561 do
562 echo $X
563
564 perl ~/linux/linux/kernel/timeconst.pl $X | sed 's/KERNEL_TIMECONST/__KERNEL_TIMECONST/;/Automatically generated/d;/^$/d'> temp.txt
565 ./a.out $X temp2.txt
566 sed -i '/Automatically generated/d;/^$/d' temp2.txt
567
568 diff -uw temp.txt temp2.txt || exit 1
569
570 X=$(($X+1))
571 done
572
573 --------------070402000802050303040701--