On Fri, Jul 29, 2022 at 08:13:14AM -0500, Scott Cheloha wrote:
> On Wed, Jul 13, 2022 at 12:50:24AM -0500, Scott Cheloha wrote:
> > We reduce overhead if we only parse the user's format string once.  To
> > achieve that, this patch does the following:
> > 
> > [...]
> > 
> > - When parsing the user format string in fmtfmt(), keep a list of
> >   where each microsecond substring lands in buf.  We'll need it later.
> > 
> > - Move the printing part of fmtfmt() into a new function, fmtprint().
> >   fmtprint() is now called from the main loop instead of fmtfmt().
> > 
> > - In fmtprint(), before calling strftime(3), update any microsecond
> >   substrings in buf using the list we built earlier in fmtfmt().  Note
> >   that if there aren't any such substrings we don't call snprintf(3)
> >   at all.
> > 
> > [...]
> 
> Two week bump.
> 
> Here is a stripped-down patch with only the above changes.  Hopefully
> this makes the intent of the patch more obvious.

Four week bump + rebase.

Index: ts.c
===================================================================
RCS file: /cvs/src/usr.bin/ts/ts.c,v
retrieving revision 1.9
diff -u -p -r1.9 ts.c
--- ts.c        3 Aug 2022 16:54:30 -0000       1.9
+++ ts.c        10 Aug 2022 17:49:53 -0000
@@ -17,6 +17,7 @@
  */
 
 #include <sys/types.h>
+#include <sys/queue.h>
 #include <sys/time.h>
 
 #include <err.h>
@@ -27,13 +28,20 @@
 #include <unistd.h>
 #include <time.h>
 
+SIMPLEQ_HEAD(, usec) usec_queue = SIMPLEQ_HEAD_INITIALIZER(usec_queue);
+struct usec {
+       SIMPLEQ_ENTRY(usec) next;
+       char *pos;
+};
+
 static char            *format = "%b %d %H:%M:%S";
 static char            *buf;
 static char            *outbuf;
 static size_t           bufsize;
 static size_t           obsize;
 
-static void             fmtfmt(const struct timespec *);
+static void             fmtfmt(void);
+static void             fmtprint(const struct timespec *);
 static void __dead      usage(void);
 
 int
@@ -90,6 +98,8 @@ main(int argc, char *argv[])
        if ((outbuf = calloc(1, obsize)) == NULL)
                err(1, NULL);
 
+       fmtfmt();
+
        /* force UTC for interval calculations */
        if (iflag || sflag)
                if (setenv("TZ", "UTC", 1) == -1)
@@ -108,7 +118,7 @@ main(int argc, char *argv[])
                                timespecadd(&now, &utc_offset, &ts);
                        else
                                ts = now;
-                       fmtfmt(&ts);
+                       fmtprint(&ts);
                        if (iflag)
                                start = now;
                }
@@ -134,15 +144,11 @@ usage(void)
  * so you can format while you format
  */
 static void
-fmtfmt(const struct timespec *ts)
+fmtfmt(void)
 {
-       struct tm *tm;
-       char *f, us[7];
-
-       if ((tm = localtime(&ts->tv_sec)) == NULL)
-               err(1, "localtime");
+       char *f;
+       struct usec *u;
 
-       snprintf(us, sizeof(us), "%06ld", ts->tv_nsec / 1000);
        strlcpy(buf, format, bufsize);
        f = buf;
 
@@ -161,12 +167,34 @@ fmtfmt(const struct timespec *ts)
                        f[0] = f[1];
                        f[1] = '.';
                        f += 2;
+                       u = malloc(sizeof u);
+                       if (u == NULL)
+                               err(1, NULL);
+                       u->pos = f;
+                       SIMPLEQ_INSERT_TAIL(&usec_queue, u, next);
                        l = strlen(f);
                        memmove(f + 6, f, l + 1);
-                       memcpy(f, us, 6);
                        f += 6;
                }
        } while (*f != '\0');
+}
+
+static void
+fmtprint(const struct timespec *ts)
+{
+       char us[8];
+       struct tm *tm;
+       struct usec *u;
+
+       if ((tm = localtime(&ts->tv_sec)) == NULL)
+               err(1, "localtime");
+
+       /* Update any microsecond substrings in the format buffer. */
+       if (!SIMPLEQ_EMPTY(&usec_queue)) {
+               snprintf(us, sizeof(us), "%06ld", ts->tv_nsec / 1000);
+               SIMPLEQ_FOREACH(u, &usec_queue, next)
+                       memcpy(u->pos, us, 6);
+       }
 
        *outbuf = '\0';
        if (*buf != '\0') {

Reply via email to