#include #include #include #include #include #include #include #include #include #include #define CPUINFO "/proc/cpuinfo" /*#define CPUFREQ "/sys/devices/system/cpu/cpu0/cpufreq/"*/ #define LOADAVG "/proc/loadavg" #define CPUTIME "/proc/sys" #define REPOS "\033[H" // Re-positions the cursor to top left of screen #define CLEAR "\033[2J" #define SPACE " " #define PROCSPACE " " typedef struct Chunk chunk; struct Chunk { size_t size; char* mem; }; size_t read_file(FILE* file, chunk* out) { char* block = malloc(500 * sizeof(char)); if (!file) { return -1; } if (!block) { fclose(file); return -1; } size_t fileout = 0; size_t old = 0; fileout = fread(block, sizeof(char), 500, file); while (fileout != 0) { old = out->size; out->size = out->size + fileout; out->mem = realloc(out->mem, out->size); if (out->mem) { fclose(file); free(block); return -1; } memcpy(&(out->mem[old]), block, fileout); } free(block); fclose(file); return fileout; } void move(int row, int col) { printf("\x1b[%d;%df", row, col); } void repos() { printf("\033[H"); } void die(const char* reason, int ret) { printf("%s\n", reason); exit(ret); } int printcores(char* proc_data) { char* core_loc = strstr(proc_data, "siblings"); char* freq_loc = strstr(proc_data, "cpu MHz"); int core_num = atoi(core_loc); float core_freq = atof(freq_loc); int fullcpurows = floorf((float) atoi(core_loc)/4.0); int remainder = atoi(core_loc) - fullcpurows * 4; for (int i = 0; i < fullcpurows; i++) { printf("+---+%s+---+%s+---+%s+---+\n", SPACE, SPACE, SPACE); printf("|%s|%s|%s|%s|%s|%s|%s|\n", PROCSPACE, SPACE, PROCSPACE, SPACE, PROCSPACE, SPACE, PROCSPACE); printf("+---+%s+---+%s+---+%s+---+\n", SPACE, SPACE, SPACE); } for (int i = 0; i < remainder; i++) { } for (int i = 0; i < core_num; i++) { printf("+---+\n| |\n+---+\n"); } return 0; } char* rightshift(char* data, size_t size) { char* res = malloc(size * sizeof(char)); *res = ' '; memcpy(res + 1, data, size - 1); free(data); return res; } int printmemgraph(int max, int inuse, char** graphdata, char prog) { float percentage = (float)inuse/(float)max; int percent = floorf(percentage); for (int i = 0; i < 10; i++) { graphdata[i] = rightshift(graphdata[i], 12); if ((percentage >= i) && (percentage <= i + 10)) { graphdata[i][0] = prog; } printf("%s\n", graphdata[i]); } return 0; } int printcpugraph (float max, float inuse, char** graphdata, char prog) { float percentage = inuse/max; int percent = floorf(percentage); if (inuse > max) { graphdata[9][0] = prog; } else { for (int i = 0; i < 10; i++) { graphdata[i] = rightshift(graphdata[i], 12); if ((percentage >= i) && (percentage <= i + 1)) { graphdata[i][0] = prog; } printf("%s\n", graphdata[i]); } } return 0; } float getload() { chunk* data = malloc(sizeof(chunk)); data->mem = malloc(1); data->size = 0; if (read_file(fopen(CPUTIME, "r"), data) == -1) { die("Reading file error!", 4); } int inuse_time = 0; int total_time = 0; int is_idle = 0; char* cpu_line = strstr(data->mem, "cpu0"); long diff =(long) strstr(cpu_line, "\n") - (long) cpu_line; char* load = malloc((diff * sizeof(char))); strncpy(load, cpu_line, diff); char* read_line = strtok(cpu_line, " "); while (read_line != NULL) { if (is_idle != 3) { int num = atoi(read_line); inuse_time+=num; total_time+=num; } else { int num = atoi(read_line); total_time+=num; } read_line = strtok(NULL, " "); is_idle++; } free(load); free(data->mem); free(data); return (float)inuse_time/(float)total_time; } void wipe(char** arr, int samples) { for (int i = 0; i < 10; i++) { for (int r = 0; i < samples; r++) { *(*(arr + i)+r) = ' '; } } } int main(int argc, char** argv) { /*Variables pertaining to program CLA*/ short memory = 0; short cpu = 0; short cores = 0; int samples = 20; unsigned int tdelay = 500000; /*Variables pertaining to the running of the program*/ unsigned long prevtime; long max_ram = 0; int core_num = 0; char** memgraph; char** cpugraph; int cpu_rows = 0; int cpu_remainder = 0; struct sysinfo system_read; chunk* proc_data = malloc(sizeof(chunk)); if (!proc_data) { die("Memory error!", 3); } proc_data->mem = malloc(1); if (!proc_data) { die("Memory error!", 3); } proc_data->size = 0; if (!sysinfo(&system_read)) { die("Unable to get system info!", 2); } if (read_file(fopen(CPUINFO, "r"), proc_data) == -1) { die("Reading file error!", 4); } int start = 1; max_ram = system_read.totalram; if ((atoi(argv[1]) != 0) || (strlen(argv[1]) == 1)) { samples = atoi(argv[1]); start++; } if ((argc >= 3) && ((atoi(argv[2]) != 0) || (strlen(argv[2]) == 1))) { tdelay = atoi(argv[2]); start++; } for (int i = start; i < argc ; i++) { if (strstr(argv[i], "--memory")) { memgraph = malloc(sizeof(char*) * 10); for (int i = 0; i < 10; i++) { *(memgraph+i) = malloc(sizeof(char) * samples); } wipe(memgraph, samples); memory = 1; } else if (strstr(argv[i], "--cpu")) { cpugraph = malloc(sizeof(char*) * 10); for (int i = 0; i < 10; i++) { *(cpugraph+i) = malloc(sizeof(char) * samples); } wipe(cpugraph, samples); cpu = 1; } else if (strstr(argv[i], "--cores")) { cores = 1; } else if (strstr(argv[i], "--samples=")) { samples = atoi(argv[i] + 10); } else if (strstr(argv[i], "--tdelay=")) { tdelay = atoi(strstr(argv[i], "--tdelay=") + 9); } else { free(proc_data->mem); free(proc_data); printf("Invalid argument!"); die("Invalid argument!", 1); return 1; } } /* Main Logic Here*/ struct timeval tv; if (samples < 0 || tdelay < 0) die("Invalid argument!", 1); for (int i = 0; i < samples; i++) { gettimeofday(&tv, NULL); prevtime = tv.tv_usec; printf("%s", CLEAR); printf("%s", REPOS); if (memory) { if (!sysinfo(&system_read)) { die("Unable to get system info!", 2); } printmemgraph(max_ram, system_read.bufferram, memgraph, '#'); } printf("\n"); if (cpu) { printcpugraph(1.0, getload(), cpugraph,':'); } while (1) { gettimeofday(&tv, NULL); if (prevtime - tv.tv_usec >= tdelay) break; } } if (cores) printcores(proc_data->mem); free(proc_data->mem); free(proc_data); return 0; }