svn commit: r335939 - head/lib/libc/gen

Konstantin Belousov kib at FreeBSD.org
Wed Jul 4 13:31:18 UTC 2018


Author: kib
Date: Wed Jul  4 13:31:16 2018
New Revision: 335939
URL: https://svnweb.freebsd.org/changeset/base/335939

Log:
  Add setproctitle_fast(3) for frequent callers.
  
  Some applications, notably PostgreSQL, want to call setproctitle()
  very often.  It's slow.  Provide an alternative cheap way of updating
  process titles without making any syscalls, instead requiring other
  processes (top, ps etc) to do a bit more work to retrieve the data.
  This uses a pre-existing code path inherited from ancient BSD, which
  always did it that way.
  
  Submitted by:	Thomas Munro
  MFC after:	2 weeks
  Differential revision:	https://reviews.freebsd.org/D16111

Modified:
  head/lib/libc/gen/Symbol.map
  head/lib/libc/gen/setproctitle.3
  head/lib/libc/gen/setproctitle.c

Modified: head/lib/libc/gen/Symbol.map
==============================================================================
--- head/lib/libc/gen/Symbol.map	Wed Jul  4 13:28:43 2018	(r335938)
+++ head/lib/libc/gen/Symbol.map	Wed Jul  4 13:31:16 2018	(r335939)
@@ -419,6 +419,7 @@ FBSD_1.5 {
 	scandir;
 	scandir_b;
 	sem_clockwait_np;
+	setproctitle_fast;
 };
 
 FBSDprivate_1.0 {

Modified: head/lib/libc/gen/setproctitle.3
==============================================================================
--- head/lib/libc/gen/setproctitle.3	Wed Jul  4 13:28:43 2018	(r335938)
+++ head/lib/libc/gen/setproctitle.3	Wed Jul  4 13:31:16 2018	(r335939)
@@ -20,7 +20,7 @@
 .\" $FreeBSD$
 .\"
 .\" The following requests are required for all man pages.
-.Dd December 16, 1995
+.Dd July 4, 2018
 .Dt SETPROCTITLE 3
 .Os
 .Sh NAME
@@ -31,12 +31,20 @@
 .In unistd.h
 .Ft void
 .Fn setproctitle "const char *fmt" "..."
+.Ft void
+.Fn setproctitle_fast "const char *fmt" "..."
 .Sh DESCRIPTION
 The
 .Fn setproctitle
 library routine sets the process title that appears on the
 .Xr ps 1
 command.
+The
+.Fn setproctitle_fast
+variant is optimized for high frequency updates, but may make the
+.Xr ps 1
+command slightly slower by not updating the kernel cache of the program
+arguments.
 .Pp
 The title is set from the executable's name, followed by the
 result of a
@@ -96,6 +104,10 @@ The
 function
 first appeared in
 .Fx 2.2 .
+The
+.Fn setproctitle_fast
+function first appeared in
+.Fx 12 .
 Other operating systems have
 similar functions.
 .Sh AUTHORS

Modified: head/lib/libc/gen/setproctitle.c
==============================================================================
--- head/lib/libc/gen/setproctitle.c	Wed Jul  4 13:28:43 2018	(r335938)
+++ head/lib/libc/gen/setproctitle.c	Wed Jul  4 13:31:16 2018	(r335939)
@@ -55,8 +55,8 @@ struct old_ps_strings {
 
 #define SPT_BUFSIZE 2048	/* from other parts of sendmail */
 
-void
-setproctitle(const char *fmt, ...)
+static char *
+setproctitle_internal(const char *fmt, va_list ap)
 {
 	static struct ps_strings *ps_strings;
 	static char *buf = NULL;
@@ -67,27 +67,23 @@ setproctitle(const char *fmt, ...)
 	char **nargvp;
 	int nargc;
 	int i;
-	va_list ap;
 	size_t len;
 	unsigned long ul_ps_strings;
-	int oid[4];
 
 	if (buf == NULL) {
 		buf = malloc(SPT_BUFSIZE);
 		if (buf == NULL) 
-			return;
+			return (NULL);
 		nargv[0] = buf;
 	}
 
 	if (obuf == NULL ) {
 		obuf = malloc(SPT_BUFSIZE);
 		if (obuf == NULL)
-			return;
+			return (NULL);
 		*obuf = '\0';
 	}
 
-	va_start(ap, fmt);
-
 	if (fmt) {
 		buf[SPT_BUFSIZE - 1] = '\0';
 
@@ -114,22 +110,13 @@ setproctitle(const char *fmt, ...)
 		kbuf = obuf;
 	} else
 		/* Nothing to restore */
-		return;
+		return (NULL);
 
-	va_end(ap);
-
-	/* Set the title into the kernel cached command line */
-	oid[0] = CTL_KERN;
-	oid[1] = KERN_PROC;
-	oid[2] = KERN_PROC_ARGS;
-	oid[3] = getpid();
-	sysctl(oid, 4, 0, 0, kbuf, strlen(kbuf) + 1);
-
 	if (ps_strings == NULL) {
 		len = sizeof(ul_ps_strings);
 		if (sysctlbyname("kern.ps_strings", &ul_ps_strings, &len, NULL,
 		    0) == -1)
-			return;
+			return (NULL);
 		ps_strings = (struct ps_strings *)ul_ps_strings;
 	}
 
@@ -138,7 +125,7 @@ setproctitle(const char *fmt, ...)
 	 * Should not happen.
 	 */
 	if (ps_strings->ps_argvstr == NULL)
-		return;
+		return (NULL);
 
 	/* style #3 */
 	if (oargc == -1) {
@@ -167,4 +154,52 @@ setproctitle(const char *fmt, ...)
 	}
 	ps_strings->ps_nargvstr = nargc;
 	ps_strings->ps_argvstr = nargvp;
+
+	return (nargvp[0]);
+}
+
+static int fast_update = 0;
+
+void
+setproctitle_fast(const char *fmt, ...)
+{
+	va_list ap;
+	char *buf;
+	int oid[4];
+
+	va_start(ap, fmt);
+	buf = setproctitle_internal(fmt, ap);
+	va_end(ap);
+
+	if (buf && !fast_update) {
+		/* Tell the kernel to start looking in user-space */
+		oid[0] = CTL_KERN;
+		oid[1] = KERN_PROC;
+		oid[2] = KERN_PROC_ARGS;
+		oid[3] = getpid();
+		sysctl(oid, 4, 0, 0, "", 0);
+		fast_update = 1;
+	}
+}
+
+void
+setproctitle(const char *fmt, ...)
+{
+	va_list ap;
+	char *buf;
+	int oid[4];
+
+	va_start(ap, fmt);
+	buf = setproctitle_internal(fmt, ap);
+	va_end(ap);
+
+	if (buf != NULL) {
+		/* Set the title into the kernel cached command line */
+		oid[0] = CTL_KERN;
+		oid[1] = KERN_PROC;
+		oid[2] = KERN_PROC_ARGS;
+		oid[3] = getpid();
+		sysctl(oid, 4, 0, 0, buf, strlen(buf) + 1);
+		fast_update = 0;
+	}
 }


More information about the svn-src-all mailing list