#include "SystemInformation.h"
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <cassert>
//Last modified: 18/11/12 19:13:35(CET) by Fabian Holler
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
struct pstat {
long unsigned int utime_ticks;
long int cutime_ticks;
long unsigned int stime_ticks;
long int cstime_ticks;
long unsigned int vsize; // virtual memory size in bytes
long unsigned int rss; //Resident Set Size in bytes
long unsigned int cpu_total_time;
};
/*
* read /proc data into the passed struct pstat
* returns 0 on success, -1 on error
*/
int get_usage(const pid_t pid, struct pstat* result) {
//convert pid to string
char pid_s[20];
snprintf(pid_s, sizeof(pid_s), "%d", pid);
char stat_filepath[30] = "/proc/"; strncat(stat_filepath, pid_s,
sizeof(stat_filepath) - strlen(stat_filepath) -1);
strncat(stat_filepath, "/stat", sizeof(stat_filepath) -
strlen(stat_filepath) -1);
FILE *fpstat = fopen(stat_filepath, "r");
if (fpstat == NULL) {
perror("FOPEN ERROR ");
return -1;
}
FILE *fstat = fopen("/proc/stat", "r");
if (fstat == NULL) {
perror("FOPEN ERROR ");
fclose(fstat);
return -1;
}
//read values from /proc/pid/stat
bzero(result, sizeof(struct pstat));
long int rss;
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) {
fclose(fpstat);
return -1;
}
fclose(fpstat);
result->rss = rss * getpagesize();
//read+calc cpu total time from /proc/stat
long unsigned int cpu_time[10];
bzero(cpu_time, sizeof(cpu_time));
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) {
fclose(fstat);
return -1;
}
fclose(fstat);
for(int i=0; i < 10;i++)
result->cpu_total_time += cpu_time[i];
return 0;
}
/*
* calculates the elapsed CPU usage between 2 measuring points. in percent
*/
void calc_cpu_usage_pct(const struct pstat* cur_usage,
const struct pstat* last_usage,
double* ucpu_usage, double* scpu_usage)
{
const long unsigned int total_time_diff = cur_usage->cpu_total_time -
last_usage->cpu_total_time;
*ucpu_usage = 100 * (((cur_usage->utime_ticks + cur_usage->cutime_ticks)
- (last_usage->utime_ticks + last_usage->cutime_ticks))
/ (double) total_time_diff);
*scpu_usage = 100 * ((((cur_usage->stime_ticks + cur_usage->cstime_ticks)
- (last_usage->stime_ticks + last_usage->cstime_ticks))) /
(double) total_time_diff);
}
SystemInformation::SystemInformation()
{
m_lastFrameTimePoint = GameTime::now();
}
SystemInformation::~SystemInformation()
{
}
//
// http://stackoverflow.com/questions/8223348/ios-get-cpu-usage-from-application
//
struct pstat cpuinfo;
float SystemInformation::getCpuUsage()
{
get_usage(getpid(), &cpuinfo);
static struct pstat last_cpuinfo = cpuinfo;
double userTime, sysTime;
calc_cpu_usage_pct(&cpuinfo, &last_cpuinfo, &userTime, &sysTime);
last_cpuinfo = cpuinfo;
/*
struct rusage usage;
struct rlimit limit;
int r1 = getrusage(RUSAGE_SELF, &usage);
int r2 = getrlimit(RLIMIT_CPU, &limit);
float perc = (r1 * 100.0) / r2;
return tot_cpu;
*/
return userTime;
}
//
// http://stackoverflow.com/questions/7989864/watching-memory-usage-in-ios
//
size_t SystemInformation::getMemoryUsage()
{
//return cpuinfo.vsize;
return cpuinfo.rss;
/*
struct task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);
assert(kr == KERN_SUCCESS);
return info.resident_size; // size in bytes
*/
}
float SystemInformation::getFrameTime()
{
return m_lastFrameDuration.count() * 0.000000001f; // nanosecs to seconds as a float
}
float SystemInformation::getFps()
{
return m_fps;
}
float SystemInformation::getAverageFps()
{
return m_averageFps;
}
float SystemInformation::getDrawTime()
{
return m_postDrawFrameDuration.count() * 0.000000001f; // nanosecs to seconds as a float
}
void SystemInformation::preDraw()
{
m_preDrawTimePoint = GameTime::now();
}
//
// fps calculations
// http://stackoverflow.com/questions/1738315/calculate-fps-frames-per-second-for-iphone-app
//
void SystemInformation::frameDrawn()
{
GameTime::TimePoint thisFrameTimePoint = GameTime::now();
m_lastFrameDuration = thisFrameTimePoint - m_lastFrameTimePoint;
m_postDrawFrameDuration = thisFrameTimePoint - m_preDrawTimePoint;
m_lastFrameTimePoint = thisFrameTimePoint;
uint64_t nanoSecs = m_lastFrameDuration.count();
m_fps = (nanoSecs == 0) ? 0 : 1000000000 / float(nanoSecs);
m_averageFpsCounter++;
m_averageFpsSum += m_fps;
if (m_averageFpsCounter >= 15) // calculate average FPS over 15 frames
{
m_averageFps = m_averageFpsSum / m_averageFpsCounter;
m_averageFpsCounter = 0;
m_averageFpsSum = 0;
}
}