|
| 1 | +//Last modified: 17/10/11 18:52:02(CEST) by Fabian Holler |
| 2 | +#include <stdlib.h> |
| 3 | +#include <sys/types.h> |
| 4 | +#include <stdio.h> |
| 5 | +#include <strings.h> |
| 6 | +#include <unistd.h> |
| 7 | + |
| 8 | +struct pstat{ |
| 9 | + long unsigned int utime_ticks; |
| 10 | + long int cutime_ticks; |
| 11 | + long unsigned int stime_ticks; |
| 12 | + long int cstime_ticks; |
| 13 | + long unsigned int vsize; // virtual memory size in bytes |
| 14 | + long unsigned int rss; //Resident Set Size in bytes |
| 15 | + |
| 16 | + long unsigned int cpu_total_time; |
| 17 | +}; |
| 18 | + |
| 19 | +/* |
| 20 | + * read /proc data into the passed struct pstat |
| 21 | + * returns 0 on success, -1 on error |
| 22 | +*/ |
| 23 | +int get_usage(const pid_t pid, struct pstat* result){ |
| 24 | + //convert pid to string |
| 25 | + char pid_s[20]; |
| 26 | + snprintf(pid_s, sizeof(pid_s), "%d", pid); |
| 27 | + char stat_filepath[30] = "/proc/"; |
| 28 | + strncat(stat_filepath, pid_s, sizeof(stat_filepath) - strlen(stat_filepath) -1); |
| 29 | + strncat(stat_filepath, "/stat", sizeof(stat_filepath) - strlen(stat_filepath) -1); |
| 30 | + |
| 31 | + //open /proc/pid/stat |
| 32 | + FILE *fpstat = fopen(stat_filepath, "r"); |
| 33 | + if(fpstat == NULL){ |
| 34 | + printf("FOPEN ERROR pid stat %s:\n", stat_filepath); |
| 35 | + return -1; |
| 36 | + } |
| 37 | + |
| 38 | + //open /proc/stat |
| 39 | + FILE *fstat = fopen("/proc/stat", "r"); |
| 40 | + if(fstat == NULL){ |
| 41 | + printf("FOPEN ERROR"); |
| 42 | + fclose(fstat); |
| 43 | + return -1; |
| 44 | + } |
| 45 | + bzero(result, sizeof(struct pstat)); |
| 46 | + |
| 47 | + //read values from /proc/pid/stat |
| 48 | + long int rss; |
| 49 | + if(fscanf(fpstat, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu %ld %ld %*d %*d %*d %*d %*u %lu %ld", &result->utime_ticks, &result->stime_ticks, &result->cutime_ticks, &result->cstime_ticks, &result->vsize, &rss) == EOF){ |
| 50 | + fclose(fpstat); |
| 51 | + fclose(fstat); |
| 52 | + return -1; |
| 53 | + } |
| 54 | + fclose(fpstat); |
| 55 | + result->rss = rss * getpagesize(); |
| 56 | + |
| 57 | + //read+calc cpu total time from /proc/stat, on linux 2.6.35-23 x86_64 the cpu row has 10values could differ on different architectures :/ |
| 58 | + long unsigned int cpu_time[10]; |
| 59 | + bzero(cpu_time, sizeof(cpu_time)); |
| 60 | + if(fscanf(fstat, "%*s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", &cpu_time[0], &cpu_time[1], &cpu_time[2], &cpu_time[3], &cpu_time[4], &cpu_time[5], &cpu_time[6], &cpu_time[7], &cpu_time[8], &cpu_time[9]) == EOF){ |
| 61 | + fclose(fstat); |
| 62 | + return -1; |
| 63 | + } |
| 64 | + fclose(fstat); |
| 65 | + |
| 66 | + for(int i=0; i < 10;i++){ |
| 67 | + result->cpu_total_time += cpu_time[i]; |
| 68 | + } |
| 69 | + |
| 70 | + return 0; |
| 71 | +} |
| 72 | + |
| 73 | +/* |
| 74 | +* calculates the actual CPU usage(cur_usage - last_usage) in percent |
| 75 | +* cur_usage, last_usage: both last measured get_usage() results |
| 76 | +* ucpu_usage, scpu_usage: result parameters: user and sys cpu usage in % |
| 77 | +*/ |
| 78 | +void calc_cpu_usage(const struct pstat* cur_usage, const struct pstat* last_usage, float* ucpu_usage, float* scpu_usage){ |
| 79 | + *ucpu_usage = 100 * ((((cur_usage->utime_ticks + cur_usage->cutime_ticks) - (last_usage->utime_ticks + last_usage->cutime_ticks))) / (float)((cur_usage->cpu_total_time - last_usage->cpu_total_time))); |
| 80 | + *scpu_usage = 100 * ((((cur_usage->stime_ticks + cur_usage->cstime_ticks) - (last_usage->stime_ticks + last_usage->cstime_ticks))) / (float)((cur_usage->cpu_total_time - last_usage->cpu_total_time))); |
| 81 | +} |
| 82 | + |
0 commit comments