From b0161972b61f32e3939b1d00ed596a51f2d9df53 Mon Sep 17 00:00:00 2001 From: kib Date: Wed, 18 Jul 2018 09:54:32 +0000 Subject: [PATCH] MFC r335939, r336088: Add setproctitle_fast(3) for frequent callers. --- include/unistd.h | 1 + lib/libc/gen/Symbol.map | 1 + lib/libc/gen/setproctitle.3 | 14 ++++++- lib/libc/gen/setproctitle.c | 75 +++++++++++++++++++++++++++---------- 4 files changed, 70 insertions(+), 21 deletions(-) diff --git a/include/unistd.h b/include/unistd.h index fc310646654..c91fd592c21 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -569,6 +569,7 @@ int setloginclass(const char *); void *setmode(const char *); int setpgrp(pid_t, pid_t); /* obsoleted by setpgid() */ void setproctitle(const char *_fmt, ...) __printf0like(1, 2); +void setproctitle_fast(const char *_fmt, ...) __printf0like(1, 2); int setresgid(gid_t, gid_t, gid_t); int setresuid(uid_t, uid_t, uid_t); int setrgid(gid_t); diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index cb4e4da69fc..56e1006f2b5 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -420,6 +420,7 @@ FBSD_1.4 { FBSD_1.5 { sem_clockwait_np; + setproctitle_fast; }; FBSDprivate_1.0 { diff --git a/lib/libc/gen/setproctitle.3 b/lib/libc/gen/setproctitle.3 index 955556e5b20..af8e885b5d0 100644 --- a/lib/libc/gen/setproctitle.3 +++ b/lib/libc/gen/setproctitle.3 @@ -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 diff --git a/lib/libc/gen/setproctitle.c b/lib/libc/gen/setproctitle.c index fd87c350715..a631c70e1e9 100644 --- a/lib/libc/gen/setproctitle.c +++ b/lib/libc/gen/setproctitle.c @@ -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; - - 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); + return (NULL); 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; + } } -- 2.45.0