public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: libc-alpha@sourceware.org
Subject: [PATCH 07/11] misc: syslog: Use static buffer
Date: Mon, 12 Apr 2021 18:11:09 -0300	[thread overview]
Message-ID: <20210412211113.393120-7-adhemerval.zanella@linaro.org> (raw)
In-Reply-To: <20210412211113.393120-1-adhemerval.zanella@linaro.org>

The static buffer is used instead of memstream for messages up to
1024 bytes to avoid the potential BUFSIZ (8K) malloc and free for
each syslog call.  The memstream is still used as fallback for
larger messages.

Checked on x86_64-linux-gnu.
---
 misc/syslog.c | 102 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 68 insertions(+), 34 deletions(-)

diff --git a/misc/syslog.c b/misc/syslog.c
index cb608766cb..a310eba476 100644
--- a/misc/syslog.c
+++ b/misc/syslog.c
@@ -115,12 +115,11 @@ void
 __vsyslog_internal (int pri, const char *fmt, va_list ap,
                     unsigned int mode_flags)
 {
-  FILE *f;
-  char *buf = 0;
+  char *buf = NULL;
   size_t bufsize = 0;
+  bool buf_to_free = false;
   int msgoff;
   int saved_errno = errno;
-  char failbuf[3 * sizeof (pid_t) + sizeof "out of memory []"];
 
 #define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
   /* Check for invalid bits.  */
@@ -144,42 +143,77 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
   if ((pri & LOG_FACMASK) == 0)
     pri |= LogFacility;
 
-  /* Build the message in a memory-buffer stream.  */
-  f = __open_memstream (&buf, &bufsize);
-  if (f != NULL)
+  pid_t pid = LogStat & LOG_PID ? __getpid () : 0;
+
+  enum
+    {
+      timebuf_size = 3+1                     /* "%h "  */
+                     + 2+1                   /* "%e "  */
+                     + 2+1 + 2+1 + 2+1 + 1,  /* "%T "  */
+
+      bufs_size    = 1024
+    };
+
+  /* "%h %e %H:%M:%S "  */
+  char timestamp[timebuf_size];
+  time_t now = time_now ();
+  struct tm now_tm;
+  __localtime_r (&now, &now_tm);
+  __strftime_l (timestamp, sizeof (timestamp), "%h %e %T ", &now_tm,
+                _nl_C_locobj_ptr);
+
+#define SYSLOG_HEADER(__pri, __timestamp, __msgoff, pid) \
+  "<%d>%s %n%s%s%.0d%s: ",                               \
+  __pri, __timestamp, __msgoff,                          \
+  LogTag == NULL ? __progname : LogTag,                  \
+  pid != 0 ? "[" : "", pid, pid != 0 ? "]" : ""
+
+  /* Try to use a static buffer as an optimization.  */
+  char bufs[bufs_size];
+  int l = __snprintf (bufs, sizeof bufs,
+                      SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
+  if (l < sizeof (bufs))
     {
-      __fsetlocking (f, FSETLOCKING_BYCALLER);
-
-      /* "%h %e %H:%M:%S "  */
-      char timebuf[3+1                   /* "%h "  */
-                   + 2+1                 /* "%e "  */
-                   + 2+1 + 2+1 + 2+1 + 1 /* "%T "  */];
-      time_t now = time_now ();
-      struct tm now_tm;
-      __localtime_r (&now, &now_tm);
-      __strftime_l (timebuf, sizeof (timebuf), "%h %e %T ", &now_tm,
-                    _nl_C_locobj_ptr);
-
-      pid_t pid = LogStat & LOG_PID ? __getpid () : 0;
-
-      fprintf (f, "<%d>%s %n%s%s%.0d%s: ", pri, timebuf, &msgoff,
-               LogTag == NULL ? __progname : LogTag,
-               pid != 0 ? "[" : "", pid, pid != 0 ? "]" : "");
+      va_list apc;
+      va_copy (apc, ap);
+
       /* Restore errno for %m format.  */
       __set_errno (saved_errno);
-      __vfprintf_internal (f, fmt, ap, mode_flags);
-      fclose (f);
+      int vl = __vsnprintf_internal (bufs + l, sizeof (bufs) - l, fmt, apc,
+                                     mode_flags);
+      if (l + vl < sizeof (bufs))
+        {
+          buf = bufs;
+          bufsize = l + vl;
+        }
 
-      /* Tell the cancellation handler to free this buffer.  */
-      clarg.buf = buf;
+      va_end (apc);
     }
-  else
+
+  /* If the required size is larger than buffer size fallbacks to
+     open_memstream.  */
+  if (buf == NULL)
     {
-      /* We cannot get a stream.  There is not much we can do but emitting an
-         error messages.  */
-      bufsize = __snprintf (failbuf, sizeof failbuf, "out of memory[%d]",
-                            __getpid ());
-      buf = failbuf;
+      FILE *f = __open_memstream (&buf, &bufsize);
+      if (f != NULL)
+        {
+          __fsetlocking (f, FSETLOCKING_BYCALLER);
+          fprintf (f, SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
+          /* Restore errno for %m format.  */
+          __set_errno (saved_errno);
+          __vfprintf_internal (f, fmt, ap, mode_flags);
+          fclose (f);
+
+          /* Tell the cancellation handler to free this buffer.  */
+          buf_to_free = true;
+          clarg.buf = buf;
+        }
+      else
+        {
+          bufsize = __snprintf (bufs, sizeof bufs,
+                                "out of memory[%d]", __getpid ());
+          buf = bufs;
+        }
     }
 
   /* Output to stderr if requested.  */
@@ -229,7 +263,7 @@ out:
   __libc_cleanup_pop (0);
   __libc_lock_unlock (syslog_lock);
 
-  if (buf != failbuf)
+  if (buf_to_free)
     free (buf);
 }
 
-- 
2.27.0


  parent reply	other threads:[~2021-04-12 21:11 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-12 21:11 [PATCH 01/11] support: Add xmkfifo Adhemerval Zanella
2021-04-12 21:11 ` [PATCH 02/11] misc: Add syslog test Adhemerval Zanella
2021-04-12 21:11 ` [PATCH 03/11] misc: syslog: Fix indentation and style Adhemerval Zanella
2021-04-12 21:11 ` [PATCH 04/11] misc: syslog: Use bool for connected Adhemerval Zanella
2021-04-14 14:54   ` Andreas Schwab
2021-04-12 21:11 ` [PATCH 05/11] misc: syslog: Assume MSG_NOSIGNAL support (BZ #17144) Adhemerval Zanella
2021-04-14 14:57   ` Andreas Schwab
2021-04-12 21:11 ` [PATCH 06/11] misc: syslog: Simplify implementation Adhemerval Zanella
2021-04-12 21:11 ` Adhemerval Zanella [this message]
2021-04-12 21:11 ` [PATCH 08/11] misc: syslog: Use CLOC_EXEC with _PATH_CONSOLE (BZ #17145) Adhemerval Zanella
2021-04-14 15:00   ` Andreas Schwab
2021-04-12 21:11 ` [PATCH 09/11] misc: syslog: Use static const for AF_UNIX address Adhemerval Zanella
2021-04-14 15:03   ` Andreas Schwab
2021-04-12 21:11 ` [PATCH 10/11] misc: syslog: Move SYSLOG_NAME to USE_MISC (BZ #16355) Adhemerval Zanella
2021-04-12 21:11 ` [PATCH 11/11] misc: syslog: Use RFC5424 Adhemerval Zanella

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210412211113.393120-7-adhemerval.zanella@linaro.org \
    --to=adhemerval.zanella@linaro.org \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).