All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Use sed instead of perl to generate x86/kernel/cpu/capflags.c.
@ 2011-01-16 19:59 Rob Landley
  2011-01-16 20:05 ` Jesper Juhl
  0 siblings, 1 reply; 6+ messages in thread
From: Rob Landley @ 2011-01-16 19:59 UTC (permalink / raw)
  To: linux-kernel, tglx, mingo, hpa, x86, K. Y. Srinivasan,
	Greg Kroah-Hartman

From: Rob Landley <rlandley@parallels.com>

Generate capflags.c with sed (POSIX 2008) instead of perl.

Signed-off-by: Rob Landley <rlandley@parallels.com>
---

This patch hasn't changed since 2009.

 arch/x86/kernel/cpu/Makefile      |    4 +--
 arch/x86/kernel/cpu/mkcapflags.pl |   32 ----------------------------
 arch/x86/kernel/cpu/mkcapflags.sh |   28 ++++++++++++++++++++++++
 3 files changed, 30 insertions(+), 34 deletions(-)

diff -ruN linux-2.6.30.old/arch/x86/kernel/cpu/Makefile linux-2.6.30/arch/x86/kernel/cpu/Makefile
--- linux-2.6.30.old/arch/x86/kernel/cpu/Makefile	2009-06-09 22:05:27.000000000 -0500
+++ linux-2.6.30/arch/x86/kernel/cpu/Makefile	2009-06-22 16:39:06.000000000 -0500
@@ -36,10 +36,10 @@
 obj-$(CONFIG_X86_LOCAL_APIC)		+= perfctr-watchdog.o
 
 quiet_cmd_mkcapflags = MKCAP   $@
-      cmd_mkcapflags = $(PERL) $(srctree)/$(src)/mkcapflags.pl $< $@
+      cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $< $@
 
 cpufeature = $(src)/../../include/asm/cpufeature.h
 
 targets += capflags.c
-$(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.pl FORCE
+$(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE
 	$(call if_changed,mkcapflags)
diff -ruN linux-2.6.30.old/arch/x86/kernel/cpu/mkcapflags.pl linux-2.6.30/arch/x86/kernel/cpu/mkcapflags.pl
--- linux-2.6.30.old/arch/x86/kernel/cpu/mkcapflags.pl	2009-06-09 22:05:27.000000000 -0500
+++ linux-2.6.30/arch/x86/kernel/cpu/mkcapflags.pl	1969-12-31 18:00:00.000000000 -0600
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-#
-# Generate the x86_cap_flags[] array from include/asm-x86/cpufeature.h
-#
-
-($in, $out) = @ARGV;
-
-open(IN, "< $in\0")   or die "$0: cannot open: $in: $!\n";
-open(OUT, "> $out\0") or die "$0: cannot create: $out: $!\n";
-
-print OUT "#include <asm/cpufeature.h>\n\n";
-print OUT "const char * const x86_cap_flags[NCAPINTS*32] = {\n";
-
-while (defined($line = <IN>)) {
-	if ($line =~ /^\s*\#\s*define\s+(X86_FEATURE_(\S+))\s+(.*)$/) {
-		$macro = $1;
-		$feature = $2;
-		$tail = $3;
-		if ($tail =~ /\/\*\s*\"([^"]*)\".*\*\//) {
-			$feature = $1;
-		}
-
-		if ($feature ne '') {
-			printf OUT "\t%-32s = \"%s\",\n",
-				"[$macro]", "\L$feature";
-		}
-	}
-}
-print OUT "};\n";
-
-close(IN);
-close(OUT);
diff -ruN linux-2.6.30.old/arch/x86/kernel/cpu/mkcapflags.sh linux-2.6.30/arch/x86/kernel/cpu/mkcapflags.sh
--- linux-2.6.30.old/arch/x86/kernel/cpu/mkcapflags.sh	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.30/arch/x86/kernel/cpu/mkcapflags.sh	2009-06-22 16:39:06.000000000 -0500
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Generate the x86_cap_flags[] array from include/asm/cpufeature.h
+#
+
+IN=$1
+OUT=$2
+
+(
+	echo "#include <asm/cpufeature.h>"
+	echo ""
+	echo "const char * const x86_cap_flags[NCAPINTS*32] = {"
+
+	# Iterate through any input lines starting with #define X86_FEATURE_
+	sed -n -e 's/\t/ /g' -e 's/^ *# *define *X86_FEATURE_//p' $IN |
+	while read i
+	do
+		# Name is everything up to the first whitespace
+		NAME="$(echo "$i" | sed 's/ .*//')"
+
+		# If the /* comment */ starts with a quote string, grab that.
+		VALUE="$(echo "$i" | sed -n 's@.*/\* *\("[^"]*"\).*\*/@\1@p')"
+		[ -z "$VALUE" ] && VALUE="\"$(echo "$NAME" | tr A-Z a-z)\""
+
+		[ "$VALUE" != '""' ] && echo "	[X86_FEATURE_$NAME] = $VALUE,"
+	done
+	echo "};"
+) > $OUT

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Use sed instead of perl to generate x86/kernel/cpu/capflags.c.
  2011-01-16 19:59 [PATCH] Use sed instead of perl to generate x86/kernel/cpu/capflags.c Rob Landley
@ 2011-01-16 20:05 ` Jesper Juhl
  2011-01-16 20:30   ` Rob Landley
  0 siblings, 1 reply; 6+ messages in thread
From: Jesper Juhl @ 2011-01-16 20:05 UTC (permalink / raw)
  To: Rob Landley
  Cc: linux-kernel, tglx, mingo, hpa, x86, K. Y. Srinivasan,
	Greg Kroah-Hartman

On Sun, 16 Jan 2011, Rob Landley wrote:

> From: Rob Landley <rlandley@parallels.com>
> 
> Generate capflags.c with sed (POSIX 2008) instead of perl.
> 

While I'm not personally a great perl fan, this still begs the 
question, why?

We already depend on perl for other stuff, so why replace something that 
works with something that may or may not work?


-- 
Jesper Juhl <jj@chaosbits.net>            http://www.chaosbits.net/
Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html
Plain text mails only, please.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Use sed instead of perl to generate x86/kernel/cpu/capflags.c.
  2011-01-16 20:05 ` Jesper Juhl
