NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/44864: sysctl unnecessarily recompiling regex



>Number:         44864
>Category:       bin
>Synopsis:       sysctl unnecessarily recompiling regex
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Apr 13 10:05:00 +0000 2011
>Originator:     Paul Ripke
>Release:        NetBSD 5.99.22 and up, at least
>Organization:
Paul Ripke
I love deadlines. I like the whooshing sound they make as they fly by.
-- Douglas Adams
>Environment:
System: NetBSD kitt.stix.org.au 5.99.22 NetBSD 5.99.22 (KITT) #0: Sun Dec 13 
23:56:43 EST 2009 
stix%hex.stix.org.au@localhost:/hex/netbsd/20091212T0002/obj.mac68k/hex/netbsd/20091212T0002/src/sys/arch/mac68k/compile/KITT
 mac68k

Architecture: m68k
Machine: mac68k
>Description:
sysctl -a (or with any pattern) is woefully slow.

On my trusty slow box, without patch:
kitt:ksh$ time /sbin/sysctl -a > /dev/null
   23.75s real    20.50s user     0.65s system

With patch:
kitt:ksh$ time ./sysctl -a > /dev/null
    3.06s real     2.18s user     0.51s system

>How-To-Repeat:
Use sysctl with any pattern matching or even -a.

>Fix:

Index: sbin/sysctl/sysctl.c
===================================================================
RCS file: /usr/netbsd/cvsroot/src/sbin/sysctl/sysctl.c,v
retrieving revision 1.133
diff -u -d -r1.133 sysctl.c
--- sbin/sysctl/sysctl.c        13 Dec 2010 17:47:40 -0000      1.133
+++ sbin/sysctl/sysctl.c        13 Apr 2011 05:33:24 -0000
@@ -380,32 +380,37 @@
 findhandler(const char *s, int w)
 {
        const struct handlespec *p;
-       regex_t re;
+       static regex_t *re = NULL;
        int i, j, l;
        char eb[64];
        regmatch_t match[1];
 
        p = &handlers[0];
        l = strlen(s);
-       for (i = 0; p[i].ps_re != NULL; i++) {
-               j = regcomp(&re, p[i].ps_re, REG_EXTENDED);
-               if (j != 0) {
-                       regerror(j, &re, eb, sizeof(eb));
-                       errx(1, "regcomp: %s: %s", p[i].ps_re, eb);
+       if (re == NULL) {
+               for (i = 0; p[i].ps_re != NULL; i++)
+                       ;
+               re = malloc(sizeof(*re) * i);
+               for (i = 0; p[i].ps_re != NULL; i++) {
+                       j = regcomp(&re[i], p[i].ps_re, REG_EXTENDED);
+                       if (j != 0) {
+                               regerror(j, &re[i], eb, sizeof(eb));
+                               errx(1, "regcomp: %s: %s", p[i].ps_re, eb);
+                       }
                }
-               j = regexec(&re, s, 1, match, 0);
+       }
+       for (i = 0; p[i].ps_re != NULL; i++) {
+               j = regexec(&re[i], s, 1, match, 0);
                if (j == 0) {
                        if (match[0].rm_so == 0 && match[0].rm_eo == l &&
                            (w ? p[i].ps_w : p[i].ps_p) != NULL) {
-                               regfree(&re);
                                return (&p[i]);
                        }
                }
                else if (j != REG_NOMATCH) {
-                       regerror(j, &re, eb, sizeof(eb));
+                       regerror(j, &re[i], eb, sizeof(eb));
                        errx(1, "regexec: %s: %s", p[i].ps_re, eb);
                }
-               regfree(&re);
        }
 
        return (NULL);



Home | Main Index | Thread Index | Old Index