F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
SystemResources.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title Linux/SystemResources.cpp
3 // \author sfregoso
4 // \brief hpp file for SystemResources component implementation class
5 //
6 // \copyright
7 // Copyright 2021, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12 #include <cstdio>
13 #include <cstring>
14 #include <sys/sysinfo.h>
15 #include <Os/SystemResources.hpp>
16 #include <Fw/Types/Assert.hpp>
17 
18 constexpr char PROC_STAT_PATH[] = "/proc/stat";
19 constexpr char READ_ONLY[] = "r";
20 constexpr int LINE_SIZE = 256;
22 
23 namespace Os {
24 
26  cpuCount = static_cast<U32>(get_nprocs());
27  return SYSTEM_RESOURCES_OK;
28  }
29 
30  U64 getCpuUsed(U32 cpu_data[4]) {
31  return cpu_data[0] + cpu_data[1] + cpu_data[2];
32  }
33  U64 getCpuTotal(U32 cpu_data[4]) {
34  return cpu_data[0] + cpu_data[1] + cpu_data[2] + cpu_data[3];
35  }
36 
38  if ((fp = fopen(PROC_STAT_PATH, READ_ONLY)) == nullptr) {
40  }
42  }
43 
45  if (fgets(proc_stat_line, LINE_SIZE, fp) == nullptr) {
47  }
49  }
50 
52  U32 cpu_index,
53  char proc_stat_line[LINE_SIZE]) {
54  for (U32 i = 0; i < cpu_index + 1; i++) {
57  }
58  if (i != cpu_index) {
59  continue;
60  }
61  if (strncmp(proc_stat_line, "cpu", 3) != 0) {
63  }
64  break;
65  }
67  }
68 
70  U32 cpu_data[4]) {
71  if (sscanf(proc_stat_line, "%*s %u %u %u %u", &cpu_data[0], &cpu_data[1], &cpu_data[2], &cpu_data[3]) !=
72  4) {
74  }
76  }
77 
78  SystemResources::SystemResourcesStatus getCpuData(U32 cpu_index, U32 cpu_data[4]) {
79  FILE* fp = nullptr;
82  }
83 
87  fclose(fp);
89  }
90  fclose(fp);
92  }
93 
94  SystemResources::SystemResourcesStatus SystemResources::getCpuTicks(CpuTicks& cpu_ticks, U32 cpu_index) {
96  U32 cpu_data[4] = {0};
97  U32 cpuCount = 0;
98 
99  if ((status = getCpuCount(cpuCount)) != SYSTEM_RESOURCES_OK) {
100  return status;
101  }
102  if (cpu_index >= cpuCount) {
103  return SYSTEM_RESOURCES_ERROR;
104  }
105 
106  if ((status = getCpuData(cpu_index, cpu_data)) != SYSTEM_RESOURCES_OK) {
107  return status;
108  }
109 
110  cpu_ticks.used = getCpuUsed(cpu_data);
111  cpu_ticks.total = getCpuTotal(cpu_data);
112  return SYSTEM_RESOURCES_OK;
113  }
114 
115 
116  U64 getMemoryTotal(FwSizeType total_ram, FwSizeType memory_unit) {
117  return static_cast<U64>(total_ram)*static_cast<U64>(memory_unit);
118  }
119  U64 getMemoryUsed(FwSizeType total_ram, FwSizeType free_ram, FwSizeType memory_unit) {
120  return static_cast<U64>((total_ram - free_ram)) * static_cast<U64>(memory_unit);
121  }
122 
124  FwSizeType free_ram,
125  FwSizeType memory_unit,
126  const struct sysinfo& memory_info) {
127  return ((total_ram <= 0) || (memory_unit <= 0) ||
128  (static_cast<unsigned long>(total_ram) != memory_info.totalram) ||
129  (static_cast<unsigned long>(free_ram) != memory_info.freeram) ||
130  (static_cast<unsigned int>(memory_unit) != memory_info.mem_unit));
131  }
132 
134  return (total_ram < free_ram);
135  }
136 
137  bool checkMultiplicationOverflow(FwSizeType total_ram, FwSizeType memory_unit) {
138  return (total_ram > (std::numeric_limits<FwSizeType>::max() / memory_unit));
139  }
140 
142  struct sysinfo memory_info;
143 
144  if (sysinfo(&memory_info) != 0) {
145  return SYSTEM_RESOURCES_ERROR;
146  }
147 
148  const FwSizeType total_ram = static_cast<FwSizeType>(memory_info.totalram);
149  const FwSizeType free_ram = static_cast<FwSizeType>(memory_info.freeram);
150  const FwSizeType memory_unit = static_cast<FwSizeType>(memory_info.mem_unit);
151 
152  if (checkCastingAndTypeErrors(total_ram, free_ram, memory_unit, memory_info)) {
153  return SYSTEM_RESOURCES_ERROR;
154  }
155 
156  if (checkInvalidMemoryCalculation(total_ram, free_ram)) {
157  return SYSTEM_RESOURCES_ERROR;
158  }
159 
160  if (checkMultiplicationOverflow(total_ram, memory_unit)) {
161  return SYSTEM_RESOURCES_ERROR;
162  }
163 
164  memory_util.used = getMemoryUsed(total_ram, free_ram, memory_unit);
165  memory_util.total = getMemoryTotal(total_ram, memory_unit);
166 
167  return SYSTEM_RESOURCES_OK;
168  }
169 }
PlatformSizeType FwSizeType
Definition: FpConfig.h:30
constexpr char PROC_STAT_PATH[]
constexpr char READ_ONLY[]
char proc_stat_line[LINE_SIZE]
constexpr int LINE_SIZE
SystemResourcesStatus getCpuTicks(CpuTicks &ticks, U32 cpu_index=0)
Get the CPU tick information for a given CPU.
SystemResourcesStatus getMemUtil(MemUtil &memory_util)
Get system memory usage.
SystemResourcesStatus getCpuCount(U32 &cpu_count)
Request the count of the CPUs detected by the system.
@ SYSTEM_RESOURCES_OK
Call was successful.
@ SYSTEM_RESOURCES_ERROR
Call failed.
SystemResources::SystemResourcesStatus readProcStatLine(FILE *fp, char proc_stat_line[LINE_SIZE])
bool checkInvalidMemoryCalculation(FwSizeType total_ram, FwSizeType free_ram)
SystemResources::SystemResourcesStatus getCpuData(U32 cpu_index, U32 cpu_data[4])
SystemResources::SystemResourcesStatus openProcStatFile(FILE *&fp)
U64 getCpuTotal(U32 cpu_data[4])
U64 getCpuUsed(U32 cpu_data[4])
bool checkCastingAndTypeErrors(FwSizeType total_ram, FwSizeType free_ram, FwSizeType memory_unit, const struct sysinfo &memory_info)
SystemResources::SystemResourcesStatus parseCpuData(char proc_stat_line[LINE_SIZE], U32 cpu_data[4])
SystemResources::SystemResourcesStatus getCpuDataLine(FILE *fp, U32 cpu_index, char proc_stat_line[LINE_SIZE])
U64 getMemoryUsed(FwSizeType total_ram, FwSizeType free_ram, FwSizeType memory_unit)
U64 getMemoryTotal(FwSizeType total_ram, FwSizeType memory_unit)
bool checkMultiplicationOverflow(FwSizeType total_ram, FwSizeType memory_unit)
#define U64(C)
Definition: sha.h:176