@ 2011-01-16 20:30   ` Rob Landley
  2011-01-16 20:39     ` Jesper Juhl
  0 siblings, 1 reply; 6+ messages in thread
From: Rob Landley @ 2011-01-16 20:30 UTC (permalink / raw)
  To: Jesper Juhl
  Cc: linux-kernel, tglx, mingo, hpa, x86, K. Y. Srinivasan,
	Greg Kroah-Hartman

On 01/16/2011 02:05 PM, Jesper Juhl wrote:
> On Sun, 16 Jan 2011, Rob Landley wrote:
> 
>> From: Rob Landley <rlandley@parallels.com>
>>
>> Generate capflags.c with sed (POSIX 2008) instead of perl.
>>
> 
> While I'm not personally a great perl fan, this still begs the 
> question, why?

1) In general, simpler is better.  (Why ship autoconf files to build on
hosts that don't have autoconf?  Why fix make oldconfig so it builds on
platforms that don't have curses installed?)

2) Making reliable cross compile build environments involves creating a
known build environment on the host, generally removing everything you
don't actually _need_ so it can't screw things up when you introduce
another target or upgrade packages on your host.

I've maintained such a build environment (aboriginal linux) for several
years.  I've personally encountered literally _dozens_ of others, and
expect there are at least hundreds if not thousands out in the wild.

3) Perl is not a well-defined langauge.  It is a single implementation,
not a standard.  (Like Microsoft Word and Excel, their file formats are
just "what this program emits/parses".  Similarly, Perl is what the perl
binary runs.  Attemts to rewrite it based on Parrot famously collapsed
into a black hole of corner cases.)

