Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions modula/Components/Include/Logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ enum CommonMessageTypes {
YAML_PARSE_ERROR,
NOTIFY_RESOURCE_TUNER_INIT_START,
NOTIFY_CURRENT_TARGET_NAME,
NOTIFY_RAM_TIER_DETECTED,
NOTIFY_PARSING_START,
NOTIFY_PARSING_SUCCESS,
NOTIFY_PARSING_FAILURE,
Expand Down
8 changes: 8 additions & 0 deletions modula/Components/Logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,14 @@ void Logger::typeLog(CommonMessageTypes type, const std::string& funcName, ...)

break;

case CommonMessageTypes::NOTIFY_RAM_TIER_DETECTED:
vsnprintf(buffer, sizeof(buffer),
"Detected RAM Tier: [%s]", args);

Logger::log(LOG_INFO, "URM_SERVER_INIT", funcName, buffer);

break;

case CommonMessageTypes::PULSE_MONITOR_INIT_FAILED:
Logger::log(LOG_ERR, "URM_SERVER_INIT", funcName,
"Pulse Monitor Could not be started, " \
Expand Down
54 changes: 54 additions & 0 deletions modula/CoreModules/AuxRoutines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,3 +271,57 @@ std::string AuxRoutines::toLowerCase(const std::string& str) {
[](unsigned char c) { return std::tolower(c); });
return result;
}

// Get total system RAM in MB from /proc/meminfo
int64_t AuxRoutines::getTotalSystemRAM() {
std::ifstream meminfo("/proc/meminfo");
if (!meminfo.is_open()) {
LOGE("URM_AUX_ROUTINE", "Failed to open /proc/meminfo");
return -1;
}
std::string line;
while (std::getline(meminfo, line)) {
if (line.find("MemTotal:") == 0) {
std::istringstream iss(line);
std::string label;
int64_t value;
std::string unit;

iss >> label >> value >> unit;
meminfo.close();

// Convert KB to MB
return value / 1024;
}
}

meminfo.close();
LOGE("URM_AUX_ROUTINE", "MemTotal not found in /proc/meminfo");
return -1;
}
// Categorize RAM into tiers: low, medium, high, very_high
std::string AuxRoutines::getRAMTier() {
int64_t totalRAM = getTotalSystemRAM();

if (totalRAM < 0) {
LOGW("URM_AUX_ROUTINE", "Failed to detect RAM, using default tier");
return "medium";
}

LOGI("URM_AUX_ROUTINE", "Detected Total RAM: " + std::to_string(totalRAM) + " MB");

// RAM tier thresholds (in MB)
if (totalRAM < 4096) {
LOGI("URM_AUX_ROUTINE", "RAM Tier: LOW (< 4GB)");
return "low";
} else if (totalRAM < 8192) {
LOGI("URM_AUX_ROUTINE", "RAM Tier: MEDIUM (4GB - 8GB)");
return "medium";
} else if (totalRAM < 65536) {
LOGI("URM_AUX_ROUTINE", "RAM Tier: HIGH (8GB - 64GB)");
return "high";
} else {
LOGI("URM_AUX_ROUTINE", "RAM Tier: VERY_HIGH (> 64GB)");
return "very_high";
}
}
4 changes: 4 additions & 0 deletions modula/CoreModules/Include/AuxRoutines.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ class AuxRoutines {
static int64_t generateUniqueHandle();
static int64_t getCurrentTimeInMilliseconds();
static std::string toLowerCase(const std::string& str);

// RAM detection utilities
static int64_t getTotalSystemRAM();
static std::string getRAMTier();
};

// Following are some client-lib centric utilities
Expand Down
58 changes: 58 additions & 0 deletions modula/CoreModules/Include/RAMConfigGenerator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
// SPDX-License-Identifier: BSD-3-Clause-Clear

#ifndef RAM_CONFIG_GENERATOR_H
#define RAM_CONFIG_GENERATOR_H

#include <string>
#include <unordered_map>
#include <cstdint>

/**
* @brief RAMConfigGenerator
* @details Generates optimized configuration values based on system RAM tier.
* This class provides RAM-aware configuration values for various
* resource tuner parameters.
*/
class RAMConfigGenerator {
public:
/**
* @brief Get configuration value for a given property based on RAM tier
* @param propertyName The name of the property
* @param ramTier The RAM tier (low, medium, high, very_high)
* @return The optimized value for the property, or empty string if not found
*/
static std::string getConfigValue(const std::string& propertyName,
const std::string& ramTier);

/**
* @brief Get all RAM-based configurations for a given tier
* @param ramTier The RAM tier (low, medium, high, very_high)
* @return Map of property names to their optimized values
*/
static std::unordered_map<std::string, std::string>
getAllConfigs(const std::string& ramTier);

private:
// Configuration profiles for different RAM tiers
struct ConfigProfile {
uint32_t maxConcurrentRequests;
uint32_t maxResourcesPerRequest;
uint32_t threadPoolDesiredCapacity;
uint32_t threadPoolMaxScalingCapacity;
uint32_t pulseDuration;
uint32_t garbageCollectionDuration;
uint32_t garbageCollectionBatchSize;
uint32_t rateLimiterDelta;
double penaltyFactor;
double rewardFactor;
};

static ConfigProfile getLowRAMProfile();
static ConfigProfile getMediumRAMProfile();
static ConfigProfile getHighRAMProfile();
static ConfigProfile getVeryHighRAMProfile();
static ConfigProfile getProfileForTier(const std::string& ramTier);
};

#endif
150 changes: 150 additions & 0 deletions modula/CoreModules/RAMConfigGenerator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
// SPDX-License-Identifier: BSD-3-Clause-Clear

#include "RAMConfigGenerator.h"
#include "Logger.h"

// Low RAM Profile (< 4GB)
// Conservative settings to minimize memory usage
RAMConfigGenerator::ConfigProfile RAMConfigGenerator::getLowRAMProfile() {
ConfigProfile profile;
profile.maxConcurrentRequests = 30;
profile.maxResourcesPerRequest = 10;
profile.threadPoolDesiredCapacity = 3;
profile.threadPoolMaxScalingCapacity = 6;
profile.pulseDuration = 30000;
profile.garbageCollectionDuration = 1500;
profile.garbageCollectionBatchSize = 10;
profile.rateLimiterDelta = 3;
profile.penaltyFactor = 2.5;
profile.rewardFactor = 0.3;
return profile;
}

// Medium RAM Profile (4GB - 8GB)
// Balanced settings - similar to current defaults
RAMConfigGenerator::ConfigProfile RAMConfigGenerator::getMediumRAMProfile() {
ConfigProfile profile;
profile.maxConcurrentRequests = 60;
profile.maxResourcesPerRequest = 20;
profile.threadPoolDesiredCapacity = 5;
profile.threadPoolMaxScalingCapacity = 10;
profile.pulseDuration = 23000;
profile.garbageCollectionDuration = 1000;
profile.garbageCollectionBatchSize = 20;
profile.rateLimiterDelta = 5;
profile.penaltyFactor = 2.0;
profile.rewardFactor = 0.4;
return profile;
}

// High RAM Profile (8GB - 64GB)
// Aggressive settings for better performance
RAMConfigGenerator::ConfigProfile RAMConfigGenerator::getHighRAMProfile() {
ConfigProfile profile;
profile.maxConcurrentRequests = 75;
profile.maxResourcesPerRequest = 30;
profile.threadPoolDesiredCapacity = 8;
profile.threadPoolMaxScalingCapacity = 16;
profile.pulseDuration = 18000;
profile.garbageCollectionDuration = 800;
profile.garbageCollectionBatchSize = 30;
profile.rateLimiterDelta = 7;
profile.penaltyFactor = 1.8;
profile.rewardFactor = 0.5;
return profile;
}

// Very High RAM Profile (> 64GB)
// Maximum performance settings
RAMConfigGenerator::ConfigProfile RAMConfigGenerator::getVeryHighRAMProfile() {
ConfigProfile profile;
profile.maxConcurrentRequests = 100;
profile.maxResourcesPerRequest = 50;
profile.threadPoolDesiredCapacity = 12;
profile.threadPoolMaxScalingCapacity = 24;
profile.pulseDuration = 15000;
profile.garbageCollectionDuration = 600;
profile.garbageCollectionBatchSize = 40;
profile.rateLimiterDelta = 10;
profile.penaltyFactor = 1.5;
profile.rewardFactor = 0.6;
return profile;
}

RAMConfigGenerator::ConfigProfile RAMConfigGenerator::getProfileForTier(const std::string& ramTier) {
if (ramTier == "low") {
LOGI("RAM_CONFIG_GEN", "Using LOW RAM configuration profile");
return getLowRAMProfile();
} else if (ramTier == "medium") {
LOGI("RAM_CONFIG_GEN", "Using MEDIUM RAM configuration profile");
return getMediumRAMProfile();
} else if (ramTier == "high") {
LOGI("RAM_CONFIG_GEN", "Using HIGH RAM configuration profile");
return getHighRAMProfile();
} else if (ramTier == "very_high") {
LOGI("RAM_CONFIG_GEN", "Using VERY_HIGH RAM configuration profile");
return getVeryHighRAMProfile();
} else {
LOGW("RAM_CONFIG_GEN", "Unknown RAM tier: " + ramTier + ", using MEDIUM profile");
return getMediumRAMProfile();
}
}

std::string RAMConfigGenerator::getConfigValue(const std::string& propertyName,
const std::string& ramTier) {
ConfigProfile profile = getProfileForTier(ramTier);

if (propertyName == "resource_tuner.maximum.concurrent.requests") {
return std::to_string(profile.maxConcurrentRequests);
} else if (propertyName == "resource_tuner.maximum.resources.per.request") {
return std::to_string(profile.maxResourcesPerRequest);
} else if (propertyName == "resource_tuner.thread_pool.desired_capacity") {
return std::to_string(profile.threadPoolDesiredCapacity);
} else if (propertyName == "resource_tuner.thread_pool.max_scaling_capacity") {
return std::to_string(profile.threadPoolMaxScalingCapacity);
} else if (propertyName == "resource_tuner.pulse.duration") {
return std::to_string(profile.pulseDuration);
} else if (propertyName == "resource_tuner.garbage_collection.duration") {
return std::to_string(profile.garbageCollectionDuration);
} else if (propertyName == "resource_tuner.garbage_collection.batch_size") {
return std::to_string(profile.garbageCollectionBatchSize);
} else if (propertyName == "resource_tuner.rate_limiter.delta") {
return std::to_string(profile.rateLimiterDelta);
} else if (propertyName == "resource_tuner.penalty.factor") {
return std::to_string(profile.penaltyFactor);
} else if (propertyName == "resource_tuner.reward.factor") {
return std::to_string(profile.rewardFactor);
}

return "";
}

std::unordered_map<std::string, std::string>
RAMConfigGenerator::getAllConfigs(const std::string& ramTier) {
std::unordered_map<std::string, std::string> configs;
ConfigProfile profile = getProfileForTier(ramTier);

configs["resource_tuner.maximum.concurrent.requests"] =
std::to_string(profile.maxConcurrentRequests);
configs["resource_tuner.maximum.resources.per.request"] =
std::to_string(profile.maxResourcesPerRequest);
configs["resource_tuner.thread_pool.desired_capacity"] =
std::to_string(profile.threadPoolDesiredCapacity);
configs["resource_tuner.thread_pool.max_scaling_capacity"] =
std::to_string(profile.threadPoolMaxScalingCapacity);
configs["resource_tuner.pulse.duration"] =
std::to_string(profile.pulseDuration);
configs["resource_tuner.garbage_collection.duration"] =
std::to_string(profile.garbageCollectionDuration);
configs["resource_tuner.garbage_collection.batch_size"] =
std::to_string(profile.garbageCollectionBatchSize);
configs["resource_tuner.rate_limiter.delta"] =
std::to_string(profile.rateLimiterDelta);
configs["resource_tuner.penalty.factor"] =
std::to_string(profile.penaltyFactor);
configs["resource_tuner.reward.factor"] =
std::to_string(profile.rewardFactor);

return configs;
}
9 changes: 9 additions & 0 deletions resource-tuner/core/Include/PropertiesRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ class PropertiesRegistry {

int32_t getPropertiesCount();

/**
* @brief Apply RAM-based configuration overrides
* @param ramTier The RAM tier (low, medium, high, very_high)
* @return int8_t:
* - 1: if RAM-based configs were successfully applied
* - 0: otherwise
*/
int8_t applyRAMBasedConfigs(const std::string& ramTier);

static std::shared_ptr<PropertiesRegistry> getInstance() {
if(propRegistryInstance == nullptr) {
std::shared_ptr<PropertiesRegistry> localpropRegistryInstance(new PropertiesRegistry());
Expand Down
39 changes: 39 additions & 0 deletions resource-tuner/core/PropertiesRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear

#include "PropertiesRegistry.h"
#include "RAMConfigGenerator.h"
#include "Logger.h"

std::shared_ptr<PropertiesRegistry> PropertiesRegistry::propRegistryInstance = nullptr;

Expand Down Expand Up @@ -81,4 +83,41 @@ int32_t PropertiesRegistry::getPropertiesCount() {
return this->mProperties.size();
}

int8_t PropertiesRegistry::applyRAMBasedConfigs(const std::string& ramTier) {
LOGI("PROPERTIES_REGISTRY", "Applying RAM-based configurations for tier: " + ramTier);

// Get all RAM-based configurations
auto ramConfigs = RAMConfigGenerator::getAllConfigs(ramTier);

int32_t appliedCount = 0;
for (const auto& config : ramConfigs) {
const std::string& propName = config.first;
const std::string& propValue = config.second;

// Check if property already exists
std::string existingValue;
if (queryProperty(propName, existingValue) > 0) {
// Property exists, modify it
if (modifyProperty(propName, propValue)) {
LOGI("PROPERTIES_REGISTRY",
"Updated property: " + propName + " = " + propValue +
" (was: " + existingValue + ")");
appliedCount++;
}
} else {
// Property doesn't exist, create it
if (createProperty(propName, propValue)) {
LOGI("PROPERTIES_REGISTRY",
"Created property: " + propName + " = " + propValue);
appliedCount++;
}
}
}

LOGI("PROPERTIES_REGISTRY",
"Applied " + std::to_string(appliedCount) + " RAM-based configurations");

return appliedCount > 0 ? true : false;
}

PropertiesRegistry::~PropertiesRegistry() {}
9 changes: 9 additions & 0 deletions resource-tuner/init/RestuneInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "UrmSettings.h"
#include "SignalRegistry.h"
#include "RestuneParser.h"
#include "RAMConfigGenerator.h"

#define MAX_EXTENSION_LIB_HANDLES 6
static void** extensionLibHandles = nullptr;
Expand Down Expand Up @@ -533,6 +534,14 @@ static ErrCode init(void* arg) {
return RC_MODULE_INIT_FAILURE;
}

// Detect RAM and apply RAM-based configurations
std::string ramTier = AuxRoutines::getRAMTier();
TYPELOGV(NOTIFY_RAM_TIER_DETECTED, ramTier.c_str());

if(!PropertiesRegistry::getInstance()->applyRAMBasedConfigs(ramTier)) {
LOGW("RESTUNE_SERVER_INIT", "Failed to apply RAM-based configurations, using defaults");
}

if(RC_IS_NOTOK(fetchMetaConfigs())) {
TYPELOGD(META_CONF_FETCH_FAILED);
return RC_MODULE_INIT_FAILURE;
Expand Down
Loading