From 117fd67950a7b7d1ed48653b7e39266dc83fcd73 Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 19 Apr 2014 21:23:34 +0800 Subject: [PATCH] add cpu stat --- trunk/src/app/srs_app_config.cpp | 22 +++ trunk/src/app/srs_app_config.hpp | 5 + trunk/src/app/srs_app_http_api.cpp | 90 ++++++++++ trunk/src/app/srs_app_http_api.hpp | 22 +++ trunk/src/app/srs_app_server.cpp | 59 +++++-- trunk/src/kernel/srs_kernel_utility.cpp | 113 +++++++++++++ trunk/src/kernel/srs_kernel_utility.hpp | 213 ++++++++++++++++++++++++ 7 files changed, 510 insertions(+), 14 deletions(-) diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 5a7c3957e..4bd4a3405 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -1079,6 +1079,18 @@ int SrsConfig::parse_options(int argc, char** argv) { int ret = ERROR_SUCCESS; + for (int i = 0; i < argc; i++) { + _argv.append(argv[i]); + + if (i < argc - 1) { + _argv.append(" "); + } + } + + char cwd[256]; + getcwd(cwd, sizeof(cwd)); + _cwd = cwd; + show_help = true; for (int i = 1; i < argc; i++) { if ((ret = parse_argv(i, argv)) != ERROR_SUCCESS) { @@ -1239,6 +1251,16 @@ void SrsConfig::print_help(char** argv) argv[0], argv[0], argv[0], argv[0]); } +string SrsConfig::get_cwd() +{ + return _cwd; +} + +string SrsConfig::get_argv() +{ + return _argv; +} + bool SrsConfig::get_deamon() { srs_assert(root); diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index c7d3e8e2b..b289f7a5c 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -120,6 +120,8 @@ private: bool test_conf; bool show_version; std::string config_file; + std::string _argv; + std::string _cwd; SrsConfDirective* root; std::vector subscribes; public: @@ -143,6 +145,9 @@ private: virtual int parse_file(const char* filename); virtual int parse_argv(int& i, char** argv); virtual void print_help(char** argv); +public: + virtual std::string get_cwd(); + virtual std::string get_argv(); // global section public: virtual SrsConfDirective* get_root(); diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index f3f9467e1..0661a0856 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -34,6 +34,8 @@ using namespace std; #include #include #include +#include +#include SrsApiRoot::SrsApiRoot() { @@ -114,6 +116,8 @@ int SrsApiApi::do_process_request(SrsSocket* skt, SrsHttpMessage* req) SrsApiV1::SrsApiV1() { handlers.push_back(new SrsApiVersion()); + handlers.push_back(new SrsApiSummaries()); + handlers.push_back(new SrsApiRusages()); handlers.push_back(new SrsApiAuthors()); } @@ -134,6 +138,9 @@ int SrsApiV1::do_process_request(SrsSocket* skt, SrsHttpMessage* req) << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT << JFIELD_ORG("urls", JOBJECT_START) << JFIELD_STR("versions", "the version of SRS") << JFIELD_CONT + << JFIELD_STR("summaries", "the summary(pid, argv, pwd, cpu, mem) of SRS") << JFIELD_CONT + << JFIELD_STR("rusages", "the rusage of SRS") << JFIELD_CONT + << JFIELD_STR("proc_stats", "the /proc/self/stat of SRS") << JFIELD_CONT << JFIELD_STR("authors", "the primary authors and contributors") << JOBJECT_END << JOBJECT_END; @@ -171,6 +178,89 @@ int SrsApiVersion::do_process_request(SrsSocket* skt, SrsHttpMessage* req) return res_json(skt, req, ss.str()); } +SrsApiSummaries::SrsApiSummaries() +{ +} + +SrsApiSummaries::~SrsApiSummaries() +{ +} + +bool SrsApiSummaries::can_handle(const char* path, int length, const char** /*pchild*/) +{ + return srs_path_equals("/summaries", path, length); +} + +int SrsApiSummaries::do_process_request(SrsSocket* skt, SrsHttpMessage* req) +{ + std::stringstream ss; + + SrsRusage* r = srs_get_system_rusage(); + SrsCpuSelfStat* u = srs_get_self_cpu_stat(); + SrsCpuSystemStat* s = srs_get_system_cpu_stat(); + + ss << JOBJECT_START + << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT + << JFIELD_ORG("data", JOBJECT_START) + << JFIELD_ORG("pid", getpid()) << JFIELD_CONT + << JFIELD_STR("argv", _srs_config->get_argv()) << JFIELD_CONT + << JFIELD_STR("cwd", _srs_config->get_cwd()) << JFIELD_CONT + << JFIELD_ORG("rusage_ok", (r->ok? "true":"false")) << JFIELD_CONT + << JFIELD_ORG("self_cpu_stat_ok", (u->ok? "true":"false")) << JFIELD_CONT + << JFIELD_ORG("system_cpu_stat_ok", (s->ok? "true":"false")) << JFIELD_CONT + << JFIELD_ORG("mem_kbyte", r->r.ru_maxrss) << JFIELD_CONT + << JFIELD_ORG("ppid", u->ppid) + << JOBJECT_END + << JOBJECT_END; + + return res_json(skt, req, ss.str()); +} + +SrsApiRusages::SrsApiRusages() +{ +} + +SrsApiRusages::~SrsApiRusages() +{ +} + +bool SrsApiRusages::can_handle(const char* path, int length, const char** /*pchild*/) +{ + return srs_path_equals("/rusages", path, length); +} + +int SrsApiRusages::do_process_request(SrsSocket* skt, SrsHttpMessage* req) +{ + std::stringstream ss; + + SrsRusage* r = srs_get_system_rusage(); + + ss << JOBJECT_START + << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT + << JFIELD_ORG("data", JOBJECT_START) + << JFIELD_ORG("rusage_ok", (r->ok? "true":"false")) << JFIELD_CONT + << JFIELD_ORG("ru_utime", r->r.ru_utime.tv_sec) << JFIELD_CONT + << JFIELD_ORG("ru_stime", r->r.ru_stime.tv_sec) << JFIELD_CONT + << JFIELD_ORG("ru_maxrss", r->r.ru_maxrss) << JFIELD_CONT + << JFIELD_ORG("ru_ixrss", r->r.ru_ixrss) << JFIELD_CONT + << JFIELD_ORG("ru_idrss", r->r.ru_idrss) << JFIELD_CONT + << JFIELD_ORG("ru_isrss", r->r.ru_isrss) << JFIELD_CONT + << JFIELD_ORG("ru_minflt", r->r.ru_minflt) << JFIELD_CONT + << JFIELD_ORG("ru_majflt", r->r.ru_majflt) << JFIELD_CONT + << JFIELD_ORG("ru_nswap", r->r.ru_nswap) << JFIELD_CONT + << JFIELD_ORG("ru_inblock", r->r.ru_inblock) << JFIELD_CONT + << JFIELD_ORG("ru_oublock", r->r.ru_oublock) << JFIELD_CONT + << JFIELD_ORG("ru_msgsnd", r->r.ru_msgsnd) << JFIELD_CONT + << JFIELD_ORG("ru_msgrcv", r->r.ru_msgrcv) << JFIELD_CONT + << JFIELD_ORG("ru_nsignals", r->r.ru_nsignals) << JFIELD_CONT + << JFIELD_ORG("ru_nvcsw", r->r.ru_nvcsw) << JFIELD_CONT + << JFIELD_ORG("ru_nivcsw", r->r.ru_nivcsw) + << JOBJECT_END + << JOBJECT_END; + + return res_json(skt, req, ss.str()); +} + SrsApiAuthors::SrsApiAuthors() { } diff --git a/trunk/src/app/srs_app_http_api.hpp b/trunk/src/app/srs_app_http_api.hpp index 2b66aeb2b..831c38bef 100644 --- a/trunk/src/app/srs_app_http_api.hpp +++ b/trunk/src/app/srs_app_http_api.hpp @@ -87,6 +87,28 @@ protected: virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); }; +class SrsApiSummaries : public SrsHttpHandler +{ +public: + SrsApiSummaries(); + virtual ~SrsApiSummaries(); +public: + virtual bool can_handle(const char* path, int length, const char** pchild); +protected: + virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); +}; + +class SrsApiRusages : public SrsHttpHandler +{ +public: + SrsApiRusages(); + virtual ~SrsApiRusages(); +public: + virtual bool can_handle(const char* path, int length, const char** pchild); +protected: + virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); +}; + class SrsApiAuthors : public SrsHttpHandler { public: diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 3cb6c94a8..2b13a0ab1 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -46,7 +46,21 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #endif #define SERVER_LISTEN_BACKLOG 512 -#define SRS_SYS_TIME_RESOLUTION_MS 500 + +// system interval +#define SRS_SYS_CYCLE_INTERVAL 100 + +// update time interval: +// SRS_SYS_CYCLE_INTERVAL * SRS_SYS_TIME_RESOLUTION_MS_TIMES +#define SRS_SYS_TIME_RESOLUTION_MS_TIMES 3 + +// update rusage interval: +// SRS_SYS_CYCLE_INTERVAL * SRS_SYS_RUSAGE_RESOLUTION_TIMES +#define SRS_SYS_RUSAGE_RESOLUTION_TIMES 15 + +// update rusage interval: +// SRS_SYS_CYCLE_INTERVAL * SRS_SYS_CPU_STAT_RESOLUTION_TIMES +#define SRS_SYS_CPU_STAT_RESOLUTION_TIMES 15 SrsListener::SrsListener(SrsServer* server, SrsListenerType type) { @@ -393,10 +407,15 @@ int SrsServer::cycle() { int ret = ERROR_SUCCESS; + // find the max loop + int max = srs_max(0, SRS_SYS_TIME_RESOLUTION_MS_TIMES); + max = srs_max(max, SRS_SYS_RUSAGE_RESOLUTION_TIMES); + max = srs_max(max, SRS_SYS_CPU_STAT_RESOLUTION_TIMES); + // the deamon thread, update the time cache while (true) { - st_usleep(SRS_SYS_TIME_RESOLUTION_MS * 1000); - srs_update_system_time_ms(); + for (int i = 1; i < max + 1; i++) { + st_usleep(SRS_SYS_CYCLE_INTERVAL * 1000); // for gperf heap checker, // @see: research/gperftools/heap-checker/heap_checker.cc @@ -404,20 +423,32 @@ int SrsServer::cycle() // but, if gperf, use reload to ensure main return normally, // because directly exit will cause core-dump. #ifdef SRS_AUTO_GPERF_MC - if (signal_gmc_stop) { - break; - } + if (signal_gmc_stop) { + break; + } #endif - if (signal_reload) { - signal_reload = false; - srs_info("get signal reload, to reload the config."); - - if ((ret = _srs_config->reload()) != ERROR_SUCCESS) { - srs_error("reload config failed. ret=%d", ret); - return ret; + if (signal_reload) { + signal_reload = false; + srs_info("get signal reload, to reload the config."); + + if ((ret = _srs_config->reload()) != ERROR_SUCCESS) { + srs_error("reload config failed. ret=%d", ret); + return ret; + } + srs_trace("reload config success."); + } + + // update the cache time or rusage. + if (i == SRS_SYS_TIME_RESOLUTION_MS_TIMES) { + srs_update_system_time_ms(); + } + if (i == SRS_SYS_RUSAGE_RESOLUTION_TIMES) { + srs_update_system_rusage(); + } + if (i == SRS_SYS_CPU_STAT_RESOLUTION_TIMES) { + srs_update_system_cpu_stat(); } - srs_trace("reload config success."); } } diff --git a/trunk/src/kernel/srs_kernel_utility.cpp b/trunk/src/kernel/srs_kernel_utility.cpp index 4fa4ac573..340300ca2 100644 --- a/trunk/src/kernel/srs_kernel_utility.cpp +++ b/trunk/src/kernel/srs_kernel_utility.cpp @@ -57,3 +57,116 @@ void srs_update_system_time_ms() _srs_system_time_us_cache = now_us; } + +static SrsRusage _srs_system_rusage; + +SrsRusage::SrsRusage() +{ + ok = false; + memset(&r, 0, sizeof(rusage)); +} + +SrsRusage* srs_get_system_rusage() +{ + return &_srs_system_rusage; +} + +void srs_update_system_rusage() +{ + if (getrusage(RUSAGE_SELF, &_srs_system_rusage.r) < 0) { + srs_warn("getrusage failed, ignore"); + return; + } + + _srs_system_rusage.ok = true; +} + +static SrsCpuSelfStat _srs_system_cpu_self_stat; +static SrsCpuSystemStat _srs_system_cpu_system_stat; + +SrsCpuSelfStat::SrsCpuSelfStat() +{ + ok = false; +} + +SrsCpuSystemStat::SrsCpuSystemStat() +{ + ok = false; +} + +SrsCpuSelfStat* srs_get_self_cpu_stat() +{ + return &_srs_system_cpu_self_stat; +} + +SrsCpuSystemStat* srs_get_system_cpu_stat() +{ + return &_srs_system_cpu_system_stat; +} + +void srs_update_system_cpu_stat() +{ + // system cpu stat + if (true) { + FILE* f = fopen("/proc/stat", "r"); + if (f == NULL) { + srs_warn("open system cpu stat failed, ignore"); + return; + } + + SrsCpuSystemStat& r = _srs_system_cpu_system_stat; + for (;;) { + int ret = fscanf(f, "%4s %lu %lu %lu %lu %lu " + "%lu %lu %lu %lu\n", + r.label, &r.user, &r.nice, &r.sys, &r.idle, &r.iowait, + &r.irq, &r.softirq, &r.steal, &r.guest); + r.ok = false; + + if (ret == EOF) { + break; + } + + if (strcmp("cpu", r.label) == 0) { + r.ok = true; + break; + } + } + + fclose(f); + } + + // self cpu stat + if (true) { + FILE* f = fopen("/proc/self/stat", "r"); + if (f == NULL) { + srs_warn("open self cpu stat failed, ignore"); + return; + } + + SrsCpuSelfStat& r = _srs_system_cpu_self_stat; + int ret = fscanf(f, "%d %32s %c %d %d %d %d " + "%d %u %lu %lu %lu %lu " + "%lu %lu %ld %ld %ld %ld " + "%ld %ld %llu %lu %ld " + "%lu %lu %lu %lu %lu " + "%lu %lu %lu %lu %lu " + "%lu %lu %lu %d %d " + "%u %u %llu " + "%lu %ld", + &r.pid, r.comm, &r.state, &r.ppid, &r.pgrp, &r.session, &r.tty_nr, + &r.tpgid, &r.flags, &r.minflt, &r.cminflt, &r.majflt, &r.cmajflt, + &r.utime, &r.stime, &r.cutime, &r.cstime, &r.priority, &r.nice, + &r.num_threads, &r.itrealvalue, &r.starttime, &r.vsize, &r.rss, + &r.rsslim, &r.startcode, &r.endcode, &r.startstack, &r.kstkesp, + &r.kstkeip, &r.signal, &r.blocked, &r.sigignore, &r.sigcatch, + &r.wchan, &r.nswap, &r.cnswap, &r.exit_signal, &r.processor, + &r.rt_priority, &r.policy, &r.delayacct_blkio_ticks, + &r.guest_time, &r.cguest_time); + + if (ret >= 0) { + r.ok = true; + } + + fclose(f); + } +} diff --git a/trunk/src/kernel/srs_kernel_utility.hpp b/trunk/src/kernel/srs_kernel_utility.hpp index 4d74ab87a..fb3a7d443 100644 --- a/trunk/src/kernel/srs_kernel_utility.hpp +++ b/trunk/src/kernel/srs_kernel_utility.hpp @@ -30,9 +30,222 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include +#include + // get current system time in ms, use cache to avoid performance problem extern int64_t srs_get_system_time_ms(); // the deamon st-thread will update it. extern void srs_update_system_time_ms(); +// @see: man getrusage +struct SrsRusage +{ + bool ok; + rusage r; + + SrsRusage(); +}; + +// get system rusage, use cache to avoid performance problem. +extern SrsRusage* srs_get_system_rusage(); +// the deamon st-thread will update it. +extern void srs_update_system_rusage(); + +// @see: man 5 proc, /proc/[pid]/stat +struct SrsCpuSelfStat +{ + // whether the data is ok. + bool ok; + + // pid %d The process ID. + int pid; + // comm %s The filename of the executable, in parentheses. This is visible whether or not the executable is + // swapped out. + char comm[32]; + // state %c One character from the string "RSDZTW" where R is running, S is sleeping in an interruptible wait, D + // is waiting in uninterruptible disk sleep, Z is zombie, T is traced or stopped (on a signal), and W is + // paging. + char state; + // ppid %d The PID of the parent. + int ppid; + // pgrp %d The process group ID of the process. + int pgrp; + // session %d The session ID of the process. + int session; + // tty_nr %d The controlling terminal of the process. (The minor device number is contained in the combination of + // bits 31 to 20 and 7 to 0; the major device number is in bits 15 t0 8.) + int tty_nr; + // tpgid %d The ID of the foreground process group of the controlling terminal of the process. + int tpgid; + // flags %u (%lu before Linux 2.6.22) + // The kernel flags word of the process. For bit meanings, see the PF_* defines in . + // Details depend on the kernel version. + unsigned int flags; + // minflt %lu The number of minor faults the process has made which have not required loading a memory page from + // disk. + unsigned long minflt; + // cminflt %lu The number of minor faults that the process’s waited-for children have made. + unsigned long cminflt; + // majflt %lu The number of major faults the process has made which have required loading a memory page from disk. + unsigned long majflt; + // cmajflt %lu The number of major faults that the process’s waited-for children have made. + unsigned long cmajflt; + // utime %lu Amount of time that this process has been scheduled in user mode, measured in clock ticks (divide by + // sysconf(_SC_CLK_TCK). This includes guest time, guest_time (time spent running a virtual CPU, see + // below), so that applications that are not aware of the guest time field do not lose that time from + // their calculations. + unsigned long utime; + // stime %lu Amount of time that this process has been scheduled in kernel mode, measured in clock ticks (divide by + // sysconf(_SC_CLK_TCK). + unsigned long stime; + // cutime %ld Amount of time that this process’s waited-for children have been scheduled in user mode, measured in + // clock ticks (divide by sysconf(_SC_CLK_TCK). (See also times(2).) This includes guest time, + // cguest_time (time spent running a virtual CPU, see below). + long cutime; + // cstime %ld Amount of time that this process’s waited-for children have been scheduled in kernel mode, measured in + // clock ticks (divide by sysconf(_SC_CLK_TCK). + long cstime; + // priority %ld + // (Explanation for Linux 2.6) For processes running a real-time scheduling policy (policy below; see + // sched_setscheduler(2)), this is the negated scheduling priority, minus one; that is, a number in the + // range -2 to -100, corresponding to real-time priorities 1 to 99. For processes running under a non- + // real-time scheduling policy, this is the raw nice value (setpriority(2)) as represented in the kernel. + // The kernel stores nice values as numbers in the range 0 (high) to 39 (low), corresponding to the user- + // visible nice range of -20 to 19. + // + // Before Linux 2.6, this was a scaled value based on the scheduler weighting given to this process. + long priority; + // nice %ld The nice value (see setpriority(2)), a value in the range 19 (low priority) to -20 (high priority). + long nice; + // num_threads %ld + // Number of threads in this process (since Linux 2.6). Before kernel 2.6, this field was hard coded to + // 0 as a placeholder for an earlier removed field. + long num_threads; + // itrealvalue %ld + // The time in jiffies before the next SIGALRM is sent to the process due to an interval timer. Since + // kernel 2.6.17, this field is no longer maintained, and is hard coded as 0. + long itrealvalue; + // starttime %llu (was %lu before Linux 2.6) + // The time in jiffies the process started after system boot. + long long starttime; + // vsize %lu Virtual memory size in bytes. + unsigned long vsize; + // rss %ld Resident Set Size: number of pages the process has in real memory. This is just the pages which count + // towards text, data, or stack space. This does not include pages which have not been demand-loaded in, + // or which are swapped out. + long rss; + // rsslim %lu Current soft limit in bytes on the rss of the process; see the description of RLIMIT_RSS in getprior- + // ity(2). + unsigned long rsslim; + // startcode %lu + // The address above which program text can run. + unsigned long startcode; + // endcode %lu The address below which program text can run. + unsigned long endcode; + // startstack %lu + // The address of the start (i.e., bottom) of the stack. + unsigned long startstack; + // kstkesp %lu The current value of ESP (stack pointer), as found in the kernel stack page for the process. + unsigned long kstkesp; + // kstkeip %lu The current EIP (instruction pointer). + unsigned long kstkeip; + // signal %lu The bitmap of pending signals, displayed as a decimal number. Obsolete, because it does not provide + // information on real-time signals; use /proc/[pid]/status instead. + unsigned long signal; + // blocked %lu The bitmap of blocked signals, displayed as a decimal number. Obsolete, because it does not provide + // information on real-time signals; use /proc/[pid]/status instead. + unsigned long blocked; + // sigignore %lu + // The bitmap of ignored signals, displayed as a decimal number. Obsolete, because it does not provide + // information on real-time signals; use /proc/[pid]/status instead. + unsigned long sigignore; + // sigcatch %lu + // The bitmap of caught signals, displayed as a decimal number. Obsolete, because it does not provide + // information on real-time signals; use /proc/[pid]/status instead. + unsigned long sigcatch; + // wchan %lu This is the "channel" in which the process is waiting. It is the address of a system call, and can be + // looked up in a namelist if you need a textual name. (If you have an up-to-date /etc/psdatabase, then + // try ps -l to see the WCHAN field in action.) + unsigned long wchan; + // nswap %lu Number of pages swapped (not maintained). + unsigned long nswap; + // cnswap %lu Cumulative nswap for child processes (not maintained). + unsigned long cnswap; + // exit_signal %d (since Linux 2.1.22) + // Signal to be sent to parent when we die. + int exit_signal; + // processor %d (since Linux 2.2.8) + // CPU number last executed on. + int processor; + // rt_priority %u (since Linux 2.5.19; was %lu before Linux 2.6.22) + // Real-time scheduling priority, a number in the range 1 to 99 for processes scheduled under a real-time + // policy, or 0, for non-real-time processes (see sched_setscheduler(2)). + unsigned int rt_priority; + // policy %u (since Linux 2.5.19; was %lu before Linux 2.6.22) + // Scheduling policy (see sched_setscheduler(2)). Decode using the SCHED_* constants in linux/sched.h. + unsigned int policy; + // delayacct_blkio_ticks %llu (since Linux 2.6.18) + // Aggregated block I/O delays, measured in clock ticks (centiseconds). + unsigned long long delayacct_blkio_ticks; + // guest_time %lu (since Linux 2.6.24) + // Guest time of the process (time spent running a virtual CPU for a guest operating system), measured in + // clock ticks (divide by sysconf(_SC_CLK_TCK). + unsigned long guest_time; + // cguest_time %ld (since Linux 2.6.24) + // Guest time of the process’s children, measured in clock ticks (divide by sysconf(_SC_CLK_TCK). + long cguest_time; + + SrsCpuSelfStat(); +}; + +// @see: man 5 proc, /proc/stat +struct SrsCpuSystemStat +{ + // whether the data is ok. + bool ok; + + // always be cpu + char label[32]; + + //The amount of time, measured in units of USER_HZ (1/100ths of a second on most architectures, use + // sysconf(_SC_CLK_TCK) to obtain the right value) + // + // the system spent in user mode, + unsigned long user; + // user mode with low priority (nice), + unsigned long nice; + // system mode, + unsigned long sys; + // and the idle task, respectively. + unsigned long idle; + + // In Linux 2.6 this line includes three additional columns: + // + // iowait - time waiting for I/O to complete (since 2.5.41); + unsigned long iowait; + // irq - time servicing interrupts (since 2.6.0-test4); + unsigned long irq; + // softirq - time servicing softirqs (since 2.6.0-test4). + unsigned long softirq; + + // Since Linux 2.6.11, there is an eighth column, + // steal - stolen time, which is the time spent in other oper- + // ating systems when running in a virtualized environment + unsigned long steal; + + // Since Linux 2.6.24, there is a ninth column, + // guest, which is the time spent running a virtual CPU for guest + // operating systems under the control of the Linux kernel. + unsigned long guest; + + SrsCpuSystemStat(); +}; + +// get system cpu stat, use cache to avoid performance problem. +extern SrsCpuSelfStat* srs_get_self_cpu_stat(); +// get system cpu stat, use cache to avoid performance problem. +extern SrsCpuSystemStat* srs_get_system_cpu_stat(); +// the deamon st-thread will update it. +extern void srs_update_system_cpu_stat(); + #endif