added to git
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
#include "myMonitoringTool.h"
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define MAIN 0
|
||||
#define MEM 1
|
||||
#define CPU 2
|
||||
#define CORE 3
|
||||
|
||||
bool isint(char *str) {
|
||||
///_|> descry: checks if a string is an integer
|
||||
///_|> str: string to check
|
||||
///_|> returning: true iff is an integer
|
||||
|
||||
int i = 0;
|
||||
while (str[i] != '\0') {
|
||||
if (!isdigit(str[i])) {
|
||||
return false;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void sigint_handler(int sig) {
|
||||
///_|> descry: Handles SIGINT, exiting if pressed twice
|
||||
///_|> sig: signal number
|
||||
///_|> returning: void
|
||||
static int count = 0;
|
||||
if (count == 0) {
|
||||
printf("\nPress Ctrl+C again to quit");
|
||||
count++;
|
||||
char buf[LINE_BUF];
|
||||
fgets(buf, sizeof buf, stdin);
|
||||
count = 0;
|
||||
if (signal(SIGINT, sigint_handler) != 0) {
|
||||
perror("signal");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse input, read values, display requested output
|
||||
int main(int argc, char **argv) {
|
||||
///_|> Parse CLAs, implement children to read data, prints childrens data
|
||||
///_|> argc: number of arguments including function name
|
||||
///_|> argv: list of string arguments
|
||||
///_|> retuning: integer success code
|
||||
if (signal(SIGTSTP, SIG_IGN) != 0) {
|
||||
perror("signal");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bool show_mem = false;
|
||||
bool show_cpu = false;
|
||||
bool show_cores = false;
|
||||
int samples = 20;
|
||||
int tdelay = 5e5;
|
||||
int nums_given = 0;
|
||||
|
||||
// Parse input
|
||||
for (int i = 1; i < argc; i++) {
|
||||
char first9[10];
|
||||
strncpy(first9, argv[i], 9);
|
||||
first9[9] = '\0';
|
||||
char first10[11];
|
||||
strncpy(first10, argv[i], 10);
|
||||
first10[10] = '\0';
|
||||
if (strcmp(argv[i], "--memory") == 0) {
|
||||
show_mem = true;
|
||||
} else if (strcmp(argv[i], "--cpu") == 0) {
|
||||
show_cpu = true;
|
||||
} else if (strcmp(argv[i], "--cores") == 0) {
|
||||
show_cores = true;
|
||||
} else if (isint(argv[i])) {
|
||||
if (nums_given == 0) {
|
||||
samples = atoi(argv[i]);
|
||||
} else if (nums_given == 1) {
|
||||
tdelay = atoi(argv[i]);
|
||||
} else {
|
||||
printf("Unknown flag %s\nUsage: myMonitoringTool [samples [tdelay]] "
|
||||
"[--memory] [--cpu] [--cores] [--samples=N] [--tdelay=T]\n",
|
||||
argv[i]);
|
||||
exit(1);
|
||||
}
|
||||
nums_given += 1;
|
||||
} else if (strcmp(first9, "--tdelay=") == 0) {
|
||||
char value[LINE_BUF];
|
||||
strncpy(value, argv[i] + 9, 20);
|
||||
tdelay = atoi(value);
|
||||
} else if (strcmp(first10, "--samples=") == 0) {
|
||||
char value[LINE_BUF];
|
||||
strncpy(value, argv[i] + 10, 20);
|
||||
samples = atoi(value);
|
||||
} else {
|
||||
printf("Unknown flag %s\nUsage: myMonitoringTool [samples [tdelay]] "
|
||||
"[--memory] [--cpu] [--cores] [--samples=N] [--tdelay=T]\n",
|
||||
argv[i]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
bool show_all = !(show_mem || show_cpu || show_cores);
|
||||
if (show_cores && !(show_mem || show_cpu || show_all)) {
|
||||
samples = 1;
|
||||
}
|
||||
|
||||
int cpu_cores = get_file_line_value("/proc/cpuinfo", 11);
|
||||
int p[2]; // Mem pipe
|
||||
int q[2]; // Cpu pipe
|
||||
int r[2]; // Core pipe
|
||||
|
||||
if (pipe(p) == -1 || pipe(q) == -1) {
|
||||
perror("pipe");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int cpu_proc = fork();
|
||||
int mem_proc = -2;
|
||||
if (cpu_proc != 0) {
|
||||
mem_proc = fork();
|
||||
}
|
||||
if (cpu_proc == -1 || mem_proc == -1) {
|
||||
perror("fork");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int id = -1;
|
||||
|
||||
if (cpu_proc != 0 && mem_proc > 0) {
|
||||
close(p[1]);
|
||||
close(q[1]);
|
||||
id = MAIN;
|
||||
if (signal(SIGINT, sigint_handler) != 0) {
|
||||
perror("signal");
|
||||
exit(1);
|
||||
}
|
||||
} else if (cpu_proc == 0 && mem_proc <= 0) {
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
close(q[0]);
|
||||
id = CPU;
|
||||
if (signal(SIGINT, SIG_IGN) != 0) {
|
||||
perror("signal");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
assert(cpu_proc != 0 && mem_proc == 0);
|
||||
close(p[0]);
|
||||
close(q[0]);
|
||||
close(q[1]);
|
||||
id = MEM;
|
||||
if (signal(SIGINT, SIG_IGN) != 0) {
|
||||
perror("signal");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare the core info
|
||||
char coreinfo[PANE_BUF];
|
||||
if (id == MAIN && (show_cores || show_all)) {
|
||||
if (pipe(r) == -1) {
|
||||
perror("pipe");
|
||||
exit(1);
|
||||
}
|
||||
int pid = fork();
|
||||
if (pid == -1) {
|
||||
perror("fork");
|
||||
exit(1);
|
||||
}
|
||||
if (pid == 0) {
|
||||
close(r[0]);
|
||||
int cpu_max_freq = get_file_line_value(
|
||||
"/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", 0);
|
||||
draw_cores(cpu_cores, cpu_max_freq, r[1]);
|
||||
exit(0);
|
||||
} else {
|
||||
close(r[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the frames
|
||||
|
||||
int mem_total = get_file_line_value("/proc/meminfo", 0);
|
||||
|
||||
// Initialize arrays for values that change, scaled from 0 to 10. For use
|
||||
// in children
|
||||
int mem_usages[samples];
|
||||
int cpu_utils[samples];
|
||||
|
||||
// Values that will be printed, for use in parent
|
||||
char meminfo[PANE_BUF];
|
||||
char cpuinfo[PANE_BUF];
|
||||
|
||||
// Draw, compute, and display output
|
||||
for (int i = 0; i < samples; i++) {
|
||||
|
||||
if (id == MEM && (show_mem || show_all)) {
|
||||
assert(mem_proc == 0 && cpu_proc != 0);
|
||||
get_mem_usage(mem_total, meminfo, mem_usages, i);
|
||||
write(p[1], meminfo, PANE_BUF);
|
||||
|
||||
raise(SIGSTOP);
|
||||
}
|
||||
|
||||
if (id == CPU && (show_cpu || show_all)) {
|
||||
assert(mem_proc != 0 && cpu_proc == 0);
|
||||
get_cpu_usage(cpu_cores, cpuinfo, cpu_utils, i, tdelay / 2);
|
||||
write(q[1], cpuinfo, PANE_BUF);
|
||||
|
||||
raise(SIGSTOP);
|
||||
}
|
||||
|
||||
// Display cores info
|
||||
if (id == MAIN) {
|
||||
if (show_mem || show_cpu || show_all) {
|
||||
usleep(tdelay);
|
||||
}
|
||||
draw_reset(samples, tdelay);
|
||||
if (show_mem || show_all) {
|
||||
// printf("main wait to read mem\n");
|
||||
read(p[0], meminfo, PANE_BUF);
|
||||
printf("%s", meminfo);
|
||||
if (kill(mem_proc, SIGCONT) != 0) {
|
||||
perror("kill");
|
||||
exit(1);
|
||||
};
|
||||
}
|
||||
|
||||
if (show_cpu || show_all) {
|
||||
read(q[0], cpuinfo, PANE_BUF);
|
||||
printf("%s", cpuinfo);
|
||||
if (kill(cpu_proc, SIGCONT) != 0) {
|
||||
perror("kill");
|
||||
exit(1);
|
||||
};
|
||||
}
|
||||
|
||||
if (show_cores || show_all) {
|
||||
// The core info had time to generate, now it should read without
|
||||
// generation time
|
||||
if (i == 0) {
|
||||
read(r[0], coreinfo, PANE_BUF);
|
||||
}
|
||||
printf("%s", coreinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user