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