From 6ed404cbc9896dc5b75ef7eaf5e44e5b53a8d152 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Tue, 31 Mar 2015 20:33:54 +0000 Subject: [PATCH 1/4] multicpu1sec-c: ignoring generated files --- plugins/system/multicpu1sec/.gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 plugins/system/multicpu1sec/.gitignore diff --git a/plugins/system/multicpu1sec/.gitignore b/plugins/system/multicpu1sec/.gitignore new file mode 100644 index 00000000..4ff4b96f --- /dev/null +++ b/plugins/system/multicpu1sec/.gitignore @@ -0,0 +1,4 @@ +/multicpu1sec-c +/multicpu1sec.o +/multicpu1sec.pid +/multicpu1sec.value From 7d88587fb6d5b0a33939b75cf38bbf5cb44c82de Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Tue, 31 Mar 2015 22:17:16 +0000 Subject: [PATCH 2/4] multicpu1sec-c: use plain POSIX instead of stdlib As it will be used every second, we should limit the overhead --- plugins/system/multicpu1sec/multicpu1sec-c.c | 44 ++++++++++++-------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/plugins/system/multicpu1sec/multicpu1sec-c.c b/plugins/system/multicpu1sec/multicpu1sec-c.c index b66eab79..f3d00684 100644 --- a/plugins/system/multicpu1sec/multicpu1sec-c.c +++ b/plugins/system/multicpu1sec/multicpu1sec-c.c @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -110,36 +111,45 @@ int acquire() { time_t epoch = wait_until_next_second(); /* Reading /proc/stat */ - FILE* f = fopen(PROC_STAT, "r"); - // Read and ignore the 1rst line - char buffer[1024]; - fgets(buffer, 1024, f); + int f = open(PROC_STAT, O_RDONLY); + + const int buffer_size = 64 * 1024; + char buffer[buffer_size]; + + // whole /proc/stat can be read in 1 syscall + if (read(f, buffer, buffer_size) <= 0) { + return fail("cannot read " PROC_STAT); + } + + // ignore the 1rst line + char* line; + const char* newl = "\n"; + line = strtok(buffer, newl); /* open the spoolfile */ - FILE* cache_file = fopen(cache_filename, "a"); + int cache_file = open(cache_filename, O_CREAT | O_APPEND | O_WRONLY); + /* lock */ - flock(fileno(cache_file), LOCK_EX); - - while (! feof(f)) { - if (fgets(buffer, 1024, f) == 0) { - // EOF - break; - } + flock(cache_file, LOCK_EX); + for (line = strtok(NULL, newl); line; line = strtok(NULL, newl)) { // Not on CPU lines anymore - if (strncmp(buffer, "cpu", 3)) break; + if (strncmp(line, "cpu", 3)) break; char cpu_id[64]; long usr, nice, sys, idle, iowait, irq, softirq; - sscanf(buffer, "%s %ld %ld %ld %ld %ld %ld %ld", cpu_id, &usr, &nice, &sys, &idle, &iowait, &irq, &softirq); + sscanf(line, "%s %ld %ld %ld %ld %ld %ld %ld", cpu_id, &usr, &nice, &sys, &idle, &iowait, &irq, &softirq); long used = usr + nice + sys + iowait + irq + softirq; - fprintf(cache_file, "%s.value %ld:%ld\n", cpu_id, epoch, used); + char out_buffer[1024]; + sprintf(out_buffer, "%s.value %ld:%ld\n", cpu_id, epoch, used); + + write(cache_file, out_buffer, strlen(out_buffer)); } - fclose(cache_file); - fclose(f); + close(cache_file); + close(f); } } From 2db160e26812a4f8bfdcbb700a7d1443b180924a Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Tue, 26 May 2015 20:50:26 +0000 Subject: [PATCH 3/4] p/multicpu1sec-c: use posix IO instead of stdlib --- plugins/system/multicpu1sec/multicpu1sec-c.c | 25 +++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/plugins/system/multicpu1sec/multicpu1sec-c.c b/plugins/system/multicpu1sec/multicpu1sec-c.c index f3d00684..9997ef6f 100644 --- a/plugins/system/multicpu1sec/multicpu1sec-c.c +++ b/plugins/system/multicpu1sec/multicpu1sec-c.c @@ -21,23 +21,30 @@ int fail(char* msg) { int config() { /* Get the number of CPU */ - FILE* f; - if ( !(f=fopen(PROC_STAT, "r")) ) { + int f; + if ( !(f=open(PROC_STAT, O_RDONLY)) ) { return fail("cannot open " PROC_STAT); } // Starting with -1, since the first line is the "global cpu line" int ncpu = -1; - while (! feof(f)) { - char buffer[1024]; - if (fgets(buffer, 1024, f) == 0) { - break; - } - if (! strncmp(buffer, "cpu", 3)) ncpu ++; + const int buffer_size = 64 * 1024; + char buffer[buffer_size]; + + // whole /proc/stat can be read in 1 syscall + if (read(f, buffer, buffer_size) <= 0) { + return fail("cannot read " PROC_STAT); } - fclose(f); + // tokenization per-line + char* line; + char* newl = "\n"; + for (line = strtok(buffer, newl); line; line = strtok(NULL, newl)) { + if (! strncmp(line, "cpu", 3)) ncpu ++; + } + + close(f); printf( "graph_title multicpu1sec\n" From 9901e00140c50c6428a16b8a8e6d8c568a60e002 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Tue, 26 May 2015 20:56:57 +0000 Subject: [PATCH 4/4] p/multicpu1sec-c: keep the files open --- plugins/system/multicpu1sec/multicpu1sec-c.c | 22 +++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/plugins/system/multicpu1sec/multicpu1sec-c.c b/plugins/system/multicpu1sec/multicpu1sec-c.c index 9997ef6f..49b4320a 100644 --- a/plugins/system/multicpu1sec/multicpu1sec-c.c +++ b/plugins/system/multicpu1sec/multicpu1sec-c.c @@ -112,17 +112,25 @@ int acquire() { fprintf(pid_file, "%d\n", getpid()); fclose(pid_file); + /* Reading /proc/stat */ + int f = open(PROC_STAT, O_RDONLY); + + /* open the spoolfile */ + int cache_file = open(cache_filename, O_CREAT | O_APPEND | O_WRONLY); + /* loop each second */ while (1) { /* wait until next second */ time_t epoch = wait_until_next_second(); - /* Reading /proc/stat */ - int f = open(PROC_STAT, O_RDONLY); const int buffer_size = 64 * 1024; char buffer[buffer_size]; + if (lseek(f, 0, SEEK_SET) < 0) { + return fail("cannot seek " PROC_STAT); + } + // whole /proc/stat can be read in 1 syscall if (read(f, buffer, buffer_size) <= 0) { return fail("cannot read " PROC_STAT); @@ -133,9 +141,6 @@ int acquire() { const char* newl = "\n"; line = strtok(buffer, newl); - /* open the spoolfile */ - int cache_file = open(cache_filename, O_CREAT | O_APPEND | O_WRONLY); - /* lock */ flock(cache_file, LOCK_EX); @@ -155,9 +160,12 @@ int acquire() { write(cache_file, out_buffer, strlen(out_buffer)); } - close(cache_file); - close(f); + /* unlock */ + flock(cache_file, LOCK_UN); } + + close(cache_file); + close(f); } int fetch() {