// ====================================================================== // \title SystemResourcesComponentImpl.cpp // \author sfregoso // \brief cpp file for SystemResources component implementation class // // \copyright // Copyright 2021, by the California Institute of Technology. // ALL RIGHTS RESERVED. United States Government Sponsorship // acknowledged. // // ====================================================================== #include #include #include //isnan() namespace Svc { // ---------------------------------------------------------------------- // Construction, initialization, and destruction // ---------------------------------------------------------------------- SystemResources ::SystemResources(const char* const compName) : SystemResourcesComponentBase(compName), m_cpu_count(0), m_enable(true) { // Structure initializations m_mem.used = 0; m_mem.total = 0; for (U32 i = 0; i < CPU_COUNT; i++) { m_cpu[i].used = 0; m_cpu[i].total = 0; m_cpu_prev[i].used = 0; m_cpu_prev[i].total = 0; } if (Os::Cpu::getCount(m_cpu_count) == Os::Generic::ERROR) { m_cpu_count = 0; } m_cpu_count = (m_cpu_count >= CPU_COUNT) ? CPU_COUNT : m_cpu_count; m_cpu_tlm_functions[0] = &Svc::SystemResources::tlmWrite_CPU_00; m_cpu_tlm_functions[1] = &Svc::SystemResources::tlmWrite_CPU_01; m_cpu_tlm_functions[2] = &Svc::SystemResources::tlmWrite_CPU_02; m_cpu_tlm_functions[3] = &Svc::SystemResources::tlmWrite_CPU_03; m_cpu_tlm_functions[4] = &Svc::SystemResources::tlmWrite_CPU_04; m_cpu_tlm_functions[5] = &Svc::SystemResources::tlmWrite_CPU_05; m_cpu_tlm_functions[6] = &Svc::SystemResources::tlmWrite_CPU_06; m_cpu_tlm_functions[7] = &Svc::SystemResources::tlmWrite_CPU_07; m_cpu_tlm_functions[8] = &Svc::SystemResources::tlmWrite_CPU_08; m_cpu_tlm_functions[9] = &Svc::SystemResources::tlmWrite_CPU_09; m_cpu_tlm_functions[10] = &Svc::SystemResources::tlmWrite_CPU_10; m_cpu_tlm_functions[11] = &Svc::SystemResources::tlmWrite_CPU_11; m_cpu_tlm_functions[12] = &Svc::SystemResources::tlmWrite_CPU_12; m_cpu_tlm_functions[13] = &Svc::SystemResources::tlmWrite_CPU_13; m_cpu_tlm_functions[14] = &Svc::SystemResources::tlmWrite_CPU_14; m_cpu_tlm_functions[15] = &Svc::SystemResources::tlmWrite_CPU_15; } SystemResources ::~SystemResources() {} // ---------------------------------------------------------------------- // Handler implementations for user-defined typed input ports // ---------------------------------------------------------------------- void SystemResources ::run_handler(const FwIndexType portNum, U32 tick_time_hz) { if (m_enable) { Cpu(); Mem(); PhysMem(); } } // ---------------------------------------------------------------------- // Command handler implementations // ---------------------------------------------------------------------- void SystemResources ::ENABLE_cmdHandler(const FwOpcodeType opCode, const U32 cmdSeq, SystemResourceEnabled enable) { m_enable = (enable == SystemResourceEnabled::ENABLED); this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); } F32 SystemResources::compCpuUtil(Os::Cpu::Ticks current, Os::Cpu::Ticks previous) { F32 util = 100.0f; // Prevent divide by zero on fast-sample if ((current.total - previous.total) != 0) { // Compute CPU % Utilization util = (static_cast(current.used - previous.used) / static_cast(current.total - previous.total)) * 100.0f; util = std::isnan(util) ? 100.0f : util; } return util; } void SystemResources::Cpu() { U32 count = 0; F32 cpuAvg = 0; for (U32 i = 0; i < m_cpu_count && i < CPU_COUNT; i++) { Os::Cpu::Status status = Os::Cpu::getTicks(m_cpu[i], i); // Best-effort calculations and telemetry if (status == Os::Generic::OP_OK) { F32 cpuUtil = compCpuUtil(m_cpu[i], m_cpu_prev[i]); cpuAvg += cpuUtil; // Send telemetry using telemetry output table FW_ASSERT(this->m_cpu_tlm_functions[i]); (this->*m_cpu_tlm_functions[i])(cpuUtil, Fw::Time()); // Store cpu used and total m_cpu_prev[i] = m_cpu[i]; count++; } } cpuAvg = (count == 0) ? 0.0f : (cpuAvg / static_cast(count)); this->tlmWrite_CPU(cpuAvg); } void SystemResources::Mem() { if (Os::Memory::getUsage(m_mem) == Os::Generic::OP_OK) { this->tlmWrite_MEMORY_TOTAL(m_mem.total / 1024); this->tlmWrite_MEMORY_USED(m_mem.used / 1024); } } void SystemResources::PhysMem() { FwSizeType total = 0; FwSizeType free = 0; if (Os::FileSystem::getFreeSpace("/", total, free) == Os::FileSystem::OP_OK) { this->tlmWrite_NON_VOLATILE_FREE(free / 1024); this->tlmWrite_NON_VOLATILE_TOTAL(total / 1024); } } } // end namespace Svc