diff options
Diffstat (limited to 'service/system/system_manager/server/src/ss_system_memory_monitor.cpp')
-rwxr-xr-x | service/system/system_manager/server/src/ss_system_memory_monitor.cpp | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/service/system/system_manager/server/src/ss_system_memory_monitor.cpp b/service/system/system_manager/server/src/ss_system_memory_monitor.cpp new file mode 100755 index 0000000..7ea9b71 --- /dev/null +++ b/service/system/system_manager/server/src/ss_system_memory_monitor.cpp @@ -0,0 +1,362 @@ +/* + * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/////////////////////////////////////////////////////////////////////////////// +/// \ingroup tag_SystemManager +/// \brief This file provides support for System Manager System Low Memory +/// detection. +/// +/////////////////////////////////////////////////////////////////////////////// +#include <native_service/frameworkunified_framework_if.h> +#include <native_service/frameworkunified_multithreading.h> +#include <native_service/frameworkunified_thread_priority.h> +#include <system_service/ss_sm_thread_names_local.h> +#include <system_service/ss_templates.h> +#include <stub/Clock_API.h> + +#include <sys/stat.h> +#include <errno.h> +#include <sys/resource.h> +#include <boost/bind.hpp> +#include <fstream> +#include <sstream> +#include <string> + +#include "ss_system_memory_monitor.h" +#include "ss_sm_systemmanagerlog.h" + +CSysMemoryMonitor::CSysMemoryMonitor() : + m_hThread(NULL), + m_hParentApp(NULL), + m_SLMCheckCounter(0), + m_siPriority(-1), + m_NbrSamplesBeforeSystemmanagerlog(0), + m_memMonitorThreadName(SS_SMLowMemMonitor), + m_resmSession(-1) { // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + m_SLMConfig.SLMTimerValue = 0; + m_SLMConfig.SLMMaxRetryCount = 0; + m_SLMConfig.SLMThresholdValue = 0; + m_SLMConfig.SLMSystemmanagerLogIntervalMs = 0; + bzero(&m_sysMemInfoLast, sizeof(m_sysMemInfoLast)); + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); +} + +CSysMemoryMonitor::~CSysMemoryMonitor(void) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + StopAndFreeObjects(m_hParentApp); + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); +} + +EFrameworkunifiedStatus CSysMemoryMonitor::Initialize(HANDLE f_hApp) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + + if (NULL == f_hApp) { // LCOV_EXCL_BR_LINE 4:NSFW + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + l_eStatus = eFrameworkunifiedStatusNullPointer; // LCOV_EXCL_LINE 4:NSFW + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error. Argument f_hApp passed NULL pointer."); + } else if (NULL == (m_hThread = FrameworkunifiedCreateChildThreadWithPriority(f_hApp, SS_SMLowMemMonitor, boost::bind(&CSysMemoryMonitor::CPUMemThreadStart, this, _1), boost::bind(&CSysMemoryMonitor::CPUMemThreadStop, this, _1), PR_SMLOWMEMMON))) { // LCOV_EXCL_BR_LINE 4:NSFW // NOLINT(whitespace/line_length) + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + l_eStatus = eFrameworkunifiedStatusInvldHandle; // LCOV_EXCL_LINE 4:NSFW + LOG_ERROR("FrameworkunifiedCreateChildThreadWithPriority()"); // LCOV_EXCL_LINE 4:NSFW + } else if (eFrameworkunifiedStatusOK != (l_eStatus = FrameworkunifiedStartChildThread(f_hApp, m_hThread, 0, NULL))) { // LCOV_EXCL_BR_LINE 4:NSFW // NOLINT(whitespace/line_length) + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + LOG_ERROR("FrameworkunifiedStartChildThread()"); // LCOV_EXCL_LINE 4:NSFW + } else { + m_hParentApp = f_hApp; + m_sysMemInfoLast.TotalMemoryBytes = GetSystemRamSize(); + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, " Info. SLM thread successfully initialized."); + } + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return (l_eStatus); +} + +EFrameworkunifiedStatus CSysMemoryMonitor::StopAndFreeObjects(HANDLE f_hApp) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + EFrameworkunifiedStatus l_eStatus; + + CALL_AND_LOG_STATUS(FrameworkunifiedStopChildThread(f_hApp, m_hThread, 0, NULL)); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + CALL_AND_LOG_STATUS(FrameworkunifiedDestroyChildThread(f_hApp, m_hThread)); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return (l_eStatus); +} + +const std::string CSysMemoryMonitor::GetThreadName(void) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return (m_memMonitorThreadName); +} + +void CSysMemoryMonitor::SetSLMConfigData(SLMConfigParameters & f_ConfigData) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + m_SLMConfig.SLMTimerValue = f_ConfigData.SLMTimerValue; + m_SLMConfig.SLMMaxRetryCount = f_ConfigData.SLMMaxRetryCount; + m_SLMConfig.SLMThresholdValue = f_ConfigData.SLMThresholdValue; + m_SLMConfig.SLMSystemmanagerLogIntervalMs = f_ConfigData.SLMSystemmanagerLogIntervalMs; + + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, + "Timer value '%d', Retry Count '%d', threshold '%d', log interval '%dms'", + m_SLMConfig.SLMTimerValue, m_SLMConfig.SLMMaxRetryCount, + m_SLMConfig.SLMThresholdValue, m_SLMConfig.SLMSystemmanagerLogIntervalMs); + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); +} + +EFrameworkunifiedStatus CSysMemoryMonitor::CPUMemThreadStart(HANDLE f_hThread) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + + l_eStatus = FrameworkunifiedSubscribeNotificationWithCallback(f_hThread, + NTFY_ResourceMgr_Availability, + boost::bind(&CSysMemoryMonitor::OnAvailability, this, _1)); + if (l_eStatus != eFrameworkunifiedStatusOK) { // LCOV_EXCL_BR_LINE 4:NSFW + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + SS_ASERT(0); // LCOV_EXCL_LINE 4:NSFW + } + + if (FALSE == (m_memMonitorTimer.Initialize(f_hThread, SS_SLM_MEM_MONITOR_TIMER_ID, boost::bind(&CSysMemoryMonitor::OnMemoryTimerExpiry, this, _1)))) { // LCOV_EXCL_BR_LINE 4:NSFW // NOLINT(whitespace/line_length) + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + l_eStatus = eFrameworkunifiedStatusBadConnection; // LCOV_EXCL_LINE 4:NSFW + LOG_ERROR("m_memMonitorTimer.Initialize() returned 'FALSE'"); // LCOV_EXCL_LINE 4:NSFW + } else if (FALSE == (m_systemmanagerlogTimer.Initialize(f_hThread, SS_SLM_SYSTEMMANAGERLOG_TIMER_ID, boost::bind(&CSysMemoryMonitor::OnSystemmanagerlogTimerExpiry, this, _1)))) { // LCOV_EXCL_BR_LINE 4:NSFW // NOLINT(whitespace/line_length) + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + l_eStatus = eFrameworkunifiedStatusBadConnection; // LCOV_EXCL_LINE 4:NSFW + LOG_ERROR("m_systemmanagerlogTimer.Initialize() returned 'FALSE'"); // LCOV_EXCL_LINE 4:NSFW + } else { + if (m_SLMConfig.SLMTimerValue > 0) { + m_memMonitorTimer.SetTime(m_SLMConfig.SLMTimerValue / 1000, + m_SLMConfig.SLMTimerValue % 1000, + m_SLMConfig.SLMTimerValue / 1000, + m_SLMConfig.SLMTimerValue % 1000); + } else { + // default timer settings + m_memMonitorTimer.SetTime(SS_MEMORY_TIMER_CONFIG_MS / 1000, + SS_MEMORY_TIMER_CONFIG_MS % 1000, + SS_MEMORY_TIMER_CONFIG_MS / 1000, + SS_MEMORY_TIMER_CONFIG_MS % 1000); + + FRAMEWORKUNIFIEDLOG(ZONE_WARN, __FUNCTION__, + " Warning. SLM monitor timer configuration invalid. Using default values."); + } + + if (m_SLMConfig.SLMSystemmanagerLogIntervalMs > 0) { + m_systemmanagerlogTimer.SetTime(m_SLMConfig.SLMSystemmanagerLogIntervalMs / 1000, + m_SLMConfig.SLMSystemmanagerLogIntervalMs % 1000, + m_SLMConfig.SLMSystemmanagerLogIntervalMs / 1000, + m_SLMConfig.SLMSystemmanagerLogIntervalMs % 1000); + } else { + // default timer settings + m_systemmanagerlogTimer.SetTime(SS_SYSTEMMANAGERLOG_TIMER_CONFIG_MS / 1000, + SS_SYSTEMMANAGERLOG_TIMER_CONFIG_MS % 1000, + SS_SYSTEMMANAGERLOG_TIMER_CONFIG_MS / 1000, + SS_SYSTEMMANAGERLOG_TIMER_CONFIG_MS % 1000); + + FRAMEWORKUNIFIEDLOG(ZONE_WARN, __FUNCTION__, + " Warning. SLM FRAMEWORKUNIFIEDLOG timer configuration invalid. Using default values."); + } + + if (FALSE == (m_memMonitorTimer.Start())) { // LCOV_EXCL_BR_LINE 4:NSFW + // LCOV_EXCL_START 4:NSFW + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + l_eStatus = eFrameworkunifiedStatusFault; + LOG_ERROR("m_memMonitorTimer.Start() returned 'FALSE'"); + // LCOV_EXCL_STOP 4:NSFW + } else if (FALSE == (m_systemmanagerlogTimer.Start())) { // LCOV_EXCL_BR_LINE 4:NSFW + // LCOV_EXCL_START 4:NSFW + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + l_eStatus = eFrameworkunifiedStatusFault; + LOG_ERROR("m_systemmanagerlogTimer.Start() returned 'FALSE'"); + // LCOV_EXCL_STOP 4:NSFW + } else { + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, " Success."); + } + } + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return (l_eStatus); +} + +EFrameworkunifiedStatus CSysMemoryMonitor::CPUMemThreadStop(HANDLE f_hThread) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + EFrameworkunifiedStatus l_eStatus; + + l_eStatus = StopTimers(); + LOG_STATUS_IF_ERRORED(l_eStatus, "StopTimers"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + if ((uint32_t) -1 != m_resmSession) { + if (RESM_E_OK != RESM_Close(m_resmSession)) { + l_eStatus = eFrameworkunifiedStatusFault; + LOG_ERROR("RESM_Close()"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + } + } + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return (l_eStatus); +} + +EFrameworkunifiedStatus CSysMemoryMonitor::StopTimers(void) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + + if (FALSE == (m_memMonitorTimer.Stop())) { // LCOV_EXCL_BR_LINE 4:NSFW's error + l_eStatus = eFrameworkunifiedStatusFault; + LOG_ERROR("m_memMonitorTimer.Stop() returned 'FALSE'"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + } + + if (FALSE == (m_systemmanagerlogTimer.Stop())) { // LCOV_EXCL_BR_LINE 4:NSFW's error + l_eStatus = eFrameworkunifiedStatusFault; + LOG_ERROR("m_systemmanagerlogTimer.Stop() returned 'FALSE'"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + } + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return (l_eStatus); +} + +EFrameworkunifiedStatus CSysMemoryMonitor::OnMemoryTimerExpiry(HANDLE hThread) { + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "+"); + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + RESM_STATUS_t l_resmStatus; + + if ((uint32_t) -1 == m_resmSession) { + return eFrameworkunifiedStatusOK; + } + + if (RESM_E_OK != RESM_GetStatus(m_resmSession, &l_resmStatus)) { + LOG_ERROR("RESM_GetStatus()"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + l_eStatus = eFrameworkunifiedStatusFail; + } else { + m_sysMemInfoLast.FreeMemoryBytes = l_resmStatus.restMemSize; + if ((m_sysMemInfoLast.FreeMemoryBytes * 1024) + < (UI_32) m_SLMConfig.SLMThresholdValue) { + m_SLMCheckCounter++; + + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Low Memory detected(%d/%d).", + m_SLMCheckCounter, m_SLMConfig.SLMMaxRetryCount); + + if (m_SLMCheckCounter >= m_SLMConfig.SLMMaxRetryCount) { + l_eStatus = FrameworkunifiedSendParent(hThread, + eSysMemThrdCmd_SYS_LOW_MEMORY, sizeof(m_sysMemInfoLast), + &m_sysMemInfoLast); + LOG_STATUS_IF_ERRORED(l_eStatus, // LCOV_EXCL_BR_LINE 15: marco defined in ns_logger_if.h // NOLINT(whitespace/line_length) + "FrameworkunifiedSendParent(eSysMemThrdCmd_SYS_LOW_MEMORY)"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + + l_eStatus = StopTimers(); + LOG_STATUS_IF_ERRORED(l_eStatus, "StopTimers"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + } + } else { + m_SLMCheckCounter = 0; + } + } + + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "-"); + return (l_eStatus); +} + +EFrameworkunifiedStatus CSysMemoryMonitor::OnSystemmanagerlogTimerExpiry(HANDLE hThread) { + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "+"); + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + UI_32 l_freeMemoryObfuscated; + UI_32 l_totalMemoryObfuscated; + + l_freeMemoryObfuscated = BitReverse32(m_sysMemInfoLast.FreeMemoryBytes); + l_totalMemoryObfuscated = BitReverse32(m_sysMemInfoLast.TotalMemoryBytes); + + // Print to ZONE_WARN as per IAT requirement see WI 219056. + FRAMEWORKUNIFIEDLOG(ZONE_WARN, __FUNCTION__, "FM: [%d/%d].", l_freeMemoryObfuscated, + l_totalMemoryObfuscated); + + static int count = 0; + + if (!(count %= 2)) { + CHAR l_format[256]; + uint32_t timebuf; + uint8_t status; + struct tm gmt; + struct tm local; + Clock_getSystemTimeY2K38(&timebuf, &status); + Clock_CnvSecToDateY2K38(&timebuf, &gmt); + Clock_getLocalTimeY2K38(&timebuf, &local); + + sprintf(l_format, " G%02d %02d%02d%02d L%02d %02d%02d%02d", gmt.tm_mday, // NOLINT + gmt.tm_hour, gmt.tm_min, gmt.tm_sec, local.tm_mday, + local.tm_hour, local.tm_min, local.tm_sec); + + FRAMEWORKUNIFIEDLOG(ZONE_STATE, __FUNCTION__, "%s", l_format); + } + + count++; + + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "-"); + return (l_eStatus); +} + +EFrameworkunifiedStatus CSysMemoryMonitor::OnAvailability(HANDLE hThread) { + if (FrameworkunifiedIsServiceAvailable(hThread)) { + if (m_resmSession == (uint32_t) -1) { + if (RESM_E_OK != RESM_Open(NULL, &m_resmSession)) { + m_resmSession = -1; + SS_ASERT(0); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + } + } + } + return eFrameworkunifiedStatusOK; +} + +UI_32 CSysMemoryMonitor::GetSystemRamSize(void) { + UI_32 l_ramTotalBytes = 0; + std::ifstream l_sFile("/proc/meminfo"); + + if (l_sFile.fail()) { // LCOV_EXCL_BR_LINE 5: Standard lib error + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Open /proc/meminfo"); + } else { + ssize_t l_position; + std::string l_str; + + while (getline(l_sFile, l_str)) { + +// if (std::string::npos +// != (l_position = static_cast<unsigned int>(l_str.find("MemTotal:", 0)))) { + if (0 <= (l_position = l_str.find("MemTotal:", 0))) { // LCOV_EXCL_BR_LINE 200:linux system information + + l_str.erase(l_position, l_position + strlen("MemTotal:")); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + + if (std::string::npos != (l_position = static_cast<unsigned int>(l_str.find("kB", 0)))) { // LCOV_EXCL_BR_LINE 200:linux system information + l_str.erase(l_position, l_position + strlen("kB")); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + } + + std::istringstream l_istr(l_str); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + + l_istr >> l_ramTotalBytes; + + break; + } + } + } + + return (l_ramTotalBytes); +} + +UI_32 CSysMemoryMonitor::BitReverse32(UI_32 f_val) { + // Don't print FRAMEWORKUNIFIEDLOG(ZONE_FUNC) to prevent obfuscation method from being revealed. + f_val = (((f_val & 0xaaaaaaaa) >> 1) | ((f_val & 0x55555555) << 1)); + f_val = (((f_val & 0xcccccccc) >> 2) | ((f_val & 0x33333333) << 2)); + f_val = (((f_val & 0xf0f0f0f0) >> 4) | ((f_val & 0x0f0f0f0f) << 4)); + f_val = (((f_val & 0xff00ff00) >> 8) | ((f_val & 0x00ff00ff) << 8)); + f_val = (f_val >> 16) | (f_val << 16); + return (f_val); +} |