From: Holger Hans Peter Freyther <hol...@moiji-mobile.com> Avoid memory allocations to construct the path for files in the procfs. The procfs paths are way shorter than the PATH_MAX so we can use snprintf on a string located on the stack. This shows up as a win on x86 using the benchmark program below.
$ make libsystemd-shared.la; gcc -O2 -Isrc/systemd/ -Isrc/ \ -o simple-perf-test simple-perf-test.c \ .libs/libsystemd-shared.a -lrt #include "shared/util.h" void test_once(void) { pid_t pid = getpid(); char *tmp = NULL; get_process_comm(pid, &tmp); free(tmp); tmp = NULL; get_process_cmdline(pid, 0, 1, &tmp); free(tmp); is_kernel_thread(pid); tmp = NULL; get_process_exe(pid, &tmp); free(tmp); } int main(int argc, char **argv) { int i; for (i = 0; i < 50000; ++i) test_once(); } --- src/shared/util.c | 48 +++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/src/shared/util.c b/src/shared/util.c index b516b9b..ce8f866 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -567,6 +567,10 @@ char *truncate_nl(char *s) { return s; } +#define format_procfs_path(buffer, path, pid) \ + snprintf(buffer, sizeof(buffer) - 1, "/proc/%lu/%s", (unsigned long) pid, path); \ + char_array_0(buffer); + int get_process_comm(pid_t pid, char **name) { int r; @@ -575,12 +579,9 @@ int get_process_comm(pid_t pid, char **name) { if (pid == 0) r = read_one_line_file("/proc/self/comm", name); else { - char *p; - if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0) - return -ENOMEM; - - r = read_one_line_file(p, name); - free(p); + char path[PATH_MAX]; + format_procfs_path(path, "comm", pid); + r = read_one_line_file(path, name); } return r; @@ -596,12 +597,9 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * if (pid == 0) f = fopen("/proc/self/cmdline", "re"); else { - char *p; - if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0) - return -ENOMEM; - - f = fopen(p, "re"); - free(p); + char path[PATH_MAX]; + format_procfs_path(path, "cmdline", pid); + f = fopen(path, "re"); } if (!f) @@ -688,7 +686,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * } int is_kernel_thread(pid_t pid) { - char *p; + char path[PATH_MAX]; size_t count; char c; bool eof; @@ -697,11 +695,8 @@ int is_kernel_thread(pid_t pid) { if (pid == 0) return 0; - if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0) - return -ENOMEM; - - f = fopen(p, "re"); - free(p); + format_procfs_path(path, "cmdline", pid); + f = fopen(path, "re"); if (!f) return -errno; @@ -726,12 +721,9 @@ int get_process_exe(pid_t pid, char **name) { if (pid == 0) r = readlink_malloc("/proc/self/exe", name); else { - char *p; - if (asprintf(&p, "/proc/%lu/exe", (unsigned long) pid) < 0) - return -ENOMEM; - - r = readlink_malloc(p, name); - free(p); + char path[PATH_MAX]; + format_procfs_path(path, "exe", pid); + r = readlink_malloc(path, name); } return r; @@ -739,7 +731,7 @@ int get_process_exe(pid_t pid, char **name) { static int get_process_id(pid_t pid, const char *field, uid_t *uid) { _cleanup_fclose_ FILE *f = NULL; - _cleanup_free_ char *p = NULL; + char path[PATH_MAX]; char line[LINE_MAX]; assert(field); @@ -748,10 +740,8 @@ static int get_process_id(pid_t pid, const char *field, uid_t *uid) { if (pid == 0) return getuid(); - if (asprintf(&p, "/proc/%lu/status", (unsigned long) pid) < 0) - return -ENOMEM; - - f = fopen(p, "re"); + format_procfs_path(path, "status", pid); + f = fopen(path, "re"); if (!f) return -errno; -- 1.7.10.4 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel