#include "utils/resource_usage.h" #if defined(__QNXNTO__) #include #include #include #include #include #include #include #include #include #endif #include #include #include #include #include #include #include "utils/file_system.h" namespace utils { SDL_CREATE_LOG_VARIABLE("Utils") const char* Resources::proc = "/proc/"; ResourseUsage* Resources::getCurrentResourseUsage() { PidStats pid_stats; if (false == GetProcInfo(pid_stats)) { SDL_LOG_ERROR("Failed to get cpu proc info"); return NULL; } MemInfo mem_info; if (false == GetMemInfo(mem_info)) { SDL_LOG_ERROR("Failed to get memory info"); return NULL; } ResourseUsage* usage = new ResourseUsage(); usage->utime = pid_stats.utime; usage->stime = pid_stats.stime; usage->memory = static_cast(mem_info); return usage; } bool Resources::ReadStatFile(std::string& output) { std::string filename = GetStatPath(); if (false == file_system::FileExists(filename)) { return false; } if (false == file_system::ReadFile(filename, output)) { return false; } return true; } bool Resources::GetProcInfo(Resources::PidStats& output) { #if defined(OS_LINUX) std::string proc_buf; if (false == ReadStatFile(proc_buf)) { return false; } uint32_t num_succes = sscanf(proc_buf.c_str(), "%d" // pid " %*s" // com " %c" // state " %d" // ppid " %d" // pgrp " %d" // session " %d" // tty_nr " %d" // tpgid " %u" // flags " %lu" // minflt " %lu" // cminflt " %lu" // majflt " %lu" // cmajflt " %lu" // utime " %lu" // stime " %ld" // cutime " %ld" // cstime " %ld" // priority " %ld" // nice " %ld" // num_threads " %ld" // itrealvalue " %llu" // starttime " %lu" // vsize " %ld" // rss " %lu" // rsslim " %lu" // startcode " %lu" // endcode " %lu" // startstack " %lu" // kstkesp " %lu" // kstkip " %lu" // signal " %lu" // blocked " %lu" // sigignore " %lu" // sigcatch " %lu" // wchan " %lu" // nswap " %lu" // cnswap " %d" // exit_signal " %d" // processor " %u" // rt_priority " %u" // policy " %llu" // delayacct_blkio_ticks " %lu" // guest_time " %ld" // cguest_time , &(output.pid), &(output.state), &(output.ppid), &(output.pgrp), &(output.session), &(output.tty_nr), &(output.tpgid), &(output.flags), &(output.minflt), &(output.cminflt), &(output.majflt), &(output.cmajflt), &(output.utime), &(output.stime), &(output.cutime), &(output.cstime), &(output.priority), &(output.nice), &(output.num_threads), &(output.itrealvalue), &(output.starttime), &(output.vsize), &(output.rss), &(output.rsslim), &(output.startcode), &(output.endcode), &(output.startstack), &(output.kstkesp), &(output.kstkeip), &(output.signal), &(output.blocked), &(output.sigignore), &(output.sigcatch), &(output.wchan), &(output.nswap), &(output.cnswap), &(output.exit_signal), &(output.processor), &(output.rt_priority), &(output.policy), &(output.delayacct_blkio_ticks), &(output.guest_time), &(output.cguest_time)); if (num_succes != 43) { // 43 is number of iteams in Resources::PidStats SDL_LOG_ERROR("Couldn't parse all iteams in /proc/PID/stat file"); return false; } return true; #elif defined(__QNXNTO__) int fd = open(GetProcPath().c_str(), O_RDONLY); if (0 >= fd) { SDL_LOG_ERROR("Failed open process proc file : " << GetProcPath() << "; error no : " << strerror(errno)); close(fd); return false; } devctl(fd, DCMD_PROC_INFO, &output, sizeof(output), 0); close(fd); return true; #endif } bool Resources::GetMemInfo(Resources::MemInfo& output) { bool result = false; #if defined(OS_LINUX) Resources::PidStats pid_stat; if (false == GetProcInfo(pid_stat)) { SDL_LOG_ERROR("Failed to get proc info"); result = false; } else { output = pid_stat.vsize; result = true; } #elif defined(__QNXNTO__) std::string as_path = GetStatPath(); struct stat st; struct _dir* proc_dir = 0; if (0 == (proc_dir = opendir(proc))) { SDL_LOG_ERROR("Unable to access to " << proc); result = false; return result; } if (0 == readdir(proc_dir)) { SDL_LOG_ERROR("Unable to read : " << proc_dir); closedir(proc_dir); result = false; return result; } closedir(proc_dir); if (-1 == stat(as_path.c_str(), &st) || 0 == st.st_size) { SDL_LOG_ERROR("Unable to stat : " << as_path.c_str()); result = false; return result; } output = st.st_size; result = true; #endif return result; } std::string Resources::GetStatPath() { std::string filename; #if defined(OS_LINUX) filename = GetProcPath() + "/stat"; #elif defined(__QNXNTO__) filename = GetProcPath() + "/as"; #endif return filename; } std::string Resources::GetProcPath() { char buffer[1024]; pid_t my_pid = getpid(); snprintf(buffer, sizeof(buffer), "%s%d/", proc, my_pid); std::string filename(buffer); return filename; } } // namespace utils