nvedit: speed up printing of environment
authorMike Frysinger <vapier@gentoo.org>
Sun, 24 May 2009 06:26:19 +0000 (02:26 -0400)
committerWolfgang Denk <wd@denx.de>
Fri, 12 Jun 2009 18:45:48 +0000 (20:45 +0200)
The printing code would check the same environment byte multiple times and
write to the console one byte at a time.  For some devices (such as the
Blackfin JTAG console which operates in 8 bytes at a time), this is pretty
damned slow.  So create a small 16 byte buffer to fill up and send to puts
as needed.  In the process, unify the different print functions, shrink
the resulting code (source and compiled), and avoid excess env reads as
those too can be somewhat expensive depending on the board.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
common/cmd_nvedit.c

index 3ee971ab0e3165c9bbcd680f6994b6b1833ddef1..ac9e5cfc3205797de41d3d0bba9e26bc3982e827 100644 (file)
@@ -94,56 +94,72 @@ int get_env_id (void)
  * Command interface: print one or all environment variables
  */
 
-int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+/*
+ * state 0: finish printing this string and return (matched!)
+ * state 1: no matching to be done; print everything
+ * state 2: continue searching for matched name
+ */
+static int printenv(char *name, int state)
 {
-       int i, j, k, nxt;
-       int rcode = 0;
-
-       if (argc == 1) {                /* Print all env variables      */
-               for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
-                       for (nxt=i; env_get_char(nxt) != '\0'; ++nxt)
-                               ;
-                       for (k=i; k<nxt; ++k)
-                               putc(env_get_char(k));
-                       putc  ('\n');
-
-                       if (ctrlc()) {
-                               puts ("\n ** Abort\n");
-                               return 1;
+       int i, j;
+       char c, buf[17];
+
+       i = 0;
+       buf[16] = '\0';
+
+       while (state && env_get_char(i) != '\0') {
+               if (state == 2 && envmatch((uchar *)name, i) >= 0)
+                       state = 0;
+
+               j = 0;
+               do {
+                       buf[j++] = c = env_get_char(i++);
+                       if (j == sizeof(buf) - 1) {
+                               if (state <= 1)
+                                       puts(buf);
+                               j = 0;
                        }
-               }
+               } while (c != '\0');
 
-               printf("\nEnvironment size: %d/%ld bytes\n",
-                       i, (ulong)ENV_SIZE);
+               if (state <= 1) {
+                       if (j)
+                               puts(buf);
+                       putc('\n');
+               }
 
-               return 0;
+               if (ctrlc())
+                       return -1;
        }
 
-       for (i=1; i<argc; ++i) {        /* print single env variables   */
-               char *name = argv[i];
+       if (state == 0)
+               i = 0;
+       return i;
+}
 
-               k = -1;
+int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       int i;
+       int rcode = 0;
 
-               for (j=0; env_get_char(j) != '\0'; j=nxt+1) {
+       if (argc == 1) {
+               /* print all env vars */
+               rcode = printenv(NULL, 1);
+               if (rcode < 0)
+                       return 1;
+               printf("\nEnvironment size: %d/%ld bytes\n",
+                       rcode, (ulong)ENV_SIZE);
+               return 0;
+       }
 
-                       for (nxt=j; env_get_char(nxt) != '\0'; ++nxt)
-                               ;
-                       k = envmatch((uchar *)name, j);
-                       if (k < 0) {
-                               continue;
-                       }
-                       puts (name);
-                       putc ('=');
-                       while (k < nxt)
-                               putc(env_get_char(k++));
-                       putc ('\n');
-                       break;
-               }
-               if (k < 0) {
-                       printf ("## Error: \"%s\" not defined\n", name);
-                       rcode ++;
+       /* print selected env vars */
+       for (i = 1; i < argc; ++i) {
+               char *name = argv[i];
+               if (printenv(name, 2)) {
+                       printf("## Error: \"%s\" not defined\n", name);
+                       ++rcode;
                }
        }
+
        return rcode;
 }