Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include "sys/times.h" 6 : #include <cstdlib> 7 : #include <base/cpuinfo.h> 8 : 9 : #include <fstream> 10 : #include <iostream> 11 : 12 : extern void LoadAvg(CpuLoad &load); 13 : extern uint32_t NumCpus(); 14 : 15 : static clock_t snapshot, prev_sys_cpu, prev_user_cpu; 16 : 17 0 : static void ProcessCpuShare(double &percentage) { 18 : struct tms cpu_taken; 19 : clock_t now; 20 : 21 0 : now = times(&cpu_taken); 22 0 : if (now <= snapshot || cpu_taken.tms_stime < prev_sys_cpu || 23 0 : cpu_taken.tms_utime < prev_user_cpu) { 24 0 : percentage = -1.0; 25 : } else { 26 0 : percentage = 27 0 : (double)((cpu_taken.tms_stime - prev_sys_cpu) + 28 0 : (cpu_taken.tms_utime - prev_user_cpu)) / (now - snapshot); 29 0 : percentage *= 100; 30 0 : percentage /= NumCpus(); 31 : } 32 0 : snapshot = now; 33 0 : prev_sys_cpu = cpu_taken.tms_stime; 34 0 : prev_user_cpu = cpu_taken.tms_utime; 35 0 : } 36 : 37 0 : void CpuLoadData::GetCpuLoadInfo(CpuInfo &info, bool system) { 38 0 : if (system) { 39 0 : LoadAvg(info.load_avg); 40 0 : SystemMemInfo(info.sys_mem_info); 41 : } 42 : 43 0 : ProcessMemInfo(info.mem_info); 44 : 45 0 : ProcessCpuShare(info.process_cpu_share); 46 0 : info.num_cpu = NumCpus(); 47 0 : } 48 : 49 3 : void CpuLoadData::Init() { 50 : struct tms cpu_taken; 51 3 : snapshot = times(&cpu_taken); 52 3 : prev_sys_cpu = cpu_taken.tms_stime; 53 3 : prev_user_cpu = cpu_taken.tms_utime; 54 3 : } 55 : 56 0 : void CpuLoadData::FillCpuInfo(CpuLoadInfo &cpu_load_info, bool system) { 57 : CpuInfo info; 58 0 : CpuLoadData::GetCpuLoadInfo(info, system); 59 0 : cpu_load_info.set_num_cpu(info.num_cpu); 60 0 : MemInfo mem_info; 61 0 : mem_info.set_virt(info.mem_info.virt); 62 0 : mem_info.set_peakvirt(info.mem_info.peakvirt); 63 0 : mem_info.set_res(info.mem_info.res); 64 0 : cpu_load_info.set_meminfo(mem_info); 65 : 66 0 : cpu_load_info.set_cpu_share(info.process_cpu_share); 67 : 68 0 : if (system) { 69 0 : CpuLoadAvg load_avg; 70 0 : load_avg.set_one_min_avg(info.load_avg.one_min_avg); 71 0 : load_avg.set_five_min_avg(info.load_avg.five_min_avg); 72 0 : load_avg.set_fifteen_min_avg(info.load_avg.fifteen_min_avg); 73 0 : cpu_load_info.set_cpuload(load_avg); 74 : 75 0 : SysMemInfo sys_mem_info; 76 0 : sys_mem_info.set_total(info.sys_mem_info.total); 77 0 : sys_mem_info.set_used(info.sys_mem_info.used); 78 0 : sys_mem_info.set_free(info.sys_mem_info.free); 79 0 : sys_mem_info.set_buffers(info.sys_mem_info.buffers); 80 0 : sys_mem_info.set_cached(info.sys_mem_info.cached); 81 0 : cpu_load_info.set_sys_mem_info(sys_mem_info); 82 0 : } 83 0 : } 84 : 85 0 : void CpuLoadInfoReq::HandleRequest() const { 86 0 : CpuLoadInfo cpu_load_info; 87 0 : CpuLoadData::FillCpuInfo(cpu_load_info, true); 88 : 89 0 : CpuLoadInfoResp *resp = new CpuLoadInfoResp; 90 0 : resp->set_cpu_info(cpu_load_info); 91 0 : resp->set_context(context()); 92 0 : resp->Response(); 93 0 : } 94 : 95 0 : void PopulateProcessCpuInfo(const CpuLoadInfo &cpu_load_info, 96 : ProcessCpuInfo *pinfo) { 97 0 : pinfo->set_module_id(Sandesh::module()); 98 0 : pinfo->set_inst_id(Sandesh::instance_id()); 99 0 : pinfo->set_cpu_share(cpu_load_info.get_cpu_share()); 100 0 : pinfo->set_mem_virt(cpu_load_info.get_meminfo().get_virt()); 101 0 : pinfo->set_mem_res(cpu_load_info.get_meminfo().get_res()); 102 0 : }