Meaning, if you have a platform on which the one and only implementation
of perl doesn't run, you have no alternative implementations to try.
(Did I mention that Perl's configuration stage is implemented in perl?)

This moves to an alternative standardized by POSIX, which has well
understood behavior with multiple independent implementations (gnu, bsd,
busybox...)

> We already depend on perl for other stuff, so why replace something that 
> works with something that may or may not work?

We have various development scripts that depend on perl, curses, python,
QT, and so on.  But building a _kernel_ doesn't depend on any of that...
except perl.  I'm not proposing removing checkstack.pl and such, because
"development system" != "build machine".  A build machine can be a
headless box, a development system usually has things like Gnome or KDE
installed.

The kernel's dependency on Perl was introduced in 2.6.25.  Before 2008
the kernel built just fine on a host that didn't have perl installed,
and I've been patching the kernel to remove the requirement ever since
in my own build environment.  (And building the resulting kernel for a
dozen different targets, and submitting those patches here when they
changed.  They just haven't changed in a while.)

Perl is used in exactly three places during the kernel build.  I have
patches to remove the other two instances of perl use, and using them
have built a kernel on a system that doesn't have perl installed.  I'm
tweaking them for submission later today.  My prevoius submissions (such
as http://lkml.indiana.edu/hypermail/linux/kernel/0901.0/00148.html)
treated them as a series, but since the three issues are really
orthogonal I'm posting them individually this time, and cc-ing the
various people get_maintainer.pl says to.

Rob

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Use sed instead of perl to generate x86/kernel/cpu/capflags.c.
  2011-01-16 20:30   ` Rob Landley
@ 2011-01-16 20:39     ` Jesper Juhl
  2011-01-18 20:58       ` Rob Landley
  0 siblings, 1 reply; 6+ messages in thread
From: Jesper Juhl @ 2011-01-16 20:39 UTC (permalink / raw)
  To: Rob Landley
  Cc: linux-kernel, tglx, mingo, hpa, x86, K. Y. Srinivasan,
	Greg Kroah-Hartman

On Sun, 16 Jan 2011, Rob Landley wrote:

> On 01/16/2011 02:05 PM, Jesper Juhl wrote:
> > On Sun, 16 Jan 2011, Rob Landley wrote:
> > 
> >> From: Rob Landley <rlandley@parallels.com>
> >>
> >> Generate capflags.c with sed (POSIX 2008) instead of perl.
> >>
> > 
> > While I'm not personally a great perl fan, this still begs the 
> > question, why?
> 
> 1) In general, simpler is better.  (Why ship autoconf files to build on
> hosts that don't have autoconf?  Why fix make oldconfig so it builds on
> platforms that don't have curses installed?)
> 
> 2) Making reliable cross compile build environments involves creating a
> known build environment on the host, generally removing everything you
> don't actually _need_ so it can't screw things up when you introduce
> another target or upgrade packages on your host.
> 
> I've maintained such a build environment (aboriginal linux) for several
> years.  I've personally encountered literally _dozens_ of others, and
> expect there are at least hundreds if not thousands out in the wild.
> 
> 3) Perl is not a well-defined langauge.  It is a single implementation,
> not a standard.  (Like Microsoft Word and Excel, their file formats are
> just "what this program emits/parses".  Similarly, Perl is what the perl
> binary runs.  Attemts to rewrite it based on Parrot famously collapsed
> into a black hole of corner cases.)
> 
> Meaning, if you have a platform on which the one and only implementation
> of perl doesn't run, you have no alternative implementations to try.
> (Did I mention that Perl's configuration stage is implemented in perl?)
> 
> This moves to an alternative standardized by POSIX, which has well
> understood behavior with multiple independent implementations (gnu, bsd,
> busybox...)
> 
> > We already depend on perl for other stuff, so why replace something that 
> > works with something that may or may not work?
> 
> We have various development scripts that depend on perl, curses, python,
> QT, and so on.  But building a _kernel_ doesn't depend on any of that...
> except perl.  I'm not proposing removing checkstack.pl and such, because
> "development system" != "build machine".  A build machine can be a
> headless box, a development system usually has things like Gnome or KDE
> installed.
> 
> The kernel's dependency on Perl was introduced in 2.6.25.  Before 2008
> the kernel built just fine on a host that didn't have perl installed,
> and I've been patching the kernel to remove the requirement ever since
> in my own build environment.  (And building the resulting kernel for a
> dozen different targets, and submitting those patches here when they
> changed.  They just haven't changed in a while.)
> 
> Perl is used in exactly three places during the kernel build.  I have
> patches to remove the other two instances of perl use, and using them
> have built a kernel on a system that doesn't have perl installed.  I'm
> tweaking them for submission later today.  My prevoius submissions (such
> as http://lkml.indiana.edu/hypermail/linux/kernel/0901.0/00148.html)
> treated them as a series, but since the three issues are really
> orthogonal I'm posting them individually this time, and cc-ing the
> various people get_maintainer.pl says to.
> 

Thanks a lot for spelling out the reasons.
Those are good reasons in my opinion. I'll test your changes once all 3 
are posted and if things still work I'll be sure to reply with a 
Tested-by: to help things along.

-- 
Jesper Juhl <jj@chaosbits.net>            http://www.chaosbits.net/
Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html
Plain text mails only, please.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Use sed instead of perl to generate x86/kernel/cpu/capflags.c.
  2011-01-16 20:39     ` Jesper Juhl
@ 2011-01-18 20:58       ` Rob Landley
  2011-01-19  4:57         ` Américo Wang
  0 siblings, 1 reply; 6+ messages in thread
From: Rob Landley @ 2011-01-18 20:58 UTC (permalink / raw)
  To: Jesper Juhl, Ingo Molnar, H. Peter Anvin, Yinghai Lu, Tejun Heo,
	Don Zickus, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 12373 bytes --]


From: Rob Landley <rlandley@parallels.com>

Replace perl header file generator with smaller/faster/simpler C version.

Signed-off-by: Rob Landley <rlandley@parallels.com>
---

I ran the attached test script to compare the output of the C program
with the output of the perl version for every HZ from 1 to 5000 to make
sure it was producing the same constants.

 kernel/Makefile      |   10 -
 kernel/mktimeconst.c |  109 +++++++++++
 kernel/timeconst.pl  |  378 -----------------------------------------
 3 files changed, 115 insertions(+), 382 deletions(-)

diff --git a/kernel/Makefile b/kernel/Makefile
index 5669f71..ba9ce6d 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -133,8 +133,10 @@ $(obj)/config_data.h: $(obj)/config_data.gz FORCE
 
 $(obj)/time.o: $(obj)/timeconst.h
 
-quiet_cmd_timeconst  = TIMEC   $@
-      cmd_timeconst  = $(PERL) $< $(CONFIG_HZ) > $@
+hostprogs-y	+= mktimeconst
+quiet_cmd_mktimeconst = TIMEC   $@
+	cmd_mktimeconst = $(obj)/mktimeconst $(CONFIG_HZ) $@ || ( rm -f $@ && exit 1 )
+
 targets += timeconst.h
-$(obj)/timeconst.h: $(src)/timeconst.pl FORCE
-	$(call if_changed,timeconst)
+$(obj)/timeconst.h: $(obj)/mktimeconst FORCE
+	$(call if_changed,mktimeconst)
--- /dev/null	2011-01-13 17:00:36.470564274 -0600
+++ b/kernel/mktimeconst.c	2011-01-16 12:44:04.091168778 -0600
@@ -0,0 +1,109 @@
+/* Copyright 2010 Parallels Inc, licensed under GPLv2 */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[])
+{
+	uint64_t hz, periods[] = {1000, 1000000};
+	char *names[] = {"MSEC", "USEC"};
+	FILE *file;
+	int i, j;
+
+	if (argc != 3 || (hz = atol(argv[1])) < 1
+	    || !(file = fopen(argv[2], "w")))
+	{
+		fprintf(stderr, "Usage: mktimeconst HZ FILENAME\n\n");
+		fprintf(stderr, "Generate a header file with constants to convert between\n");
+		fprintf(stderr, "decimal HZ timer ticks and milisecond or microsecond delays,\n");
+		fprintf(stderr, "using reciprocal multiplication to avoid 64 bit division.\n");
+		exit(1);
+	}
+
+	fprintf(file,
+		"/* Automatically generated by kernel/mktimeconst */\n"
+		"/* Conversion constants for HZ == %"PRIu64" */\n\n"
+		"#ifndef __KERNEL_TIMECONST_H\n"
+		"#define __KERNEL_TIMECONST_H\n\n"
+		"#include <linux/param.h>\n"
+		"#include <linux/types.h>\n\n"
+		"#if HZ != %"PRIu64"\n"
+		"#error \"kernel/timeconst.h has the wrong HZ value!\"\n"
+		"#endif\n\n", hz, hz);
+
+	/* Repeat for MSEC and USEC */
+
+	for (i = 0; i < 2; i++) {
+		uint64_t gcd, period;
+
+		/* Find greatest common denominator using Euclid's algorithm. */
+
+		gcd = hz;
+		period = periods[i];
+		while (period) {
+			uint64_t temp = gcd % period;
+			gcd = period;
+			period = temp;
+		}
+
+		/* Output both directions (HZ_TO_PERIOD and PERIOD_TO_HZ) */
+
+		for (j = 0; j < 2; j++) {
+			char name[16];
+			uint64_t from = j ? periods[i] : hz;
+			uint64_t to = j ? hz : periods[i];
+			uint64_t mul32 = 0, adj32 = 0, shift = 0;
+
+			sprintf(name, j ? "%s_TO_HZ" : "HZ_TO_%s", names[i]);
+
+			/* Figure out what shift value gives 32 significant
+			   bits of MUL32 data.  (Worst case to=1 from=1000000
+			   uses 52 bits, to<<shift won't overflow 64 bit math.)
+			*/
+
+			for (;;) {
+				mul32 = ((to << shift) + from - 1) / from;
+				if (mul32 >= (1L<<31))
+					break;
+				shift++;
+			}
+
+			/* ADJ32 is is just (((FROM/GCD)-1)<<SHIFT)/(FROM/GCD)
+			   but this can overflow 64 bit math (examples, HZ=24
+			   or HZ=122).  Worst case scenario uses 32+20+20=72
+			   bits.  Workaround: split off bottom 32 bits and
+			   reassemble after calculation (32+64=96 bits). */
+
+			adj32 = from / gcd;
+
+			if (shift > 32) {
+				uint64_t upper, lower;
+
+				upper = (adj32 - 1) << (shift - 32);
+				lower = (upper % adj32) << 32;
+				adj32 = ((upper/adj32) << 32) + (lower/adj32);
+			} else
+				adj32 = ((adj32 - 1) << shift) / adj32;
+
+			/* Emit the constants into the header file. */
+
+			fprintf(file, "#define %s_MUL32\tU64_C(0x%"PRIx64")\n",
+				name, mul32);
+			fprintf(file, "#define %s_ADJ32\tU64_C(0x%"PRIx64")\n",
+				name, adj32);
+			fprintf(file, "#define %s_SHR32\t%"PRIu64"\n",
+				name, shift);
+			fprintf(file, "#define %s_NUM\t\tU64_C(%"PRIu64")\n",
+				name, to/gcd);
+			fprintf(file, "#define %s_DEN\t\tU64_C(%"PRIu64")\n\n",
+				name, from/gcd);
+		}
+	}
+	fprintf(file, "#endif /* __KERNEL_TIMECONST_H */\n");
+
+	/* Notice if the disk fills up. */
+
+	fflush(stdout);
+	return ferror(stdout);
+}
--- a/kernel/timeconst.pl	2010-12-19 11:33:53.969732934 -0600
+++ /dev/null	2011-01-13 17:00:36.470564274 -0600
@@ -1,378 +0,0 @@
-#!/usr/bin/perl
-# -----------------------------------------------------------------------
-#
-#   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
-#   option) any later version; incorporated herein by reference.
-#
-# -----------------------------------------------------------------------
-#
-
-#
-# Usage: timeconst.pl HZ > timeconst.h
-#
-
-# Precomputed values for systems without Math::BigInt
-# Generated by:
-# timeconst.pl --can 24 32 48 64 100 122 128 200 250 256 300 512 1000 1024 1200
-%canned_values = (
-	24 => [
-		'0xa6aaaaab','0x2aaaaaa',26,
-		125,3,
-		'0xc49ba5e4','0x1fbe76c8b4',37,
-		3,125,
-		'0xa2c2aaab','0xaaaa',16,
-		125000,3,
-		'0xc9539b89','0x7fffbce4217d',47,
-		3,125000,
-	], 32 => [
-		'0xfa000000','0x6000000',27,
-		125,4,
-		'0x83126e98','0xfdf3b645a',36,
-		4,125,
-		'0xf4240000','0x0',17,
-		31250,1,
-		'0x8637bd06','0x3fff79c842fa',46,
-		1,31250,
-	], 48 => [
-		'0xa6aaaaab','0x6aaaaaa',27,
-		125,6,
-		'0xc49ba5e4','0xfdf3b645a',36,
-		6,125,
-		'0xa2c2aaab','0x15555',17,
-		62500,3,
-		'0xc9539b89','0x3fffbce4217d',46,
-		3,62500,
-	], 64 => [
-		'0xfa000000','0xe000000',28,
-		125,8,
-		'0x83126e98','0x7ef9db22d',35,
-		8,125,
-		'0xf4240000','0x0',18,
-		15625,1,
-		'0x8637bd06','0x1fff79c842fa',45,
-		1,15625,
-	], 100 => [
-		'0xa0000000','0x0',28,
-		10,1,
-		'0xcccccccd','0x733333333',35,
-		1,10,
-		'0x9c400000','0x0',18,
-		10000,1,
-		'0xd1b71759','0x1fff2e48e8a7',45,
-		1,10000,
-	], 122 => [
-		'0x8325c53f','0xfbcda3a',28,
-		500,61,
-		'0xf9db22d1','0x7fbe76c8b',35,
-		61,500,
-		'0x8012e2a0','0x3ef36',18,
-		500000,61,
-		'0xffda4053','0x1ffffbce4217',45,
-		61,500000,
-	], 128 => [
-		'0xfa000000','0x1e000000',29,
-		125,16,
-		'0x83126e98','0x3f7ced916',34,
-		16,125,
-		'0xf4240000','0x40000',19,
-		15625,2,
-		'0x8637bd06','0xfffbce4217d',44,
-		2,15625,
-	], 200 => [
-		'0xa0000000','0x0',29,
-		5,1,
-		'0xcccccccd','0x333333333',34,
-		1,5,
-		'0x9c400000','0x0',19,
-		5000,1,
-		'0xd1b71759','0xfff2e48e8a7',44,
-		1,5000,
-	], 250 => [
-		'0x80000000','0x0',29,
-		4,1,
-		'0x80000000','0x180000000',33,
-		1,4,
-		'0xfa000000','0x0',20,
-		4000,1,
-		'0x83126e98','0x7ff7ced9168',43,
-		1,4000,
-	], 256 => [
-		'0xfa000000','0x3e000000',30,
-		125,32,
-		'0x83126e98','0x1fbe76c8b',33,
-		32,125,
-		'0xf4240000','0xc0000',20,
-		15625,4,
-		'0x8637bd06','0x7ffde7210be',43,
-		4,15625,
-	], 300 => [
-		'0xd5555556','0x2aaaaaaa',30,
-		10,3,
-		'0x9999999a','0x1cccccccc',33,
-		3,10,
-		'0xd0555556','0xaaaaa',20,
-		10000,3,
-		'0x9d495183','0x7ffcb923a29',43,
-		3,10000,
-	], 512 => [
-		'0xfa000000','0x7e000000',31,
-		125,64,
-		'0x83126e98','0xfdf3b645',32,
-		64,125,
-		'0xf4240000','0x1c0000',21,
-		15625,8,
-		'0x8637bd06','0x3ffef39085f',42,
-		8,15625,
-	], 1000 => [
-		'0x80000000','0x0',31,
-		1,1,
-		'0x80000000','0x0',31,
-		1,1,
-		'0xfa000000','0x0',22,
-		1000,1,
-		'0x83126e98','0x1ff7ced9168',41,
-		1,1000,
-	], 1024 => [
-		'0xfa000000','0xfe000000',32,
-		125,128,
-		'0x83126e98','0x7ef9db22',31,
-		128,125,
-		'0xf4240000','0x3c0000',22,
-		15625,16,
-		'0x8637bd06','0x1fff79c842f',41,
-		16,15625,
-	], 1200 => [
-		'0xd5555556','0xd5555555',32,
-		5,6,
-		'0x9999999a','0x66666666',31,
-		6,5,
-		'0xd0555556','0x2aaaaa',22,
-		2500,3,
-		'0x9d495183','0x1ffcb923a29',41,
-		3,2500,
-	]
-);
-
-$has_bigint = eval 'use Math::BigInt qw(bgcd); 1;';
-
-sub bint($)
-{
-	my($x) = @_;
-	return Math::BigInt->new($x);
-}
-
-#
-# Constants for division by reciprocal multiplication.
-# (bits, numerator, denominator)
-#
-sub fmul($$$)
-{
-	my ($b,$n,$d) = @_;
-
-	$n = bint($n);
-	$d = bint($d);
-
-	return scalar (($n << $b)+$d-bint(1))/$d;
-}
-
-sub fadj($$$)
-{
-	my($b,$n,$d) = @_;
-
-	$n = bint($n);
-	$d = bint($d);
-
-	$d = $d/bgcd($n, $d);
-	return scalar (($d-bint(1)) << $b)/$d;
-}
-
-sub fmuls($$$) {
-	my($b,$n,$d) = @_;
-	my($s,$m);
-	my($thres) = bint(1) << ($b-1);
-
-	$n = bint($n);
-	$d = bint($d);
-
-	for ($s = 0; 1; $s++) {
-		$m = fmul($s,$n,$d);
-		return $s if ($m >= $thres);
-	}
-	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($$$) {
-	my($b, $t, $hz) = @_;
-	my $s = fmuls($b, $t, $hz);
-	my $m = fmul($s, $t, $hz);
-	my $a = fadj($s, $t, $hz);
-	return (bignum_hex($m), bignum_hex($a), $s);
-}
-
-# Provides numerator, denominator values
-sub numden($$) {
-	my($n, $d) = @_;
-	my $g = bgcd($n, $d);
-	return ($n/$g, $d/$g);
-}
-
-# All values for a specific (time, hz) combo
-sub conversions($$) {
-	my ($t, $hz) = @_;
-	my @val = ();
-
-	# HZ_TO_xx
-	push(@val, muladj(32, $t, $hz));
-	push(@val, numden($t, $hz));
-
-	# xx_TO_HZ
-	push(@val, muladj(32, $hz, $t));
-	push(@val, numden($hz, $t));
-
-	return @val;
-}
-
-sub compute_values($) {
-	my($hz) = @_;
-	my @val = ();
-	my $s, $m, $a, $g;
-
-	if (!$has_bigint) {
-		die "$0: HZ == $hz not canned and ".
-		    "Math::BigInt not available\n";
-	}
-
-	# MSEC conversions
-	push(@val, conversions(1000, $hz));
-
-	# USEC conversions
-	push(@val, conversions(1000000, $hz));
-
-	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) = @_;
-	my $pfx, $bit, $suf, $s, $m, $a;
-
-	print "/* Automatically generated by kernel/timeconst.pl */\n";
-	print "/* Conversion constants for HZ == $hz */\n";
-	print "\n";
-	print "#ifndef KERNEL_TIMECONST_H\n";
-	print "#define KERNEL_TIMECONST_H\n";
-	print "\n";
-
-	print "#include <linux/param.h>\n";
-	print "#include <linux/types.h>\n";
-
-	print "\n";
-	print "#if HZ != $hz\n";
-	print "#error \"kernel/timeconst.h has the wrong HZ value!\"\n";
-	print "#endif\n";
-	print "\n";
-
-	foreach $pfx ('HZ_TO_MSEC','MSEC_TO_HZ',
-		      'HZ_TO_USEC','USEC_TO_HZ') {
-		foreach $bit (32) {
-			foreach $suf ('MUL', 'ADJ', 'SHR') {
-				outputval("${pfx}_$suf$bit", shift(@val));
-			}
-		}
-		foreach $suf ('NUM', 'DEN') {
-			outputval("${pfx}_$suf", shift(@val));
-		}
-	}
-
-	print "\n";
-	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
-if ($hz eq '--can') {
-	shift(@ARGV);
-	@hzlist = sort {$a <=> $b} (@ARGV);
-
-	print "# Precomputed values for systems without Math::BigInt\n";
-	print "# Generated by:\n";
-	print "# timeconst.pl --can ", join(' ', @hzlist), "\n";
-	print "\%canned_values = (\n";
-	my $pf = "\t";
-	foreach $hz (@hzlist) {
-		my @values = compute_values($hz);
-		print "$pf$hz => [\n";
-		while (scalar(@values)) {
-			my $bit;
-			foreach $bit (32) {
-				my $m = shift(@values);
-				my $a = shift(@values);
-				my $s = shift(@values);
-				print "\t\t", perlvals($m,$a,$s), ",\n";
-			}
-			my $n = shift(@values);
-			my $d = shift(@values);
-			print "\t\t", perlvals($n,$d), ",\n";
-		}
-		print "\t]";
-		$pf = ', ';
-	}
-	print "\n);\n";
-} else {
-	$hz += 0;			# Force to number
-	if ($hz < 1) {
-		die "Usage: $0 HZ\n";
-	}
-
-	@val = @{$canned_values{$hz}};
-	if (!defined(@val)) {
-		@val = compute_values($hz);
-	}
-	output($hz, @val);
-}
-exit 0;

[-- Attachment #2: loopy.sh --]
[-- Type: application/x-sh, Size: 354 bytes --]

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] Use sed instead of perl to generate x86/kernel/cpu/capflags.c.
  2011-01-18 20:58       ` Rob Landley
@ 2011-01-19  4:57         ` Américo Wang
  0 siblings, 0 replies; 6+ messages in thread
From: Américo Wang @ 2011-01-19  4:57 UTC (permalink / raw)
  To: Rob Landley
  Cc: Jesper Juhl, Ingo Molnar, H. Peter Anvin, Yinghai Lu, Tejun Heo,
	Don Zickus, linux-kernel

On Tue, Jan 18, 2011 at 02:58:27PM -0600, Rob Landley wrote:
>
>From: Rob Landley <rlandley@parallels.com>
>
>Replace perl header file generator with smaller/faster/simpler C version.
>
>Signed-off-by: Rob Landley <rlandley@parallels.com>

Pretty nice!

One small problem below.

>
>I ran the attached test script to compare the output of the C program
>with the output of the perl version for every HZ from 1 to 5000 to make
>sure it was producing the same constants.
>


I think you can use diff to compare the perl output and C output,
with different HZ values.


>+	fprintf(file, "#endif /* __KERNEL_TIMECONST_H */\n");
>+
>+	/* Notice if the disk fills up. */
>+
>+	fflush(stdout);
>+	return ferror(stdout);


Why do you fflush stdout while you are writing to 'file'?

Thanks.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-01-19  4:57 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-16 19:59 [PATCH] Use sed instead of perl to generate x86/kernel/cpu/capflags.c Rob Landley
2011-01-16 20:05 ` Jesper Juhl
2011-01-16 20:30   ` Rob Landley
2011-01-16 20:39     ` Jesper Juhl
2011-01-18 20:58       ` Rob Landley
2011-01-19  4:57         ` Américo Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.