[Unit]
Description=Generate RM Message Queue
-DefaultDependencies=no
+After=systemd-tmpfiles-setup.service
[Service]
Type=oneshot
Name: rscmgr-service
Summary: Daemon for resource manager
Version: 0.1
-Release: 10
+Release: 11
Group: Multimedia/Libraries
License: Apache-2.0
Source0: %{name}-%{version}.tar.gz
rm -rf %{buildroot}
%files
-%manifest rscmgr-service.manifest
+%manifest %{name}.manifest
%license LICENSE.APLv2
%{TZ_SYS_BIN}/gen_rm_msgq
%{TZ_SYS_BIN}/%{name}
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <CCache.h>\r
-\r
-CCache *CCache::m_instance = NULL;\r
-\r
-CCache *CCache::getInstance(void)\r
-{\r
- if (!m_instance) {\r
- m_instance = new(std::nothrow) CCache;\r
- }\r
-\r
- return m_instance;\r
-}\r
-\r
-void CCache::SetAppStatus(std::string app_id, int status)\r
-{\r
- m_visibility.insert(std::pair<std::string, int>(app_id, status));\r
-}\r
-\r
-int CCache::GetAppStatus(std::string app_id)\r
-{\r
- auto it = m_visibility.find(app_id);\r
-\r
- return (it == m_visibility.end()) ? -1 : it->second;\r
-}\r
-\r
-void CCache::Drop(void)\r
-{\r
- m_visibility.clear();\r
-}\r
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <CCache.h>
+
+CCache *CCache::m_instance = NULL;
+
+CCache *CCache::getInstance(void)
+{
+ if (!m_instance) {
+ m_instance = new(std::nothrow) CCache;
+ }
+
+ return m_instance;
+}
+
+void CCache::SetAppStatus(std::string app_id, int status)
+{
+ m_visibility.insert(std::pair<std::string, int>(app_id, status));
+}
+
+int CCache::GetAppStatus(std::string app_id)
+{
+ auto it = m_visibility.find(app_id);
+
+ return (it == m_visibility.end()) ? -1 : it->second;
+}
+
+void CCache::Drop(void)
+{
+ m_visibility.clear();
+}
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <trace.h>\r
-#include <stdlib.h>\r
-#include <iostream>\r
-#include <vconf.h>\r
-#include <aul.h>\r
-#include <system_info.h>\r
-#include <unistd.h>\r
-\r
-#include <rms_debug.h>\r
-#include <rms_type.h>\r
-#include <CConsumer.h>\r
-#include <CDebugUtils.h>\r
-#include <CCache.h>\r
-\r
-CConsumer::CConsumer(IN const rms_consumer_s *consumer)\r
-{\r
- m_consumerID = consumer->consumer_id;\r
- m_priority = consumer->priority;\r
- m_pid = consumer->process_id;\r
- m_app_id.assign(consumer->app_id);\r
-\r
- SetCmdName(m_pid);\r
-}\r
-\r
-void CConsumer::SetCmdName(long pid)\r
-{\r
- char cmd_name[RMS_NAME_BUF_SIZE] = {0, };\r
- std::string delimiter = "/";\r
-\r
- rms_get_cmd_name(m_pid, cmd_name, RMS_NAME_BUF_SIZE);\r
- m_cmd_name.assign(cmd_name);\r
- SERVER_WARN("pid %ld cmd name %s", m_pid, cmd_name);\r
- m_cmd_name = m_cmd_name.substr(m_cmd_name.find_last_of(delimiter) + 1, m_cmd_name.length());\r
- SERVER_WARN("m_cmd_name %s", m_cmd_name.c_str());\r
-}\r
-\r
-bool CConsumer::AddResource(IN int device_id)\r
-{\r
- if (IsUsingResource(device_id)) {\r
- SERVER_INFO("already registered device id(%d) in Consumer(%d)", device_id, m_consumerID);\r
- return false;\r
- }\r
-\r
- m_resources.insert(device_id);\r
- return true;\r
-}\r
-\r
-int CConsumer::ReleaseResource(IN int device_id)\r
-{\r
- if (!IsUsingResource(device_id)) {\r
- SERVER_WARN("CID[%d] / DevID[%d] the consumer does not use this device", m_consumerID, device_id);\r
- return RMS_ERROR;\r
- }\r
-\r
- m_resources.erase(device_id);\r
-\r
- return RMS_OK;\r
-}\r
-\r
-bool CConsumer::IsUsingResource(IN int device_id)\r
-{\r
- auto it = m_resources.find(device_id);\r
-\r
- return (it != m_resources.end());\r
-}\r
-\r
-void CConsumer::SetAppID(IN const char *app_id)\r
-{\r
- m_app_id.assign(app_id);\r
-}\r
-\r
-std::string CConsumer::GetAppId(int pid)\r
-{\r
- char app_id[RMS_NAME_BUF_SIZE] ={0, };\r
- std::string result;\r
-\r
- if (aul_app_get_appid_bypid(pid, app_id, sizeof(app_id)) != AUL_R_OK) {\r
- SERVER_ERR("failed to get appid of %d", pid);\r
- return result;\r
- }\r
-\r
- result.assign(app_id);\r
-\r
- return result;\r
-}\r
-\r
-rms_error_type_e CConsumer::ComparePriority(CConsumer *requester)\r
-{\r
- std::string app_id = requester->GetAppID();\r
-\r
- m_app_id = (m_app_id.empty()) ? GetAppId((int) m_pid) : m_app_id;\r
-\r
- if (!CheckVisibility(app_id)) {\r
- SERVER_ERR("The application is not visible. cannot take resource");\r
- return RMS_ERR_TYPE_REQUEST_OF_INVISIBLE_PROCESS;\r
- }\r
-\r
- rms_priority_s requester_priority = requester->GetPriority();\r
-\r
- if (!ComparePriority(requester_priority, m_priority)) {\r
- char cmd[RMS_NAME_BUF_SIZE] = {0,};\r
- rms_get_cmd_name(m_pid, cmd, sizeof(cmd));\r
- SERVER_ERR("rqs_priority(%d/%d) - user_priority(%s-%d/%d)", requester_priority.main, requester_priority.sub, cmd, m_priority.main, m_priority.sub);\r
- return RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;\r
- }\r
-\r
- return RMS_ERR_TYPE_NONE;\r
-}\r
-\r
-bool CConsumer::ComparePriority(IN rms_priority_s priority1, IN rms_priority_s priority2)\r
-{\r
- if (priority1.main > priority2.main) {\r
- return true;\r
- } else if (priority1.main == priority2.main) {\r
- return priority1.sub >= priority2.sub;\r
- } else {\r
- return false;\r
- }\r
-}\r
-\r
-bool CConsumer::CheckVisibility(IN std::string app_id_requester)\r
-{\r
- if (app_id_requester.empty()) {\r
- SERVER_INFO("requester app id : (null)");\r
- return true;\r
- }\r
-\r
- bool visibility_consumer = (m_app_id.empty()) ? true : GetAppVisibility(m_app_id, false);\r
- bool visibility_requester = GetAppVisibility(app_id_requester, true);\r
-\r
- if (visibility_requester) {\r
- SERVER_INFO("requester is visible(%s)", app_id_requester.c_str());\r
- return true;\r
- }\r
-\r
- if (!visibility_consumer) {\r
- SERVER_INFO("current consumer(%d) is invisible(%s)", m_consumerID, m_app_id.c_str());\r
- return true;\r
- }\r
-\r
- SERVER_ERR("current consumer(%s)- visibility:(%d)", (m_app_id.empty()) ? "null" : m_app_id.c_str(), visibility_consumer);\r
- SERVER_ERR("requester(%s)- visibility:(%d)", app_id_requester.c_str(), visibility_requester);\r
-\r
- return false;\r
-}\r
-\r
-int CConsumer::UpdateAppStatus(std::string app_id)\r
-{\r
- char buf[RMS_NAME_BUF_SIZE];\r
- int status;\r
- int n_max = 4;\r
- snprintf(buf, RMS_NAME_BUF_SIZE, "Get visibility of application '%s'", app_id.c_str());\r
-\r
- for (int i = 0; i < n_max; i++) {\r
- usleep(50*1000);\r
-\r
- trace_begin(buf);\r
- status = aul_app_get_status(app_id.c_str());\r
- trace_end();\r
- SERVER_INFO("app(%s) / status(%d) / (%d)", app_id.c_str(), status, i);\r
-\r
- if (IsVisibleStatus(status)) {\r
- SERVER_ERR("status %d", status);\r
- return status;\r
- }\r
- }\r
- return status;\r
-}\r
-\r
-bool CConsumer::NeedStatusUpdate(std::string app_id)\r
-{\r
- return false;\r
-}\r
-\r
-bool CConsumer::IsVisibleStatus(int status)\r
-{\r
- return (status == STATUS_FOCUS || status == STATUS_VISIBLE);\r
-}\r
-\r
-bool CConsumer::GetAppVisibility(std::string app_id, bool requester)\r
-{\r
- CCache *cache = CCache::getInstance();\r
- int status = cache->GetAppStatus(app_id);\r
-\r
- if (status == -1) {\r
- status = aul_app_get_status(app_id.c_str());\r
-\r
- if (!IsVisibleStatus(status) && requester && NeedStatusUpdate(app_id))\r
- status = UpdateAppStatus(app_id);\r
-\r
- cache->SetAppStatus(app_id, status);\r
- }\r
-\r
- return IsVisibleStatus(status);\r
-}\r
-\r
-bool CConsumer::CheckWebAppState(IN std::string app_id_requesting)\r
-{\r
- if (app_id_requesting.length() == 0)\r
- return false;\r
-\r
- std::string webapp_vconf_key = std::string("rtc/memory/WebApp/") + app_id_requesting;\r
-\r
- char *status = vconf_get_str(webapp_vconf_key.c_str());\r
- if (!status) {\r
- SERVER_INFO("%s is not webapp", app_id_requesting.c_str());\r
- return false;\r
- }\r
-\r
- std::string webapp_status(status);\r
- if (webapp_status.compare("resume")) {\r
- SERVER_INFO("%s is not in resume status (%s)", app_id_requesting.c_str(), webapp_status.c_str());\r
- free(status);\r
- return false;\r
- }\r
-\r
- SERVER_INFO("%s is in resume status (%s)", app_id_requesting.c_str(), webapp_status.c_str());\r
- free(status);\r
-\r
- return true;\r
-}\r
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <trace.h>
+#include <stdlib.h>
+#include <iostream>
+#include <vconf.h>
+#include <aul.h>
+#include <system_info.h>
+#include <unistd.h>
+
+#include <rms_debug.h>
+#include <rms_type.h>
+#include <CConsumer.h>
+#include <CDebugUtils.h>
+#include <CCache.h>
+
+CConsumer::CConsumer(IN const rms_consumer_s *consumer)
+{
+ m_consumerID = consumer->consumer_id;
+ m_priority = consumer->priority;
+ m_pid = consumer->process_id;
+ m_app_id.assign(consumer->app_id);
+
+ SetCmdName(m_pid);
+}
+
+void CConsumer::SetCmdName(long pid)
+{
+ char cmd_name[RMS_NAME_BUF_SIZE] = {0, };
+ std::string delimiter = "/";
+
+ rms_get_cmd_name(m_pid, cmd_name, RMS_NAME_BUF_SIZE);
+ m_cmd_name.assign(cmd_name);
+ SERVER_WARN("pid %ld cmd name %s", m_pid, cmd_name);
+ m_cmd_name = m_cmd_name.substr(m_cmd_name.find_last_of(delimiter) + 1, m_cmd_name.length());
+ SERVER_WARN("m_cmd_name %s", m_cmd_name.c_str());
+}
+
+bool CConsumer::AddResource(IN int device_id)
+{
+ if (IsUsingResource(device_id)) {
+ SERVER_INFO("already registered device id(%d) in Consumer(%d)", device_id, m_consumerID);
+ return false;
+ }
+
+ m_resources.insert(device_id);
+ return true;
+}
+
+int CConsumer::ReleaseResource(IN int device_id)
+{
+ if (!IsUsingResource(device_id)) {
+ SERVER_WARN("CID[%d] / DevID[%d] the consumer does not use this device", m_consumerID, device_id);
+ return RMS_ERROR;
+ }
+
+ m_resources.erase(device_id);
+
+ return RMS_OK;
+}
+
+bool CConsumer::IsUsingResource(IN int device_id)
+{
+ auto it = m_resources.find(device_id);
+
+ return (it != m_resources.end());
+}
+
+void CConsumer::SetAppID(IN const char *app_id)
+{
+ m_app_id.assign(app_id);
+}
+
+std::string CConsumer::GetAppId(int pid)
+{
+ char app_id[RMS_NAME_BUF_SIZE] ={0, };
+ std::string result;
+
+ if (aul_app_get_appid_bypid(pid, app_id, sizeof(app_id)) != AUL_R_OK) {
+ SERVER_ERR("failed to get appid of %d", pid);
+ return result;
+ }
+
+ result.assign(app_id);
+
+ return result;
+}
+
+rms_error_type_e CConsumer::ComparePriority(CConsumer *requester)
+{
+ std::string app_id = requester->GetAppID();
+
+ m_app_id = (m_app_id.empty()) ? GetAppId((int) m_pid) : m_app_id;
+
+ if (!CheckVisibility(app_id)) {
+ SERVER_ERR("The application is not visible. cannot take resource");
+ return RMS_ERR_TYPE_REQUEST_OF_INVISIBLE_PROCESS;
+ }
+
+ rms_priority_s requester_priority = requester->GetPriority();
+
+ if (!ComparePriority(requester_priority, m_priority)) {
+ char cmd[RMS_NAME_BUF_SIZE] = {0,};
+ rms_get_cmd_name(m_pid, cmd, sizeof(cmd));
+ SERVER_ERR("rqs_priority(%d/%d) - user_priority(%s-%d/%d)", requester_priority.main, requester_priority.sub, cmd, m_priority.main, m_priority.sub);
+ return RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;
+ }
+
+ return RMS_ERR_TYPE_NONE;
+}
+
+bool CConsumer::ComparePriority(IN rms_priority_s priority1, IN rms_priority_s priority2)
+{
+ if (priority1.main > priority2.main) {
+ return true;
+ } else if (priority1.main == priority2.main) {
+ return priority1.sub >= priority2.sub;
+ } else {
+ return false;
+ }
+}
+
+bool CConsumer::CheckVisibility(IN std::string app_id_requester)
+{
+ if (app_id_requester.empty()) {
+ SERVER_INFO("requester app id : (null)");
+ return true;
+ }
+
+ bool visibility_consumer = (m_app_id.empty()) ? true : GetAppVisibility(m_app_id, false);
+ bool visibility_requester = GetAppVisibility(app_id_requester, true);
+
+ if (visibility_requester) {
+ SERVER_INFO("requester is visible(%s)", app_id_requester.c_str());
+ return true;
+ }
+
+ if (!visibility_consumer) {
+ SERVER_INFO("current consumer(%d) is invisible(%s)", m_consumerID, m_app_id.c_str());
+ return true;
+ }
+
+ SERVER_ERR("current consumer(%s)- visibility:(%d)", (m_app_id.empty()) ? "null" : m_app_id.c_str(), visibility_consumer);
+ SERVER_ERR("requester(%s)- visibility:(%d)", app_id_requester.c_str(), visibility_requester);
+
+ return false;
+}
+
+int CConsumer::UpdateAppStatus(std::string app_id)
+{
+ char buf[RMS_NAME_BUF_SIZE];
+ int status;
+ int n_max = 4;
+ snprintf(buf, RMS_NAME_BUF_SIZE, "Get visibility of application '%s'", app_id.c_str());
+
+ for (int i = 0; i < n_max; i++) {
+ usleep(50*1000);
+
+ trace_begin(buf);
+ status = aul_app_get_status(app_id.c_str());
+ trace_end();
+ SERVER_INFO("app(%s) / status(%d) / (%d)", app_id.c_str(), status, i);
+
+ if (IsVisibleStatus(status)) {
+ SERVER_ERR("status %d", status);
+ return status;
+ }
+ }
+ return status;
+}
+
+bool CConsumer::NeedStatusUpdate(std::string app_id)
+{
+ return false;
+}
+
+bool CConsumer::IsVisibleStatus(int status)
+{
+ return (status == STATUS_FOCUS || status == STATUS_VISIBLE);
+}
+
+bool CConsumer::GetAppVisibility(std::string app_id, bool requester)
+{
+ CCache *cache = CCache::getInstance();
+ int status = cache->GetAppStatus(app_id);
+
+ if (status == -1) {
+ status = aul_app_get_status(app_id.c_str());
+
+ if (!IsVisibleStatus(status) && requester && NeedStatusUpdate(app_id))
+ status = UpdateAppStatus(app_id);
+
+ cache->SetAppStatus(app_id, status);
+ }
+
+ return IsVisibleStatus(status);
+}
+
+bool CConsumer::CheckWebAppState(IN std::string app_id_requesting)
+{
+ if (app_id_requesting.length() == 0)
+ return false;
+
+ std::string webapp_vconf_key = std::string("rtc/memory/WebApp/") + app_id_requesting;
+
+ char *status = vconf_get_str(webapp_vconf_key.c_str());
+ if (!status) {
+ SERVER_INFO("%s is not webapp", app_id_requesting.c_str());
+ return false;
+ }
+
+ std::string webapp_status(status);
+ if (webapp_status.compare("resume")) {
+ SERVER_INFO("%s is not in resume status (%s)", app_id_requesting.c_str(), webapp_status.c_str());
+ free(status);
+ return false;
+ }
+
+ SERVER_INFO("%s is in resume status (%s)", app_id_requesting.c_str(), webapp_status.c_str());
+ free(status);
+
+ return true;
+}
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <assert.h>\r
-#include <CConsumer.h>\r
-#include <CConsumerContainer.h>\r
-\r
-CConsumerContainer *CConsumerContainer::m_instance = NULL;\r
-\r
-CConsumerContainer *CConsumerContainer::getInstance(void)\r
-{\r
- if (!m_instance) {\r
- m_instance = new(std::nothrow) CConsumerContainer;\r
- assert(m_instance);\r
- }\r
-\r
- return m_instance;\r
-}\r
-\r
-CConsumer *CConsumerContainer::findConsumer(int consumer_id)\r
-{\r
- std::map<int, CConsumer*>::iterator it = m_consumers.find(consumer_id);\r
-\r
- return (it == m_consumers.end()) ? NULL : (*it).second;\r
-}\r
-\r
-bool CConsumerContainer::AddConsumer(int consumer_id, CConsumer *consumer)\r
-{\r
- std::map<int, CConsumer*>::iterator it = m_consumers.find(consumer_id);\r
-\r
- if (it != m_consumers.end())\r
- return false;\r
-\r
- m_consumers.insert(std::pair<int, CConsumer*>(consumer_id, consumer));\r
- return true;\r
-}\r
-\r
-void CConsumerContainer::RemoveConsumer(int consumer_id)\r
-{\r
- m_consumers.erase(consumer_id);\r
-}\r
-\r
-std::map<int, CConsumer*> CConsumerContainer::findConsumers(int pid)\r
-{\r
- std::map<int, CConsumer*> result;\r
-\r
- for (auto const &it : m_consumers) {\r
- CConsumer *consumer = it.second;\r
-\r
- if (consumer->GetPid() != pid)\r
- continue;\r
-\r
- result.insert(std::pair<int, CConsumer*>(it.first, it.second));\r
- }\r
-\r
- return result;\r
-}\r
-\r
-std::map<int, CConsumer*> CConsumerContainer::FindConsumers(std::string app_id)\r
-{\r
- std::map<int, CConsumer*> result;\r
- for (auto const &it : m_consumers) {\r
- CConsumer *consumer = it.second;\r
- if (app_id.compare(consumer->GetAppID()))\r
- continue;\r
-\r
- result.insert(std::pair<int, CConsumer*>(it.first, it.second));\r
- }\r
-\r
- return result;\r
-}\r
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <CConsumer.h>
+#include <CConsumerContainer.h>
+
+CConsumerContainer *CConsumerContainer::m_instance = NULL;
+
+CConsumerContainer *CConsumerContainer::getInstance(void)
+{
+ if (!m_instance) {
+ m_instance = new(std::nothrow) CConsumerContainer;
+ assert(m_instance);
+ }
+
+ return m_instance;
+}
+
+CConsumer *CConsumerContainer::findConsumer(int consumer_id)
+{
+ std::map<int, CConsumer*>::iterator it = m_consumers.find(consumer_id);
+
+ return (it == m_consumers.end()) ? NULL : (*it).second;
+}
+
+bool CConsumerContainer::AddConsumer(int consumer_id, CConsumer *consumer)
+{
+ std::map<int, CConsumer*>::iterator it = m_consumers.find(consumer_id);
+
+ if (it != m_consumers.end())
+ return false;
+
+ m_consumers.insert(std::pair<int, CConsumer*>(consumer_id, consumer));
+ return true;
+}
+
+void CConsumerContainer::RemoveConsumer(int consumer_id)
+{
+ m_consumers.erase(consumer_id);
+}
+
+std::map<int, CConsumer*> CConsumerContainer::findConsumers(int pid)
+{
+ std::map<int, CConsumer*> result;
+
+ for (auto const &it : m_consumers) {
+ CConsumer *consumer = it.second;
+
+ if (consumer->GetPid() != pid)
+ continue;
+
+ result.insert(std::pair<int, CConsumer*>(it.first, it.second));
+ }
+
+ return result;
+}
+
+std::map<int, CConsumer*> CConsumerContainer::FindConsumers(std::string app_id)
+{
+ std::map<int, CConsumer*> result;
+ for (auto const &it : m_consumers) {
+ CConsumer *consumer = it.second;
+ if (app_id.compare(consumer->GetAppID()))
+ continue;
+
+ result.insert(std::pair<int, CConsumer*>(it.first, it.second));
+ }
+
+ return result;
+}
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <unistd.h>\r
-#include <sys/stat.h>\r
-#include <fcntl.h>\r
-#include <glib.h>\r
-#include <stdlib.h>\r
-\r
-#include <vconf.h>\r
-#include <stdio.h>\r
-#include <system_info.h>\r
-#include <sys/types.h>\r
-#include <signal.h>\r
-#include <vconf.h>\r
-#include <tzplatform_config.h>\r
-#include <dlfcn.h>\r
-\r
-#include <CDebugUtils.h>\r
-#include <rms_debug.h>\r
-#include <bundle.h>\r
-#include <bundle_internal.h>\r
-#include <syspopup_caller.h>\r
-\r
-\r
-static bool product_type_init = false;\r
-static int product_type = 0; //SYSTEM_INFO_PRODUCT_TYPE_TV;\r
-\r
-// The process list which is killed by resource manager\r
-static GHashTable *process_htable = NULL;\r
-\r
-#define RMS_IS_DEBUG_IMAGE (access("/etc/debug", F_OK) == 0)\r
-\r
-const char *rm_convert_state_enum_to_string(rms_resource_internal_state_e state_enum)\r
-{\r
- switch (state_enum) {\r
- case RMS_INTERNAL_STATE_FREE:\r
- return "FREE";\r
- case RMS_INTERNAL_STATE_SHARABLE:\r
- return "SHARABLE";\r
- case RMS_INTERNAL_STATE_SHARED:\r
- return "SHARED";\r
- case RMS_INTERNAL_STATE_EXCLUSIVE:\r
- return "EXCLUSIVE";\r
- case RMS_INTERNAL_STATE_ERROR:\r
- default:\r
- return "NONE";\r
- }\r
-}\r
-\r
-const char *rm_convert_requested_state_enum_to_string(rms_requests_resource_state_e state_enum)\r
-{\r
- switch (state_enum) {\r
- case RMS_STATE_PASSIVE:\r
- return "PASSIVE";\r
- case RMS_STATE_SHARABLE:\r
- return "SHARABLE";\r
- case RMS_STATE_EXCLUSIVE:\r
- return "EXCLUSIVE";\r
- case RMS_STATE_EXCLUSIVE_CONDITIONAL:\r
- return "EXCLUSIVE_CONDITIONAL";\r
- case RMS_STATE_EXCLUSIVE_AUTO:\r
- return "EXCLUSIVE_AUTO";\r
- case RMS_STATE_EXCLUSIVE_PREFERENCE:\r
- return "EXCLUSIVE_PREFERENCE";\r
- default:\r
- return "NONE";\r
- }\r
-}\r
-\r
-const char *rm_convert_category_enum_to_string(rms_rsc_category_e category_enum)\r
-{\r
- switch (category_enum) {\r
- case RMS_CATEGORY_NONE:\r
- return "NONE";\r
- case RMS_CATEGORY_AUDIO_DECODER:\r
- return "Audio_Decoder";\r
- case RMS_CATEGORY_AUDIO_SPDIF_ES_OUTPUT:\r
- return "Not Defined Yet";\r
- case RMS_CATEGORY_VIDEO_DECODER:\r
- return "Video_Decoder";\r
- case RMS_CATEGORY_DEMUX:\r
- return "Demux_Main";\r
- case RMS_CATEGORY_AUDIO_ENCODER:\r
- return "Audio_Encoder";\r
- case RMS_CATEGORY_VIDEO_ENCODER:\r
- return "Video_Encoder";\r
- case RMS_CATEGORY_SCALER:\r
- return "Video_Scaler";\r
- case RMS_CATEGORY_TUNER:\r
- return "Tuner";\r
- case RMS_CATEGORY_AUDIO_MAIN_OUT:\r
- return "Audio_Main_Out";\r
- case RMS_CATEGORY_AUDIO_REMOTE_OUT:\r
- return "Audio_Remote_Out";\r
- case RMS_CATEGORY_AUDIO_SCART_OUT:\r
- return "Audio_Scart_Out";\r
- case RMS_CATEGORY_MM_PCM_OUT:\r
- return "MM_PCM_playback";\r
- case RMS_CATEGORY_AUDIO_DECODER_SUB:\r
- return "Audio_Decorder_Sub";\r
- case RMS_CATEGORY_JPEG_DECODER:\r
- return "JPEG_Decoder";\r
- case RMS_CATEGORY_MJPEG_DECODER:\r
- return "MJPEG_Decoder";\r
- case RMS_CATEGORY_SCALER_SUB:\r
- return "Video_Scaler_Sub";\r
- case RMS_CATEGORY_EXT_VIDEO_SRC:\r
- return "Ext_Video_Src";\r
- case RMS_CATEGORY_EXT_AUDIO_SRC:\r
- return "Ext_Audio_Src";\r
- case RMS_CATEGORY_EXT_HDMI_SRC:\r
- return "Ext_HDMI_Src";\r
- case RMS_CATEGORY_VIDEO_DECODER_SUB:\r
- return "Video_Decoder_Sub";\r
- case RMS_CATEGORY_CAMERA:\r
- return "Camera";\r
- case RMS_CATEGORY_DEMUX_REC:\r
- return "Demux_Rec";\r
- case RMS_CATEGORY_TUNER_SUB:\r
- return "Tuner_Sub";\r
- case RMS_CATEGORY_VIDEO_DECODER_UHD:\r
- return "Video_Decoder UHD";\r
- case RMS_CATEGORY_INPUT_SRC_DTV:\r
- return "Input_Src_DTV";\r
- case RMS_CATEGORY_INPUT_SRC_ATV:\r
- return "Input_Src_ATV";\r
- case RMS_CATEGORY_INPUT_SRC_HDMI:\r
- return "Input_Src_HDMI";\r
- case RMS_CATEGORY_INPUT_SRC_COMP:\r
- return "Input_Src_COMP";\r
- case RMS_CATEGORY_INPUT_SRC_AV:\r
- return "Input_Src_AV";\r
- case RMS_CATEGORY_INPUT_SRC_SCART:\r
- return "Input_Src_SCART";\r
- case RMS_CATEGORY_MIC:\r
- return "Mic";\r
- case RMS_CATEGORY_SW_DECODER:\r
- return "SWDecoder";\r
- case RMS_CATEGORY_MMP_MEMORY_CLUSTER:\r
- return "MMPlayer MemoryCluster";\r
- case RMS_CATEGORY_JPEG_DECODER_8K:\r
- return "JPEG_Decoder 8K";\r
- case RMS_CATEGORY_SCALER_BG:\r
- return "Video_Scaler_BG";\r
- default:\r
- return "";\r
- }\r
-}\r
-\r
-const char *rm_convert_device_enum_to_string(rms_device_e device_enum)\r
-{\r
- switch (device_enum) {\r
- case RMS_DEVICE_NONE:\r
- return "NONE";\r
- case RMS_DEVICE_AUDIO_MAIN_OUT:\r
- return "audio_main_out";\r
- case RMS_DEVICE_AUDIO_REMOTE_OUT:\r
- return "audio_remote_out";\r
- case RMS_DEVICE_AUDIO_SCART_OUT:\r
- return "audio_scart_out";\r
- case RMS_DEVICE_MM_PCM_OUT:\r
- return "mm_pcm_out";\r
- case RMS_DEVICE_JPEG_DECODER:\r
- return "jpeg_decoder";\r
- case RMS_DEVICE_DEMUX0:\r
- return "demux0";\r
- case RMS_DEVICE_DEMUX1:\r
- return "demux1";\r
- case RMS_DEVICE_DEMUX2:\r
- return "demux2";\r
- case RMS_DEVICE_DEMUX3:\r
- return "demux3";\r
- case RMS_DEVICE_AUDIO_ENCODER:\r
- return "audio_encoder";\r
- case RMS_DEVICE_VIDEO_ENCODER:\r
- return "video_encoder";\r
- case RMS_DEVICE_SCALER:\r
- return "scaler";\r
- case RMS_DEVICE_EXT_VIDEO_SRC:\r
- return "ext_video_src";\r
- case RMS_DEVICE_EXT_AUDIO_SRC:\r
- return "ext_autio_src";\r
- case RMS_DEVICE_EXT_HDMI_SRC:\r
- return "ext_hdmi_src";\r
- case RMS_DEVICE_CAMERA:\r
- return "camera";\r
- case RMS_DEVICE_TUNER:\r
- return "tuner";\r
- case RMS_DEVICE_TUNER_SUB:\r
- return "tuner_sub";\r
- case RMS_DEVICE_SCALER_SUB:\r
- return "scaler_sub";\r
- case RMS_DEVICE_AUDIO_DECODER:\r
- return "audio_decoder";\r
- case RMS_DEVICE_AUDIO_DECODER_SUB:\r
- return "audio_decoder_sub";\r
- case RMS_DEVICE_VIDEO_DECODER_MAIN:\r
- return "video_decoder_main";\r
- case RMS_DEVICE_VIDEO_DECODER_SUB:\r
- return "video_decoder_sub";\r
- case RMS_DEVICE_VIDEO_DECODER_UDDEC:\r
- return "video_decoder_uddec";\r
- case RMS_DEVICE_VIDEO_DECODER_UDHEVC:\r
- return "video_decoder_udhevc";\r
- case RMS_DEVICE_AUDIO_SPDIF_ES_OUTPUT:\r
- return "audio_spdif_es_output";\r
- case RMS_DEVICE_MIC:\r
- return "mic";\r
- case RMS_DEVICE_EXT_COMP_SRC:\r
- return "ext_comp_src";\r
- case RMS_DEVICE_EXT_AV_SRC:\r
- return "av_src";\r
- case RMS_DEVICE_MJPEG_DECODER:\r
- return "mjpeg_decoder";\r
- case RMS_DEVICE_JPEG_DECODER_UHD:\r
- return "jpeg_decoder_uhd";\r
- case RMS_DEVICE_MJPEG_DECODER_UHD:\r
- return "mjpeg_decoder_uhd";\r
- case RMS_DEVICE_SW_DECODER:\r
- return "sw_decoder";\r
- default:\r
- return "";\r
- }\r
-}\r
-\r
-const char *rm_print_allocation_failure_reason(int ret_value)\r
-{\r
- switch (ret_value) {\r
- case RMS_OK:\r
- return "OK";\r
- case RMS_ERROR:\r
- return "Cannot Allocate Resources";\r
- case RMS_ERROR_TAKE_RESOURCE_FROM_OTHER_CONSUMER:\r
- return "RESOURCE CONFLICT - Other Consumer Is Using";\r
- case RMS_OK_UHD_RESOURCE_CONFLICT:\r
- return "UHD RESOURCE CONFLICT - Other Consumer Is Using";\r
- default:\r
- return "";\r
- }\r
-}\r
-void rms_create_popup(const char *title, const char *text)\r
-{\r
- bundle *(*bundle_create_fp) (void);\r
- int (*bundle_add_fp)(bundle*, const char*, const char*);\r
- const char *(*bundle_get_val_fp) (bundle*, const char*);\r
- int (*bundle_free_fp) (bundle*);\r
- int (*syspopup_launch_fp) (char*, bundle*);\r
- void *libsyspopup_handle = NULL;\r
- void *libbundle_handle = NULL;\r
- bundle *b = NULL;\r
- char *error;\r
-\r
- libsyspopup_handle = dlopen(LIBDIR"/libsyspopup_caller.so.0.1.0", RTLD_LAZY);\r
- if (!libsyspopup_handle) {\r
- SERVER_ERR("failed to load syspopup library");\r
- goto end;\r
- }\r
-\r
- libbundle_handle = dlopen(LIBDIR"/libbundle.so.0", RTLD_LAZY);\r
-\r
- if (!libbundle_handle) {\r
- SERVER_ERR("failed to load bundle library");\r
- goto end;\r
- }\r
-\r
- error = NULL;\r
-\r
- bundle_create_fp = (bundle *(*)(void)) dlsym(libbundle_handle, "bundle_create");\r
-\r
- if ((error = dlerror()) != NULL) {\r
- SERVER_ERR("failed to find bundle_create");\r
- goto end;\r
-\r
- }\r
-\r
- bundle_add_fp = (int (*)(bundle*, const char*, const char*)) dlsym(libbundle_handle, "bundle_add");\r
-\r
- if ((error = dlerror()) != NULL) {\r
- SERVER_ERR("failed to find bundle_add");\r
- goto end;\r
- }\r
-\r
- bundle_get_val_fp = (const char *(*)(bundle*, const char*)) dlsym(libbundle_handle, "bundle_get_val");\r
-\r
- if ((error = dlerror()) != NULL) {\r
- SERVER_ERR("failed to find bundle_get_val");\r
- goto end;\r
- }\r
-\r
- bundle_free_fp = (int (*)(bundle*)) dlsym(libbundle_handle, "bundle_free");\r
-\r
- if ((error = dlerror()) != NULL) {\r
- SERVER_ERR("failed to find bundle_free");\r
- goto end;\r
- }\r
-\r
- syspopup_launch_fp = (int (*)(char*, bundle*)) dlsym(libsyspopup_handle, "syspopup_launch");\r
-\r
- if ((error = dlerror()) != NULL) {\r
- SERVER_ERR("failed to find alert-syspopup");\r
- goto end;\r
- }\r
-\r
- b = bundle_create_fp();\r
- if (!b) {\r
- SERVER_ERR("failed to create bundle");\r
- goto end;\r
- }\r
-\r
- bundle_add_fp(b, "type", "title_message_1button");\r
- bundle_add_fp(b, "title", title);\r
- bundle_add_fp(b, "text", text);\r
-\r
- bundle_get_val_fp(b, "type");\r
- bundle_get_val_fp(b, "title");\r
- bundle_get_val_fp(b, "text");\r
-\r
- syspopup_launch_fp((char*)"alert-syspopup", b);\r
- bundle_free_fp(b);\r
-\r
-end:\r
- if (libsyspopup_handle)\r
- dlclose(libsyspopup_handle);\r
-\r
- if (libbundle_handle)\r
- dlclose(libbundle_handle);\r
-}\r
-\r
-int rms_get_cmd_name(pid_t pid, char *name_out, int size)\r
-{\r
- char name[RMS_NAME_BUF_SIZE] = {0,};\r
- FILE *f;\r
- size_t sz;\r
-\r
- snprintf(name, sizeof(name), "/proc/%d/cmdline", pid);\r
- // Check if the process exists and is accessible\r
- if (access(name, R_OK) != 0) {\r
- SERVER_ERR("failed to access (%s) : %d", name, errno);\r
- return RMS_ERROR;\r
- }\r
-\r
- f = fopen(name, "r");\r
- if (!f) {\r
- SERVER_ERR("failed to open cmdline(%s) : %d", name, errno);\r
- return RMS_ERROR;\r
- }\r
-\r
- sz = fread(name, sizeof(char), sizeof(name)-1, f);\r
- name[sz] = '\0';\r
- fclose(f);\r
-\r
- snprintf(name_out, size, "%s", name);\r
-\r
- return RMS_OK;\r
-}\r
-\r
-void rms_print_log_console(char *buf)\r
-{\r
- int fd, ret;\r
- char output[RMS_CONSOLE_BUF_SIZE] ={0,};\r
-\r
- struct timespec tnow;\r
-\r
- fd = open("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);\r
-\r
- if (fd < 0) {\r
- SERVER_ERR("console device open fail");\r
- return;\r
- }\r
-\r
- if (is_symlink_file("/dev/console")) {\r
- SERVER_ERR("%s is symbolic link file", "/dev/console");\r
- close(fd);\r
- return;\r
- }\r
-\r
- ret = clock_gettime(CLOCK_MONOTONIC, &tnow);\r
- snprintf(output, RMS_CONSOLE_BUF_SIZE, "[RMS][%ld.%6ld] %s", tnow.tv_sec, tnow.tv_nsec/1000, buf);\r
- ret = write(fd, output, strlen(output));\r
-\r
- if (ret < 0) {\r
- SERVER_ERR("Fail to write on console directly");\r
- }\r
-\r
- close(fd);\r
-}\r
-\r
-int rm_get_product_type(void)\r
-{\r
- if (product_type_init)\r
- return product_type;\r
-\r
- int type = 0; /* SYSTEM_INFO_PRODUCT_TYPE_TV */\r
-\r
- if (system_info_get_custom_int("com.samsung/featureconf/product.product_type", &type) != SYSTEM_INFO_ERROR_NONE) {\r
- SERVER_ERR("Failed to get com.samsung/featureconf/product.product_type");\r
- }\r
-\r
- product_type_init = true;\r
- product_type = type;\r
-\r
- return product_type;\r
-}\r
-\r
-int rm_is_valid_pid(int pid)\r
-{\r
- if (kill((pid_t) pid, 0) == 0) {\r
- SERVER_INFO("pid(%d) is alive", pid);\r
- return 1;\r
- }\r
-\r
- SERVER_ERR("pid(%d) / errno(%d)", pid, errno);\r
-\r
- return (errno == ESRCH) ? 0 : 1;\r
-}\r
-\r
-static void process_htable_destory_key(gpointer key)\r
-{\r
- if (key)\r
- free(key);\r
-}\r
-\r
-static void process_htable_create(void)\r
-{\r
- if (process_htable) {\r
- SERVER_ERR("hash table already created");\r
- return;\r
- }\r
-\r
- process_htable = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)process_htable_destory_key, NULL);\r
-\r
- SERVER_INFO("process hash table created");\r
-}\r
-\r
-static void process_htable_clear(void)\r
-{\r
- SERVER_INFO("clear process hash table");\r
-\r
- if (!process_htable)\r
- return;\r
-\r
- g_hash_table_remove_all(process_htable);\r
-}\r
-\r
-static void process_htable_insert(const char *name)\r
-{\r
- const int PROCESS_DATA_LIMIT = 100; // The maxinum size is (RMS_NAME_BUF_SIZE * PROCESS_DATA_LIMIT)\r
-\r
- if (!process_htable)\r
- process_htable_create();\r
-\r
- if (g_hash_table_contains(process_htable, name))\r
- return;\r
-\r
- if (g_hash_table_size(process_htable) >= PROCESS_DATA_LIMIT)\r
- process_htable_clear();\r
-\r
- char *key_name = (char*) strndup(name, strlen(name));\r
-\r
- g_hash_table_insert(process_htable, key_name, (gpointer) 1);\r
-\r
- SERVER_ERR("process info (%s) inserted to hash table (%d)", name, g_hash_table_size(process_htable));\r
-}\r
-\r
-\r
-bool process_htable_contains(const char *name)\r
-{\r
- bool result = false;\r
-\r
- if (!process_htable) {\r
- SERVER_INFO("(%s) - no table", name);\r
- return false;\r
- }\r
-\r
- if (g_hash_table_size(process_htable) == 0) {\r
- SERVER_INFO("(%s) - empty", name);\r
- return false;\r
- }\r
-\r
- result = g_hash_table_contains(process_htable, name);\r
-\r
- SERVER_INFO("(%s) - result(%d)", name, result);\r
-\r
- // resource manager is supposed to clear data once it's checked by application\r
- process_htable_clear();\r
-\r
- return result;\r
-}\r
-\r
-int rms_report_emergency(IN int cid, IN int pid, IN int requester)\r
-{\r
- const char *vconf_request_cold_poweroff = "memory/boot/cold_poweroff_request_pkg";\r
- int retry = 25; // 20ms * 25 times => 500ms\r
- int ret = 0;\r
-\r
- SERVER_ERR("consumer is not responding....CID[%d]/PID[%d]/Requester(%d) - set cold power off mode", cid, pid, requester);\r
-\r
- if (vconf_set_str(vconf_request_cold_poweroff, "resource-manager") != 0) {\r
- SERVER_ERR("Failed to set request cold power off");\r
- } else {\r
- SERVER_ERR("memory/boot/cold_poweroff_request_pkg set as resource-manager");\r
- }\r
-\r
- char process_name[RMS_NAME_BUF_SIZE] = {0,};\r
-\r
- if (rms_get_cmd_name(pid, process_name, RMS_NAME_BUF_SIZE) == RMS_OK) {\r
- process_htable_insert(process_name);\r
- }\r
-\r
- SERVER_ERR("kill PID(%d)", pid);\r
-\r
- int signal = SIGKILL;\r
-\r
- if (RMS_IS_DEBUG_IMAGE) {\r
- signal = SIGABRT;\r
- retry = 250; // 20ms * 250 times => 5 sec\r
- }\r
-\r
- ret = kill(pid, signal);\r
-\r
- if (ret!=0) {\r
- SERVER_ERR("Failed to kill(%d), errno(%d)", pid, errno);\r
- }\r
-\r
- // wait until process is really terminated for 500ms\r
- while (retry > 0 && rm_is_valid_pid(pid)) {\r
- retry--;\r
- SERVER_ERR("pid(%d) still alive(%d)", pid, retry);\r
- usleep(20*1000);\r
- continue;\r
- }\r
-\r
- if (RMS_IS_DEBUG_IMAGE && retry <= 0) {\r
- //process didn't get terminated for 5 seconds\r
- SERVER_ERR("pid(%d) is not terminated.", pid);\r
- return RMS_ERROR;\r
- }\r
-\r
- return RMS_OK;\r
-}\r
-\r
-void rms_display_timeout_error_popup(rms_alarm_reason_e reason, rms_consumer_tobe_returned_s info)\r
-{\r
- const char *title = "Resource Allocation Failure";\r
- const char *style_notification_msg = "<font_size=30 color=#00FF00>";\r
- const char *style_process_name = "<font_size=25 color=#C90000>";\r
- const char *indent = " ";\r
- const char *notification_msg = "Please contact the owner(s) of process(es) below<br>";\r
- const char *reason0 = " Resource allocation failed because there is no callback response from below process(es)<br> ";\r
- const char *reason1 = " Resource allocation failed because below process(es) did not request deallocation<br> ";\r
-\r
- char name[RMS_NAME_BUF_SIZE] = {0,};\r
- GString *gstr;\r
-\r
- if (!RMS_IS_DEBUG_IMAGE) {\r
- SERVER_ERR("Not debug mode. Timeout alarm popup is not shown. reason(%d)", (int)reason);\r
- return;\r
- }\r
-\r
- SERVER_ERR("timeout alarm");\r
-\r
- gstr = g_string_new("");\r
-\r
- if (!gstr) {\r
- SERVER_ERR("Failed to create debug popup command");\r
- return;\r
- }\r
-\r
- g_string_append_printf(gstr, "%s", style_notification_msg);\r
-\r
- switch (reason) {\r
- case RMS_ALARM_NO_CALLBACK_RESPONSE:\r
- g_string_append_printf(gstr, "%s%s", indent, reason0);\r
- break;\r
- case RMS_ALARM_NO_DEALLOCATION:\r
- g_string_append_printf(gstr, "%s%s", indent, reason1);\r
- break;\r
- default :\r
- break;\r
- }\r
-\r
- g_string_append_printf(gstr, "%s%s%s", indent, notification_msg, style_process_name);\r
-\r
- rms_get_cmd_name(info.process_id, name, sizeof(name));\r
- g_string_append_printf(gstr, "%s%s : %d - %s%s", indent, "pid", (int)(info.process_id), name, " <br>");\r
-\r
- for (int i = 0; i < info.n_conflicted; i++) {\r
- g_string_append_printf(gstr, "%s [%d] %s%s", indent, i+1, rm_convert_category_enum_to_string(info.conflicted_resources[i].category_id), " <br>");\r
- }\r
- rms_create_popup(title, gstr->str);\r
- SERVER_ERR("Command: %s", gstr->str);\r
- g_string_free(gstr, true);\r
-}\r
-\r
-static bool rms_read_index(int *data)\r
-{\r
- FILE *fp = NULL;\r
- char str[10] = {0,};\r
- size_t str_size;\r
- const char *filename = "/proc/device-tree/rm_tbl_idx";\r
-\r
- if (!data) {\r
- SERVER_ERR("invalid input : null data");\r
- return false;\r
- }\r
-\r
- fp = fopen(filename, "rb");\r
-\r
- if (!fp) {\r
- SERVER_ERR("failed to open (%s) - errno(%d)", filename, errno);\r
- return false;\r
- }\r
-\r
- str_size = fread(str, sizeof(char), sizeof(str)-1, fp);\r
-\r
- str[str_size] = '\0';\r
-\r
- if (str_size == 0) {\r
- fclose(fp);\r
- return false;\r
- }\r
-\r
- *data = atoi(str);\r
-\r
- fclose(fp);\r
- fp = NULL;\r
-\r
- return true;\r
-}\r
-\r
-void rms_display_resource_table_error_popup(void)\r
-{\r
- const char *title = "FATAL ERROR!!!";\r
- const char *reason = " Resource Manager can't find a resource table for this board<br> ";\r
- const char *style_notification_msg = "<font_size=30 color=#FF0000>";\r
- const char *indent = " ";\r
- const char *notification_msg = "<br>";\r
-\r
- GString *gstr = g_string_new("");\r
- char *chipset_info;\r
- int model_index = -1;\r
-\r
- if (!gstr) {\r
- SERVER_ERR("Failed to create debug popup command");\r
- return;\r
- }\r
-\r
- g_string_append_printf(gstr, "%s%s", indent, reason);\r
- g_string_append_printf(gstr, "%s%s%s", indent, notification_msg, style_notification_msg);\r
- g_string_append_printf(gstr, "%sProduct type : %d%s", indent, rm_get_product_type(), " <br>");\r
-\r
- if (system_info_get_custom_string("com.samsung/featureconf/product.chipset", &chipset_info)!= SYSTEM_INFO_ERROR_NONE) {\r
- SERVER_ERR("Failed to get chipset from system-info");\r
- goto end;\r
- }\r
-\r
- g_string_append_printf(gstr, "%sChipset : %s%s", indent, chipset_info, " <br>");\r
-\r
- if (!rms_read_index(&model_index)) {\r
- SERVER_ERR("failed to read model index");\r
- }\r
-\r
- g_string_append_printf(gstr, "%sIndex : %d%s", indent, model_index, " <br>");\r
-\r
- rms_create_popup(title,gstr->str);\r
-\r
- if (chipset_info) {\r
- free(chipset_info);\r
- }\r
-\r
-end:\r
- g_string_free(gstr, true);\r
- return;\r
-}\r
-\r
-void rms_print_model_info(void)\r
-{\r
- static char *chipset_info = NULL;\r
- static int rm_index = -1;\r
-\r
- if (!chipset_info) {\r
- if (system_info_get_custom_string("com.samsung/featureconf/product.chipset", &chipset_info)!= SYSTEM_INFO_ERROR_NONE)\r
- SERVER_ERR("Failed to get chipset");\r
- }\r
-\r
- if (rm_index == -1) {\r
- if (!rms_read_index(&rm_index))\r
- SERVER_ERR("failed to read rm index");\r
- }\r
-\r
- SERVER_ERR("> chipset(%s)/product_type(%d)/rm_index(%d)", chipset_info? chipset_info:"", rm_get_product_type(), rm_index);\r
-\r
- char buf[512];\r
- snprintf(buf, 512, "resource table not loaded! > chipset(%s)/product_type(%d)/rm_index(%d)", chipset_info? chipset_info:"", rm_get_product_type(), rm_index);\r
- rms_print_log_console(buf);\r
-}\r
-\r
-int is_symlink_file(const char *path)\r
-{\r
- struct stat st;\r
- if (lstat(path, &st) == -1) {\r
- SERVER_ERR("stat error. file path(%s)", path);\r
- return 0;\r
- }\r
-\r
- return (S_ISLNK(st.st_mode)) ? 1 : 0;\r
-}\r
-\r
-const char *rm_convert_error_type_to_string(rms_error_type_e error_type)\r
-{\r
- switch (error_type) {\r
- case RMS_ERR_TYPE_NONE:\r
- return "None";\r
- case RMS_ERR_TYPE_REQUEST_OF_INVISIBLE_PROCESS:\r
- return "Request of invisible process";\r
- case RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS:\r
- return "Request of low priority process";\r
- case RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE:\r
- return "Not available resource";\r
- case RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST:\r
- return "Requested resource does not exist";\r
- case RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER:\r
- return "Take resource from other consumer";\r
- default:\r
- return "";\r
- }\r
-}\r
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <glib.h>
+#include <stdlib.h>
+
+#include <vconf.h>
+#include <stdio.h>
+#include <system_info.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <vconf.h>
+#include <tzplatform_config.h>
+#include <dlfcn.h>
+
+#include <CDebugUtils.h>
+#include <rms_debug.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <syspopup_caller.h>
+
+
+static bool product_type_init = false;
+static int product_type = 0; //SYSTEM_INFO_PRODUCT_TYPE_TV;
+
+// The process list which is killed by resource manager
+static GHashTable *process_htable = NULL;
+
+#define RMS_IS_DEBUG_IMAGE (access("/etc/debug", F_OK) == 0)
+
+const char *rm_convert_state_enum_to_string(rms_resource_internal_state_e state_enum)
+{
+ switch (state_enum) {
+ case RMS_INTERNAL_STATE_FREE:
+ return "FREE";
+ case RMS_INTERNAL_STATE_SHARABLE:
+ return "SHARABLE";
+ case RMS_INTERNAL_STATE_SHARED:
+ return "SHARED";
+ case RMS_INTERNAL_STATE_EXCLUSIVE:
+ return "EXCLUSIVE";
+ case RMS_INTERNAL_STATE_ERROR:
+ default:
+ return "NONE";
+ }
+}
+
+const char *rm_convert_requested_state_enum_to_string(rms_requests_resource_state_e state_enum)
+{
+ switch (state_enum) {
+ case RMS_STATE_PASSIVE:
+ return "PASSIVE";
+ case RMS_STATE_SHARABLE:
+ return "SHARABLE";
+ case RMS_STATE_EXCLUSIVE:
+ return "EXCLUSIVE";
+ case RMS_STATE_EXCLUSIVE_CONDITIONAL:
+ return "EXCLUSIVE_CONDITIONAL";
+ case RMS_STATE_EXCLUSIVE_AUTO:
+ return "EXCLUSIVE_AUTO";
+ case RMS_STATE_EXCLUSIVE_PREFERENCE:
+ return "EXCLUSIVE_PREFERENCE";
+ default:
+ return "NONE";
+ }
+}
+
+const char *rm_convert_category_enum_to_string(rms_rsc_category_e category_enum)
+{
+ switch (category_enum) {
+ case RMS_CATEGORY_NONE:
+ return "NONE";
+ case RMS_CATEGORY_AUDIO_DECODER:
+ return "Audio_Decoder";
+ case RMS_CATEGORY_AUDIO_SPDIF_ES_OUTPUT:
+ return "Not Defined Yet";
+ case RMS_CATEGORY_VIDEO_DECODER:
+ return "Video_Decoder";
+ case RMS_CATEGORY_DEMUX:
+ return "Demux_Main";
+ case RMS_CATEGORY_AUDIO_ENCODER:
+ return "Audio_Encoder";
+ case RMS_CATEGORY_VIDEO_ENCODER:
+ return "Video_Encoder";
+ case RMS_CATEGORY_SCALER:
+ return "Video_Scaler";
+ case RMS_CATEGORY_TUNER:
+ return "Tuner";
+ case RMS_CATEGORY_AUDIO_MAIN_OUT:
+ return "Audio_Main_Out";
+ case RMS_CATEGORY_AUDIO_REMOTE_OUT:
+ return "Audio_Remote_Out";
+ case RMS_CATEGORY_AUDIO_SCART_OUT:
+ return "Audio_Scart_Out";
+ case RMS_CATEGORY_MM_PCM_OUT:
+ return "MM_PCM_playback";
+ case RMS_CATEGORY_AUDIO_DECODER_SUB:
+ return "Audio_Decorder_Sub";
+ case RMS_CATEGORY_JPEG_DECODER:
+ return "JPEG_Decoder";
+ case RMS_CATEGORY_MJPEG_DECODER:
+ return "MJPEG_Decoder";
+ case RMS_CATEGORY_SCALER_SUB:
+ return "Video_Scaler_Sub";
+ case RMS_CATEGORY_EXT_VIDEO_SRC:
+ return "Ext_Video_Src";
+ case RMS_CATEGORY_EXT_AUDIO_SRC:
+ return "Ext_Audio_Src";
+ case RMS_CATEGORY_EXT_HDMI_SRC:
+ return "Ext_HDMI_Src";
+ case RMS_CATEGORY_VIDEO_DECODER_SUB:
+ return "Video_Decoder_Sub";
+ case RMS_CATEGORY_CAMERA:
+ return "Camera";
+ case RMS_CATEGORY_DEMUX_REC:
+ return "Demux_Rec";
+ case RMS_CATEGORY_TUNER_SUB:
+ return "Tuner_Sub";
+ case RMS_CATEGORY_VIDEO_DECODER_UHD:
+ return "Video_Decoder UHD";
+ case RMS_CATEGORY_INPUT_SRC_DTV:
+ return "Input_Src_DTV";
+ case RMS_CATEGORY_INPUT_SRC_ATV:
+ return "Input_Src_ATV";
+ case RMS_CATEGORY_INPUT_SRC_HDMI:
+ return "Input_Src_HDMI";
+ case RMS_CATEGORY_INPUT_SRC_COMP:
+ return "Input_Src_COMP";
+ case RMS_CATEGORY_INPUT_SRC_AV:
+ return "Input_Src_AV";
+ case RMS_CATEGORY_INPUT_SRC_SCART:
+ return "Input_Src_SCART";
+ case RMS_CATEGORY_MIC:
+ return "Mic";
+ case RMS_CATEGORY_SW_DECODER:
+ return "SWDecoder";
+ case RMS_CATEGORY_MMP_MEMORY_CLUSTER:
+ return "MMPlayer MemoryCluster";
+ case RMS_CATEGORY_JPEG_DECODER_8K:
+ return "JPEG_Decoder 8K";
+ case RMS_CATEGORY_SCALER_BG:
+ return "Video_Scaler_BG";
+ default:
+ return "";
+ }
+}
+
+const char *rm_convert_device_enum_to_string(rms_device_e device_enum)
+{
+ switch (device_enum) {
+ case RMS_DEVICE_NONE:
+ return "NONE";
+ case RMS_DEVICE_AUDIO_MAIN_OUT:
+ return "audio_main_out";
+ case RMS_DEVICE_AUDIO_REMOTE_OUT:
+ return "audio_remote_out";
+ case RMS_DEVICE_AUDIO_SCART_OUT:
+ return "audio_scart_out";
+ case RMS_DEVICE_MM_PCM_OUT:
+ return "mm_pcm_out";
+ case RMS_DEVICE_JPEG_DECODER:
+ return "jpeg_decoder";
+ case RMS_DEVICE_DEMUX0:
+ return "demux0";
+ case RMS_DEVICE_DEMUX1:
+ return "demux1";
+ case RMS_DEVICE_DEMUX2:
+ return "demux2";
+ case RMS_DEVICE_DEMUX3:
+ return "demux3";
+ case RMS_DEVICE_AUDIO_ENCODER:
+ return "audio_encoder";
+ case RMS_DEVICE_VIDEO_ENCODER:
+ return "video_encoder";
+ case RMS_DEVICE_SCALER:
+ return "scaler";
+ case RMS_DEVICE_EXT_VIDEO_SRC:
+ return "ext_video_src";
+ case RMS_DEVICE_EXT_AUDIO_SRC:
+ return "ext_autio_src";
+ case RMS_DEVICE_EXT_HDMI_SRC:
+ return "ext_hdmi_src";
+ case RMS_DEVICE_CAMERA:
+ return "camera";
+ case RMS_DEVICE_TUNER:
+ return "tuner";
+ case RMS_DEVICE_TUNER_SUB:
+ return "tuner_sub";
+ case RMS_DEVICE_SCALER_SUB:
+ return "scaler_sub";
+ case RMS_DEVICE_AUDIO_DECODER:
+ return "audio_decoder";
+ case RMS_DEVICE_AUDIO_DECODER_SUB:
+ return "audio_decoder_sub";
+ case RMS_DEVICE_VIDEO_DECODER_MAIN:
+ return "video_decoder_main";
+ case RMS_DEVICE_VIDEO_DECODER_SUB:
+ return "video_decoder_sub";
+ case RMS_DEVICE_VIDEO_DECODER_UDDEC:
+ return "video_decoder_uddec";
+ case RMS_DEVICE_VIDEO_DECODER_UDHEVC:
+ return "video_decoder_udhevc";
+ case RMS_DEVICE_AUDIO_SPDIF_ES_OUTPUT:
+ return "audio_spdif_es_output";
+ case RMS_DEVICE_MIC:
+ return "mic";
+ case RMS_DEVICE_EXT_COMP_SRC:
+ return "ext_comp_src";
+ case RMS_DEVICE_EXT_AV_SRC:
+ return "av_src";
+ case RMS_DEVICE_MJPEG_DECODER:
+ return "mjpeg_decoder";
+ case RMS_DEVICE_JPEG_DECODER_UHD:
+ return "jpeg_decoder_uhd";
+ case RMS_DEVICE_MJPEG_DECODER_UHD:
+ return "mjpeg_decoder_uhd";
+ case RMS_DEVICE_SW_DECODER:
+ return "sw_decoder";
+ default:
+ return "";
+ }
+}
+
+const char *rm_print_allocation_failure_reason(int ret_value)
+{
+ switch (ret_value) {
+ case RMS_OK:
+ return "OK";
+ case RMS_ERROR:
+ return "Cannot Allocate Resources";
+ case RMS_ERROR_TAKE_RESOURCE_FROM_OTHER_CONSUMER:
+ return "RESOURCE CONFLICT - Other Consumer Is Using";
+ case RMS_OK_UHD_RESOURCE_CONFLICT:
+ return "UHD RESOURCE CONFLICT - Other Consumer Is Using";
+ default:
+ return "";
+ }
+}
+void rms_create_popup(const char *title, const char *text)
+{
+ bundle *(*bundle_create_fp) (void);
+ int (*bundle_add_fp)(bundle*, const char*, const char*);
+ const char *(*bundle_get_val_fp) (bundle*, const char*);
+ int (*bundle_free_fp) (bundle*);
+ int (*syspopup_launch_fp) (char*, bundle*);
+ void *libsyspopup_handle = NULL;
+ void *libbundle_handle = NULL;
+ bundle *b = NULL;
+ char *error;
+
+ libsyspopup_handle = dlopen(LIBDIR"/libsyspopup_caller.so.0.1.0", RTLD_LAZY);
+ if (!libsyspopup_handle) {
+ SERVER_ERR("failed to load syspopup library");
+ goto end;
+ }
+
+ libbundle_handle = dlopen(LIBDIR"/libbundle.so.0", RTLD_LAZY);
+
+ if (!libbundle_handle) {
+ SERVER_ERR("failed to load bundle library");
+ goto end;
+ }
+
+ error = NULL;
+
+ bundle_create_fp = (bundle *(*)(void)) dlsym(libbundle_handle, "bundle_create");
+
+ if ((error = dlerror()) != NULL) {
+ SERVER_ERR("failed to find bundle_create");
+ goto end;
+
+ }
+
+ bundle_add_fp = (int (*)(bundle*, const char*, const char*)) dlsym(libbundle_handle, "bundle_add");
+
+ if ((error = dlerror()) != NULL) {
+ SERVER_ERR("failed to find bundle_add");
+ goto end;
+ }
+
+ bundle_get_val_fp = (const char *(*)(bundle*, const char*)) dlsym(libbundle_handle, "bundle_get_val");
+
+ if ((error = dlerror()) != NULL) {
+ SERVER_ERR("failed to find bundle_get_val");
+ goto end;
+ }
+
+ bundle_free_fp = (int (*)(bundle*)) dlsym(libbundle_handle, "bundle_free");
+
+ if ((error = dlerror()) != NULL) {
+ SERVER_ERR("failed to find bundle_free");
+ goto end;
+ }
+
+ syspopup_launch_fp = (int (*)(char*, bundle*)) dlsym(libsyspopup_handle, "syspopup_launch");
+
+ if ((error = dlerror()) != NULL) {
+ SERVER_ERR("failed to find alert-syspopup");
+ goto end;
+ }
+
+ b = bundle_create_fp();
+ if (!b) {
+ SERVER_ERR("failed to create bundle");
+ goto end;
+ }
+
+ bundle_add_fp(b, "type", "title_message_1button");
+ bundle_add_fp(b, "title", title);
+ bundle_add_fp(b, "text", text);
+
+ bundle_get_val_fp(b, "type");
+ bundle_get_val_fp(b, "title");
+ bundle_get_val_fp(b, "text");
+
+ syspopup_launch_fp((char*)"alert-syspopup", b);
+ bundle_free_fp(b);
+
+end:
+ if (libsyspopup_handle)
+ dlclose(libsyspopup_handle);
+
+ if (libbundle_handle)
+ dlclose(libbundle_handle);
+}
+
+int rms_get_cmd_name(pid_t pid, char *name_out, int size)
+{
+ char name[RMS_NAME_BUF_SIZE] = {0,};
+ FILE *f;
+ size_t sz;
+
+ snprintf(name, sizeof(name), "/proc/%d/cmdline", pid);
+ // Check if the process exists and is accessible
+ if (access(name, R_OK) != 0) {
+ SERVER_ERR("failed to access (%s) : %d", name, errno);
+ return RMS_ERROR;
+ }
+
+ f = fopen(name, "r");
+ if (!f) {
+ SERVER_ERR("failed to open cmdline(%s) : %d", name, errno);
+ return RMS_ERROR;
+ }
+
+ sz = fread(name, sizeof(char), sizeof(name)-1, f);
+ name[sz] = '\0';
+ fclose(f);
+
+ snprintf(name_out, size, "%s", name);
+
+ return RMS_OK;
+}
+
+void rms_print_log_console(char *buf)
+{
+ int fd, ret;
+ char output[RMS_CONSOLE_BUF_SIZE] ={0,};
+
+ struct timespec tnow;
+
+ fd = open("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+
+ if (fd < 0) {
+ SERVER_ERR("console device open fail");
+ return;
+ }
+
+ if (is_symlink_file("/dev/console")) {
+ SERVER_ERR("%s is symbolic link file", "/dev/console");
+ close(fd);
+ return;
+ }
+
+ ret = clock_gettime(CLOCK_MONOTONIC, &tnow);
+ snprintf(output, RMS_CONSOLE_BUF_SIZE, "[RMS][%ld.%6ld] %s", tnow.tv_sec, tnow.tv_nsec/1000, buf);
+ ret = write(fd, output, strlen(output));
+
+ if (ret < 0) {
+ SERVER_ERR("Fail to write on console directly");
+ }
+
+ close(fd);
+}
+
+int rm_get_product_type(void)
+{
+ if (product_type_init)
+ return product_type;
+
+ int type = 0; /* SYSTEM_INFO_PRODUCT_TYPE_TV */
+
+ if (system_info_get_custom_int("com.samsung/featureconf/product.product_type", &type) != SYSTEM_INFO_ERROR_NONE) {
+ SERVER_ERR("Failed to get com.samsung/featureconf/product.product_type");
+ }
+
+ product_type_init = true;
+ product_type = type;
+
+ return product_type;
+}
+
+int rm_is_valid_pid(int pid)
+{
+ if (kill((pid_t) pid, 0) == 0) {
+ SERVER_INFO("pid(%d) is alive", pid);
+ return 1;
+ }
+
+ SERVER_ERR("pid(%d) / errno(%d)", pid, errno);
+
+ return (errno == ESRCH) ? 0 : 1;
+}
+
+static void process_htable_destory_key(gpointer key)
+{
+ if (key)
+ free(key);
+}
+
+static void process_htable_create(void)
+{
+ if (process_htable) {
+ SERVER_ERR("hash table already created");
+ return;
+ }
+
+ process_htable = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)process_htable_destory_key, NULL);
+
+ SERVER_INFO("process hash table created");
+}
+
+static void process_htable_clear(void)
+{
+ SERVER_INFO("clear process hash table");
+
+ if (!process_htable)
+ return;
+
+ g_hash_table_remove_all(process_htable);
+}
+
+static void process_htable_insert(const char *name)
+{
+ const int PROCESS_DATA_LIMIT = 100; // The maxinum size is (RMS_NAME_BUF_SIZE * PROCESS_DATA_LIMIT)
+
+ if (!process_htable)
+ process_htable_create();
+
+ if (g_hash_table_contains(process_htable, name))
+ return;
+
+ if (g_hash_table_size(process_htable) >= PROCESS_DATA_LIMIT)
+ process_htable_clear();
+
+ char *key_name = (char*) strndup(name, strlen(name));
+
+ g_hash_table_insert(process_htable, key_name, (gpointer) 1);
+
+ SERVER_ERR("process info (%s) inserted to hash table (%d)", name, g_hash_table_size(process_htable));
+}
+
+
+bool process_htable_contains(const char *name)
+{
+ bool result = false;
+
+ if (!process_htable) {
+ SERVER_INFO("(%s) - no table", name);
+ return false;
+ }
+
+ if (g_hash_table_size(process_htable) == 0) {
+ SERVER_INFO("(%s) - empty", name);
+ return false;
+ }
+
+ result = g_hash_table_contains(process_htable, name);
+
+ SERVER_INFO("(%s) - result(%d)", name, result);
+
+ // resource manager is supposed to clear data once it's checked by application
+ process_htable_clear();
+
+ return result;
+}
+
+int rms_report_emergency(IN int cid, IN int pid, IN int requester)
+{
+ const char *vconf_request_cold_poweroff = "memory/boot/cold_poweroff_request_pkg";
+ int retry = 25; // 20ms * 25 times => 500ms
+ int ret = 0;
+
+ SERVER_ERR("consumer is not responding....CID[%d]/PID[%d]/Requester(%d) - set cold power off mode", cid, pid, requester);
+
+ if (vconf_set_str(vconf_request_cold_poweroff, "resource-manager") != 0) {
+ SERVER_ERR("Failed to set request cold power off");
+ } else {
+ SERVER_ERR("memory/boot/cold_poweroff_request_pkg set as resource-manager");
+ }
+
+ char process_name[RMS_NAME_BUF_SIZE] = {0,};
+
+ if (rms_get_cmd_name(pid, process_name, RMS_NAME_BUF_SIZE) == RMS_OK) {
+ process_htable_insert(process_name);
+ }
+
+ SERVER_ERR("kill PID(%d)", pid);
+
+ int signal = SIGKILL;
+
+ if (RMS_IS_DEBUG_IMAGE) {
+ signal = SIGABRT;
+ retry = 250; // 20ms * 250 times => 5 sec
+ }
+
+ ret = kill(pid, signal);
+
+ if (ret!=0) {
+ SERVER_ERR("Failed to kill(%d), errno(%d)", pid, errno);
+ }
+
+ // wait until process is really terminated for 500ms
+ while (retry > 0 && rm_is_valid_pid(pid)) {
+ retry--;
+ SERVER_ERR("pid(%d) still alive(%d)", pid, retry);
+ usleep(20*1000);
+ continue;
+ }
+
+ if (RMS_IS_DEBUG_IMAGE && retry <= 0) {
+ //process didn't get terminated for 5 seconds
+ SERVER_ERR("pid(%d) is not terminated.", pid);
+ return RMS_ERROR;
+ }
+
+ return RMS_OK;
+}
+
+void rms_display_timeout_error_popup(rms_alarm_reason_e reason, rms_consumer_tobe_returned_s info)
+{
+ const char *title = "Resource Allocation Failure";
+ const char *style_notification_msg = "<font_size=30 color=#00FF00>";
+ const char *style_process_name = "<font_size=25 color=#C90000>";
+ const char *indent = " ";
+ const char *notification_msg = "Please contact the owner(s) of process(es) below<br>";
+ const char *reason0 = " Resource allocation failed because there is no callback response from below process(es)<br> ";
+ const char *reason1 = " Resource allocation failed because below process(es) did not request deallocation<br> ";
+
+ char name[RMS_NAME_BUF_SIZE] = {0,};
+ GString *gstr;
+
+ if (!RMS_IS_DEBUG_IMAGE) {
+ SERVER_ERR("Not debug mode. Timeout alarm popup is not shown. reason(%d)", (int)reason);
+ return;
+ }
+
+ SERVER_ERR("timeout alarm");
+
+ gstr = g_string_new("");
+
+ if (!gstr) {
+ SERVER_ERR("Failed to create debug popup command");
+ return;
+ }
+
+ g_string_append_printf(gstr, "%s", style_notification_msg);
+
+ switch (reason) {
+ case RMS_ALARM_NO_CALLBACK_RESPONSE:
+ g_string_append_printf(gstr, "%s%s", indent, reason0);
+ break;
+ case RMS_ALARM_NO_DEALLOCATION:
+ g_string_append_printf(gstr, "%s%s", indent, reason1);
+ break;
+ default :
+ break;
+ }
+
+ g_string_append_printf(gstr, "%s%s%s", indent, notification_msg, style_process_name);
+
+ rms_get_cmd_name(info.process_id, name, sizeof(name));
+ g_string_append_printf(gstr, "%s%s : %d - %s%s", indent, "pid", (int)(info.process_id), name, " <br>");
+
+ for (int i = 0; i < info.n_conflicted; i++) {
+ g_string_append_printf(gstr, "%s [%d] %s%s", indent, i+1, rm_convert_category_enum_to_string(info.conflicted_resources[i].category_id), " <br>");
+ }
+ rms_create_popup(title, gstr->str);
+ SERVER_ERR("Command: %s", gstr->str);
+ g_string_free(gstr, true);
+}
+
+static bool rms_read_index(int *data)
+{
+ FILE *fp = NULL;
+ char str[10] = {0,};
+ size_t str_size;
+ const char *filename = "/proc/device-tree/rm_tbl_idx";
+
+ if (!data) {
+ SERVER_ERR("invalid input : null data");
+ return false;
+ }
+
+ fp = fopen(filename, "rb");
+
+ if (!fp) {
+ SERVER_ERR("failed to open (%s) - errno(%d)", filename, errno);
+ return false;
+ }
+
+ str_size = fread(str, sizeof(char), sizeof(str)-1, fp);
+
+ str[str_size] = '\0';
+
+ if (str_size == 0) {
+ fclose(fp);
+ return false;
+ }
+
+ *data = atoi(str);
+
+ fclose(fp);
+ fp = NULL;
+
+ return true;
+}
+
+void rms_display_resource_table_error_popup(void)
+{
+ const char *title = "FATAL ERROR!!!";
+ const char *reason = " Resource Manager can't find a resource table for this board<br> ";
+ const char *style_notification_msg = "<font_size=30 color=#FF0000>";
+ const char *indent = " ";
+ const char *notification_msg = "<br>";
+
+ GString *gstr = g_string_new("");
+ char *chipset_info;
+ int model_index = -1;
+
+ if (!gstr) {
+ SERVER_ERR("Failed to create debug popup command");
+ return;
+ }
+
+ g_string_append_printf(gstr, "%s%s", indent, reason);
+ g_string_append_printf(gstr, "%s%s%s", indent, notification_msg, style_notification_msg);
+ g_string_append_printf(gstr, "%sProduct type : %d%s", indent, rm_get_product_type(), " <br>");
+
+ if (system_info_get_custom_string("com.samsung/featureconf/product.chipset", &chipset_info)!= SYSTEM_INFO_ERROR_NONE) {
+ SERVER_ERR("Failed to get chipset from system-info");
+ goto end;
+ }
+
+ g_string_append_printf(gstr, "%sChipset : %s%s", indent, chipset_info, " <br>");
+
+ if (!rms_read_index(&model_index)) {
+ SERVER_ERR("failed to read model index");
+ }
+
+ g_string_append_printf(gstr, "%sIndex : %d%s", indent, model_index, " <br>");
+
+ rms_create_popup(title,gstr->str);
+
+ if (chipset_info) {
+ free(chipset_info);
+ }
+
+end:
+ g_string_free(gstr, true);
+ return;
+}
+
+void rms_print_model_info(void)
+{
+ static char *chipset_info = NULL;
+ static int rm_index = -1;
+
+ if (!chipset_info) {
+ if (system_info_get_custom_string("com.samsung/featureconf/product.chipset", &chipset_info)!= SYSTEM_INFO_ERROR_NONE)
+ SERVER_ERR("Failed to get chipset");
+ }
+
+ if (rm_index == -1) {
+ if (!rms_read_index(&rm_index))
+ SERVER_ERR("failed to read rm index");
+ }
+
+ SERVER_ERR("> chipset(%s)/product_type(%d)/rm_index(%d)", chipset_info? chipset_info:"", rm_get_product_type(), rm_index);
+
+ char buf[512];
+ snprintf(buf, 512, "resource table not loaded! > chipset(%s)/product_type(%d)/rm_index(%d)", chipset_info? chipset_info:"", rm_get_product_type(), rm_index);
+ rms_print_log_console(buf);
+}
+
+int is_symlink_file(const char *path)
+{
+ struct stat st;
+ if (lstat(path, &st) == -1) {
+ SERVER_ERR("stat error. file path(%s)", path);
+ return 0;
+ }
+
+ return (S_ISLNK(st.st_mode)) ? 1 : 0;
+}
+
+const char *rm_convert_error_type_to_string(rms_error_type_e error_type)
+{
+ switch (error_type) {
+ case RMS_ERR_TYPE_NONE:
+ return "None";
+ case RMS_ERR_TYPE_REQUEST_OF_INVISIBLE_PROCESS:
+ return "Request of invisible process";
+ case RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS:
+ return "Request of low priority process";
+ case RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE:
+ return "Not available resource";
+ case RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST:
+ return "Requested resource does not exist";
+ case RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER:
+ return "Take resource from other consumer";
+ default:
+ return "";
+ }
+}
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <mutex>\r
-#include <CLockController.h>\r
-\r
-std::mutex m;\r
-CLockController *CLockController::m_instance = nullptr;\r
-\r
-CLockController *CLockController::GetInstance(void)\r
-{\r
- if (m_instance == nullptr)\r
- {\r
- m_instance = new(std::nothrow) CLockController();\r
- }\r
-\r
- return m_instance;\r
-}\r
-\r
-void CLockController::Lock(ResourceType rsc_type)\r
-{\r
- std::unique_lock<std::mutex> lock(m);\r
- unsigned int count = 0;\r
- auto it = m_locks.find(rsc_type);\r
-\r
- count = (it == m_locks.end()) ? 1 : ++it->second;\r
-\r
- m_locks.insert(std::pair<ResourceType, unsigned int>(rsc_type, count));\r
-}\r
-\r
-void CLockController::Unlock(ResourceType rsc_type)\r
-{\r
- std::unique_lock<std::mutex> lock(m);\r
-\r
- auto it = m_locks.find(rsc_type);\r
- if (it == m_locks.end())\r
- return;\r
-\r
- if (it->second == 0)\r
- return;\r
-\r
- m_locks.at(rsc_type) = --it->second;\r
-\r
- if (m_locks.at(rsc_type) == 0)\r
- NotifyUnlock();\r
-}\r
-\r
-unsigned int CLockController::GetLockCount(void)\r
-{\r
- std::unique_lock<std::mutex> lock(m);\r
- unsigned int count = 0;\r
-\r
- for (auto &it : m_locks)\r
- count += it.second;\r
-\r
- return count;\r
-}\r
-\r
-void CLockController::NotifyUnlock(void)\r
-{\r
- CMessage *msg = new CMessage("NotifyUnlock");\r
- m_msg_q->push(msg);\r
-}\r
-\r
-bool CLockController::IsLocked(CMessage *msg)\r
-{\r
- if ((m_locks.at(ResourceType::VIDEO_SCALER) > 0) && msg->IsMsgFor(ResourceType::VIDEO_SCALER))\r
- return true;\r
-\r
- return false;\r
-}\r
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <mutex>
+#include <CLockController.h>
+
+std::mutex m;
+CLockController *CLockController::m_instance = nullptr;
+
+CLockController *CLockController::GetInstance(void)
+{
+ if (m_instance == nullptr)
+ {
+ m_instance = new(std::nothrow) CLockController();
+ }
+
+ return m_instance;
+}
+
+void CLockController::Lock(ResourceType rsc_type)
+{
+ std::unique_lock<std::mutex> lock(m);
+ unsigned int count = 0;
+ auto it = m_locks.find(rsc_type);
+
+ count = (it == m_locks.end()) ? 1 : ++it->second;
+
+ m_locks.insert(std::pair<ResourceType, unsigned int>(rsc_type, count));
+}
+
+void CLockController::Unlock(ResourceType rsc_type)
+{
+ std::unique_lock<std::mutex> lock(m);
+
+ auto it = m_locks.find(rsc_type);
+ if (it == m_locks.end())
+ return;
+
+ if (it->second == 0)
+ return;
+
+ m_locks.at(rsc_type) = --it->second;
+
+ if (m_locks.at(rsc_type) == 0)
+ NotifyUnlock();
+}
+
+unsigned int CLockController::GetLockCount(void)
+{
+ std::unique_lock<std::mutex> lock(m);
+ unsigned int count = 0;
+
+ for (auto &it : m_locks)
+ count += it.second;
+
+ return count;
+}
+
+void CLockController::NotifyUnlock(void)
+{
+ CMessage *msg = new CMessage("NotifyUnlock");
+ m_msg_q->push(msg);
+}
+
+bool CLockController::IsLocked(CMessage *msg)
+{
+ if ((m_locks.at(ResourceType::VIDEO_SCALER) > 0) && msg->IsMsgFor(ResourceType::VIDEO_SCALER))
+ return true;
+
+ return false;
+}
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <rms_type.h>\r
-#include <rms_debug.h>\r
-#include <CResource.h>\r
-#include <CConsumer.h>\r
-#include <CResourceDB.h>\r
-#include <CConsumerContainer.h>\r
-#include <CPriority.h>\r
-\r
-int CPriority::compare(int cur_consumer_id, int consumer_id)\r
-{\r
- CConsumerContainer *c_container = CConsumerContainer::getInstance();\r
- CConsumer *cur_consumer = c_container->findConsumer(cur_consumer_id);\r
- if (!cur_consumer)\r
- return HIGH_PRIORITY;\r
-\r
- CConsumer *consumer = c_container->findConsumer(consumer_id);\r
- if (!consumer)\r
- return LOW_PRIORITY;\r
-\r
- return (cur_consumer->ComparePriority(consumer) == RMS_ERR_TYPE_NONE) ? HIGH_PRIORITY : LOW_PRIORITY;\r
-}\r
-\r
-int CPriority::compareCurConsumers(int device_id, int consumer_id)\r
-{\r
- CConsumerContainer *c_container = CConsumerContainer::getInstance();\r
-\r
- CConsumer *consumer = c_container->findConsumer(consumer_id);\r
- if (!consumer)\r
- return LOW_PRIORITY;\r
-\r
- CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
- if (!resource)\r
- return HIGH_PRIORITY;\r
-\r
- std::set<int> rsc_consumers = resource->GetConsumers();\r
-\r
- for (auto const &it : rsc_consumers) {\r
- CConsumer *rsc_consumer = c_container->findConsumer(it);\r
-\r
- if (!rsc_consumer)\r
- continue;\r
-\r
- if (rsc_consumer->GetId() == consumer_id) {\r
- SERVER_WARN("consumer(%d) is already using (%d)", consumer_id, device_id);\r
- return SAME_PRIORITY;\r
- }\r
-\r
- if (rsc_consumer->ComparePriority(consumer) != RMS_ERR_TYPE_NONE) {\r
- SERVER_WARN("LOW PRORITY consumer (%d) device (%d)", consumer_id, device_id);\r
- return LOW_PRIORITY;\r
- }\r
- }\r
-\r
- return HIGH_PRIORITY;\r
-}\r
-\r
-int CPriority::getReclaimableConsumersShare(int device_id, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)\r
-{\r
- CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
- CConsumer *requester = CConsumerContainer::getInstance()->findConsumer(consumer_id);\r
-\r
- if (!resource || !requester)\r
- return RMS_ERROR;\r
-\r
- if (resource->IsSharableState())\r
- return RMS_ERROR;\r
-\r
- std::set<int> consumers = resource->GetConsumers();\r
-\r
- for (auto const &it : consumers) {\r
- int cid = it;\r
-\r
- if (isReclaimableConsumer(cid , consumer_id, err_type)) {\r
- reclaimables->insert(std::pair<int, int>(device_id, cid));\r
- break;\r
- }\r
- }\r
-\r
- if (reclaimables->empty()) {\r
- SERVER_ERR("high priority consumer is using device(%d)", device_id);\r
- return RMS_ERROR;\r
- }\r
-\r
- return RMS_OK;\r
-}\r
-\r
-bool CPriority::isReclaimableConsumer(int consumer_id, int requester_id, rms_error_type_e *err_type)\r
-{\r
- CConsumerContainer *c_container = CConsumerContainer::getInstance();\r
- CConsumer *consumer = c_container->findConsumer(consumer_id);\r
- CConsumer *requester = c_container->findConsumer(requester_id);\r
-\r
- if (!consumer || !requester)\r
- return false;\r
-\r
- if (consumer_id == requester_id)\r
- return false;\r
-\r
- rms_error_type_e error_type = consumer->ComparePriority(requester);\r
-\r
- if (error_type != RMS_ERR_TYPE_NONE) {\r
- if (err_type)\r
- *err_type = error_type;\r
-\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-int CPriority::getReclaimableConsumers(int device_id, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)\r
-{\r
- CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
- CConsumer *requester = CConsumerContainer::getInstance()->findConsumer(consumer_id);\r
-\r
- if (!resource || !requester)\r
- return RMS_ERROR;\r
-\r
- if (resource->IsFreeState())\r
- return RMS_ERROR;\r
-\r
- std::set<int> consumers = resource->GetConsumers();\r
-\r
- for (auto const &it : consumers) {\r
- int cid = it;\r
-\r
- if (!isReclaimableConsumer(cid , consumer_id, err_type))\r
- continue;\r
-\r
- reclaimables->insert(std::pair<int, int>(device_id, cid));\r
- }\r
-\r
- if (reclaimables->empty())\r
- {\r
- SERVER_ERR("high priority consumer is using device(%d)", device_id);\r
- return RMS_ERROR;\r
- }\r
-\r
- return RMS_OK;\r
-}\r
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <rms_type.h>
+#include <rms_debug.h>
+#include <CResource.h>
+#include <CConsumer.h>
+#include <CResourceDB.h>
+#include <CConsumerContainer.h>
+#include <CPriority.h>
+
+int CPriority::compare(int cur_consumer_id, int consumer_id)
+{
+ CConsumerContainer *c_container = CConsumerContainer::getInstance();
+ CConsumer *cur_consumer = c_container->findConsumer(cur_consumer_id);
+ if (!cur_consumer)
+ return HIGH_PRIORITY;
+
+ CConsumer *consumer = c_container->findConsumer(consumer_id);
+ if (!consumer)
+ return LOW_PRIORITY;
+
+ return (cur_consumer->ComparePriority(consumer) == RMS_ERR_TYPE_NONE) ? HIGH_PRIORITY : LOW_PRIORITY;
+}
+
+int CPriority::compareCurConsumers(int device_id, int consumer_id)
+{
+ CConsumerContainer *c_container = CConsumerContainer::getInstance();
+
+ CConsumer *consumer = c_container->findConsumer(consumer_id);
+ if (!consumer)
+ return LOW_PRIORITY;
+
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);
+ if (!resource)
+ return HIGH_PRIORITY;
+
+ std::set<int> rsc_consumers = resource->GetConsumers();
+
+ for (auto const &it : rsc_consumers) {
+ CConsumer *rsc_consumer = c_container->findConsumer(it);
+
+ if (!rsc_consumer)
+ continue;
+
+ if (rsc_consumer->GetId() == consumer_id) {
+ SERVER_WARN("consumer(%d) is already using (%d)", consumer_id, device_id);
+ return SAME_PRIORITY;
+ }
+
+ if (rsc_consumer->ComparePriority(consumer) != RMS_ERR_TYPE_NONE) {
+ SERVER_WARN("LOW PRORITY consumer (%d) device (%d)", consumer_id, device_id);
+ return LOW_PRIORITY;
+ }
+ }
+
+ return HIGH_PRIORITY;
+}
+
+int CPriority::getReclaimableConsumersShare(int device_id, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)
+{
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);
+ CConsumer *requester = CConsumerContainer::getInstance()->findConsumer(consumer_id);
+
+ if (!resource || !requester)
+ return RMS_ERROR;
+
+ if (resource->IsSharableState())
+ return RMS_ERROR;
+
+ std::set<int> consumers = resource->GetConsumers();
+
+ for (auto const &it : consumers) {
+ int cid = it;
+
+ if (isReclaimableConsumer(cid , consumer_id, err_type)) {
+ reclaimables->insert(std::pair<int, int>(device_id, cid));
+ break;
+ }
+ }
+
+ if (reclaimables->empty()) {
+ SERVER_ERR("high priority consumer is using device(%d)", device_id);
+ return RMS_ERROR;
+ }
+
+ return RMS_OK;
+}
+
+bool CPriority::isReclaimableConsumer(int consumer_id, int requester_id, rms_error_type_e *err_type)
+{
+ CConsumerContainer *c_container = CConsumerContainer::getInstance();
+ CConsumer *consumer = c_container->findConsumer(consumer_id);
+ CConsumer *requester = c_container->findConsumer(requester_id);
+
+ if (!consumer || !requester)
+ return false;
+
+ if (consumer_id == requester_id)
+ return false;
+
+ rms_error_type_e error_type = consumer->ComparePriority(requester);
+
+ if (error_type != RMS_ERR_TYPE_NONE) {
+ if (err_type)
+ *err_type = error_type;
+
+ return false;
+ }
+
+ return true;
+}
+
+int CPriority::getReclaimableConsumers(int device_id, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)
+{
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);
+ CConsumer *requester = CConsumerContainer::getInstance()->findConsumer(consumer_id);
+
+ if (!resource || !requester)
+ return RMS_ERROR;
+
+ if (resource->IsFreeState())
+ return RMS_ERROR;
+
+ std::set<int> consumers = resource->GetConsumers();
+
+ for (auto const &it : consumers) {
+ int cid = it;
+
+ if (!isReclaimableConsumer(cid , consumer_id, err_type))
+ continue;
+
+ reclaimables->insert(std::pair<int, int>(device_id, cid));
+ }
+
+ if (reclaimables->empty())
+ {
+ SERVER_ERR("high priority consumer is using device(%d)", device_id);
+ return RMS_ERROR;
+ }
+
+ return RMS_OK;
+}
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <iostream>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-#include <algorithm>\r
-#include <time.h>\r
-\r
-#include <trace.h>\r
-#include <vconf.h>\r
-\r
-#include <CDebugUtils.h>\r
-#include <rms_debug.h>\r
-#include <rms_type.h>\r
-#include <ri-common-type.h>\r
-#include <ri-module-api.h>\r
-\r
-#include <CResourceObserver.h>\r
-#include <CResource.h>\r
-\r
-#define RMS_SUBSCALER_FLAG "memory/rsc_mgr/subscaler_status"\r
-\r
-using namespace std;\r
-void CResource::m_SetSubScalerFlag(int next_state)\r
-{\r
- if (next_state == RMS_INTERNAL_STATE_ERROR)\r
- return;\r
- int value = 0;\r
- switch (next_state) {\r
- case RMS_INTERNAL_STATE_FREE:\r
- value = 0;\r
- break;\r
- case RMS_INTERNAL_STATE_SHARABLE:\r
- case RMS_INTERNAL_STATE_SHARED:\r
- case RMS_INTERNAL_STATE_EXCLUSIVE:\r
- value = 1;\r
- break;\r
- }\r
- if (vconf_set_int(RMS_SUBSCALER_FLAG,value) != 0) {\r
- SERVER_ERR("Failed to Set vconf key - %s",RMS_SUBSCALER_FLAG);\r
- return;\r
- }\r
- SERVER_INFO("Subscaler flag set to - %d", value);\r
-}\r
-\r
-CResource::CResource(const int device_id, const rms_rsc_category_e category_type, const char *name, const char *path,\r
- std::set<unsigned int> mem_cluster, int is_main_device, const char *audio_codec, int sharable_count)\r
-:m_id(device_id), m_device_name(name), m_device_path(path), m_is_main_device(is_main_device), m_sharable_count(sharable_count)\r
-{\r
- m_mem_clusters = mem_cluster;\r
-\r
- if (audio_codec)\r
- m_audio_codec.assign(audio_codec);\r
-\r
- m_category_type = category_type;\r
- m_cur_category = category_type;\r
- m_is_scaler = IsScaler(category_type);\r
-}\r
-\r
-CResource::~CResource()\r
-{\r
-}\r
-\r
-bool CResource::IsScaler(rms_rsc_category_e category)\r
-{\r
- bool result = false;\r
-\r
- switch (category) {\r
- case RMS_CATEGORY_SCALER:\r
- case RMS_CATEGORY_SCALER_BG:\r
- case RMS_CATEGORY_SCALER_SUB:\r
- case RMS_CATEGORY_SCALER_SUB2:\r
- case RMS_CATEGORY_SCALER_SUB3:\r
- result = true;\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- return result;\r
-}\r
-\r
-void CResource::UpdateProperties(std::set<unsigned int> mem_clusters, int bw, int category, int category_class, int vrsc_id)\r
-{\r
- m_mem_clusters = mem_clusters;\r
- m_occupied_bw = bw;\r
- m_cur_category = category;\r
- m_category_class = category_class;\r
- m_vrsc_id = vrsc_id;\r
-}\r
-\r
-int CResource::ReserveExclusive(int consumer_id)\r
-{\r
- if (m_is_reserved && (consumer_id != m_reserved_consumer_id)) {\r
- SERVER_ERR("rsc(%d) already reserved by(%d)", m_id, m_reserved_consumer_id);\r
- return RMS_ERROR;\r
- }\r
-\r
- m_reserved_consumer_id = consumer_id;\r
- m_is_reserved = true;\r
-\r
- return RMS_OK;\r
-}\r
-\r
-int CResource::ReserveShared(int consumer_id)\r
-{\r
- if (m_is_reserved) {\r
- SERVER_ERR("rsc(%d) already reserved by (%d) with exclusive mode", m_id, m_reserved_consumer_id);\r
- return RMS_ERROR;\r
- }\r
-\r
- m_reserved_count++;\r
-\r
- if ( (m_shared_count + m_reserved_count) > m_sharable_count) {\r
- SERVER_ERR("can't reserve(%d) shared(%d), reserved(%d), max(%d)", m_id, m_shared_count, m_reserved_count, m_sharable_count);\r
- m_reserved_count--;\r
- return RMS_ERROR;\r
- }\r
-\r
- SERVER_INFO("reserve share(%d) shared(%d), reserved(%d), max(%d)", m_id, m_shared_count, m_reserved_count, m_sharable_count);\r
-\r
- return RMS_OK;\r
-}\r
-\r
-int CResource::Reserve(int consumer_id, rms_requests_resource_state_e state)\r
-{\r
- return (state == RMS_STATE_SHARABLE) ? ReserveShared(consumer_id):ReserveExclusive(consumer_id);\r
-}\r
-\r
-void CResource::CancelReservation(rms_requests_resource_state_e state)\r
-{\r
- if (state == RMS_STATE_SHARABLE)\r
- m_reserved_count = (--m_reserved_count < 0) ? 0 : m_reserved_count;\r
- else\r
- m_is_reserved = false;\r
-}\r
-\r
-void CResource::AddConsumer(IN const int consumer_id, IN rms_requests_resource_state_e state)\r
-{\r
- if (IsRegisteredConsumer(consumer_id)) {\r
- IncreaseRefCount(consumer_id);\r
- m_shared_count++;\r
- SERVER_INFO("[rsc(%d)]increase ref count of (%d), shared(%d) by consumers(%zu)", m_id, consumer_id, m_shared_count, m_shared_consumers.size());\r
- return;\r
- }\r
-\r
- m_consumers.insert(std::pair<int, int>(consumer_id, 1));\r
- m_consumer_ids.insert(consumer_id);\r
-\r
- if (state == RMS_STATE_SHARABLE) {\r
- m_shared_consumers.insert(consumer_id);\r
- m_shared_count++;\r
- SERVER_INFO("[rsc(%d)] consumer(%d) shares resource, shared(%d) by consumers(%zu)", m_id, consumer_id, m_shared_count, m_shared_consumers.size());\r
- }\r
-\r
- return;\r
-}\r
-\r
-void CResource::ResetConsumer(std::set<int> new_consumers)\r
-{\r
- m_consumers.clear();\r
- m_consumer_ids.clear();\r
- m_shared_consumers.clear();\r
- m_shared_count = 0;\r
-\r
- for (auto &it : new_consumers) {\r
- AddConsumer(it, RMS_STATE_EXCLUSIVE);\r
- }\r
-}\r
-\r
-bool CResource::IsRegisteredConsumer(int consumer_id)\r
-{\r
- std::map<int, int>::iterator it = m_consumers.find(consumer_id);\r
-\r
- return (it != m_consumers.end());\r
-}\r
-\r
-int CResource::IncreaseRefCount(int consumer_id)\r
-{\r
- int ref_count = 0;\r
- std::map<int, int>::iterator it = m_consumers.find(consumer_id);\r
-\r
- if (it == m_consumers.end())\r
- return 0;\r
-\r
- ref_count = it->second;\r
- m_consumers[consumer_id] = ++ref_count;\r
-\r
- return ref_count;\r
-}\r
-\r
-int CResource::DecreaseRefCount(int consumer_id)\r
-{\r
- int ref_count = 0;\r
- std::map<int, int>::iterator it = m_consumers.find(consumer_id);\r
-\r
- if (it == m_consumers.end())\r
- return 0;\r
-\r
- ref_count = it->second;\r
- --ref_count;\r
- ref_count = (ref_count < 0) ? 0 : ref_count;\r
- m_consumers[consumer_id] = ref_count;\r
-\r
- return ref_count;\r
-}\r
-\r
-int CResource::RemoveConsumer(IN int consumer_id, IN bool force)\r
-{\r
- if (!IsRegisteredConsumer(consumer_id)) {\r
- SERVER_ERR("[rsc(%d)] consumer(%d) is not found in list", m_id, consumer_id);\r
- return 0;\r
- }\r
-\r
- int ref_count = DecreaseRefCount(consumer_id);\r
-\r
- if (m_state == RMS_INTERNAL_STATE_SHARABLE || m_state == RMS_INTERNAL_STATE_SHARED) {\r
- m_shared_count = (--m_shared_count < 0) ? 0 : m_shared_count;\r
-\r
- if (force)\r
- m_shared_count = ((m_shared_count -= ref_count) < 0) ? 0 : m_shared_count;\r
- }\r
-\r
- if (ref_count > 0 && !force) {\r
- SERVER_INFO("consumer(%d) is still sharing resource(%d), ref(%d)", consumer_id, m_id, ref_count);\r
- return ref_count;\r
- }\r
-\r
- m_consumer_ids.erase(consumer_id);\r
- m_consumers.erase(consumer_id);\r
- ChangeStateByRelease(consumer_id);\r
-\r
- return 0;\r
-}\r
-\r
-void CResource::ChangeState(rms_resource_internal_state_e next_state)\r
-{\r
- if (m_state == next_state)\r
- return;\r
-\r
- SERVER_INFO("state changed (%s : %s) - (%s -> %s)",\r
- rm_convert_category_enum_to_string(m_category_type),\r
- m_device_name,\r
- rm_convert_state_enum_to_string(m_state),\r
- rm_convert_state_enum_to_string(next_state));\r
-\r
- m_state = next_state;\r
-\r
- if (m_category_type == RMS_CATEGORY_SCALER_SUB)\r
- m_SetSubScalerFlag(next_state);\r
-}\r
-\r
-bool CResource::ChangeStateByAllocation(IN rms_requests_resource_state_e requested_state, const int consumer_id, int mv_zone_id)\r
-{\r
- if (requested_state == RMS_STATE_EXCLUSIVE_CONDITIONAL || requested_state == RMS_STATE_EXCLUSIVE_AUTO || requested_state == RMS_STATE_EXCLUSIVE_PREFERENCE)\r
- requested_state = RMS_STATE_EXCLUSIVE;\r
-\r
- rms_resource_internal_state_e allocation_resource_state_matrix[4][3] =\r
- {{RMS_INTERNAL_STATE_ERROR, RMS_INTERNAL_STATE_SHARABLE, RMS_INTERNAL_STATE_EXCLUSIVE},\r
- {RMS_INTERNAL_STATE_SHARABLE, RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_ERROR},\r
- {RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_ERROR},\r
- {RMS_INTERNAL_STATE_EXCLUSIVE, RMS_INTERNAL_STATE_ERROR, RMS_INTERNAL_STATE_ERROR}};\r
-\r
- bool need_notify_by_alloc_matrix[4][3] = {{false, true, true},\r
- {false, true, false},\r
- {false, true, false},\r
- {false, false, true}};\r
-\r
- rms_resource_internal_state_e next_state = allocation_resource_state_matrix[m_state][requested_state];\r
- SERVER_INFO("m_state %d requested_state %d next_state %d", m_state, requested_state, next_state);\r
-\r
- bool need_notify = need_notify_by_alloc_matrix[m_state][requested_state];\r
-\r
- m_is_reserved = false;\r
- m_reserved_consumer_id = 0;\r
-\r
- if (next_state == RMS_INTERNAL_STATE_ERROR) {\r
- SERVER_ERR("state change error! device(%d) (%s) to (%s)", m_id, rm_convert_state_enum_to_string(m_state), rm_convert_state_enum_to_string(next_state));\r
- return false;\r
- }\r
-\r
- m_state = next_state;\r
-\r
- if (m_category_type == RMS_CATEGORY_SCALER_SUB)\r
- m_SetSubScalerFlag(next_state);\r
-\r
- if (mv_zone_id > 0) {\r
- m_mv_zone_id = mv_zone_id;\r
- SERVER_INFO("(%d) > zone_id(%d)", m_id, m_mv_zone_id);\r
- }\r
-\r
- if (need_notify)\r
- NotifyObservers(UPDATED_BY_ALLOC, consumer_id);\r
-\r
- return true;\r
-}\r
-\r
-bool CResource::ChangeStateByRelease(int consumer_id)\r
-{\r
- rms_resource_internal_state_e current_state = m_state;\r
- rms_resource_internal_state_e next_state = RMS_INTERNAL_STATE_ERROR;\r
-\r
- bool need_notify = false;\r
-\r
- SERVER_INFO("current_state %d m_shared_count %d", current_state, m_shared_count);\r
-\r
- switch (current_state) {\r
- case RMS_INTERNAL_STATE_SHARED:\r
- m_shared_consumers.erase(consumer_id);\r
- need_notify = true;\r
-\r
- if (m_shared_count > 1) {\r
- next_state = RMS_INTERNAL_STATE_SHARED;\r
- } else if (m_shared_count == 1) {\r
- next_state = RMS_INTERNAL_STATE_SHARABLE;\r
- } else {\r
- next_state = RMS_INTERNAL_STATE_FREE;\r
- }\r
- break;\r
- case RMS_INTERNAL_STATE_EXCLUSIVE:\r
- case RMS_INTERNAL_STATE_SHARABLE:\r
- next_state = RMS_INTERNAL_STATE_FREE;\r
- need_notify = true;\r
- break;\r
- case RMS_INTERNAL_STATE_FREE:\r
- default:\r
- SERVER_ERR("unexpected resource state (%d)", current_state);\r
- next_state = RMS_INTERNAL_STATE_FREE;\r
- break;\r
- }\r
-\r
- m_state = next_state;\r
- SERVER_INFO("m_state %d need notify %d", m_state, need_notify);\r
-\r
- if (m_category_type == RMS_CATEGORY_SCALER_SUB)\r
- m_SetSubScalerFlag(next_state);\r
-\r
- if (need_notify) {\r
- m_mv_zone_id = -1;\r
- NotifyObservers(UPDATED_BY_RELEASE, consumer_id);\r
- }\r
-\r
- return true;\r
-}\r
-\r
-bool CResource::IsAllocatableState(IN rms_requests_resource_state_e requested_state)\r
-{\r
- bool can_allocation_matrix[4][6] =\r
- /*requested_state*/ /* PASSIVE */ /*SHARABLE*/ /*EXCLUSIVE*/ /* EXCLUSIVE CON */ /* EXCLUSIVE AUTO */ /* EXCLUSIVE PREFERENCE */\r
- /* m_state */ /* FREE */{ {false, true, true, true, true, true },\r
- /* SHARABLE */ { true, true, false, false, false, false },\r
- /* SHARED */ { true, true, false, false, false, false },\r
- /* EXCLUSIVE */ { true, false, false, false, false, false } };\r
-\r
- SERVER_INFO("Status - DevID[%d:%s] / CatID[%d] / CurState[%s] / ReqState[%s]",\r
- m_id, m_device_name, m_category_type, rm_convert_state_enum_to_string(m_state), rm_convert_requested_state_enum_to_string(requested_state));\r
-\r
- /* check requested_state is valid */\r
- if ((requested_state < RMS_STATE_PASSIVE) || (requested_state > RMS_STATE_EXCLUSIVE_PREFERENCE)) {\r
- SERVER_ERR("rquested state is invalid");\r
- return false;\r
- }\r
-\r
- return can_allocation_matrix[m_state][requested_state];\r
-}\r
-\r
-void CResource::SetDefaultBW(unsigned int bw)\r
-{\r
- m_default_bw = bw;\r
- m_occupied_bw = bw;\r
-}\r
-void CResource::SetAllocatedTime(void)\r
-{\r
- struct timespec t;\r
- clock_gettime(CLOCK_MONOTONIC, &t);\r
- unsigned long sec = t.tv_sec * 1000;\r
- unsigned long nsec = t.tv_nsec / 1000000;\r
- m_allocated_time = sec + nsec;\r
-}\r
-\r
-void CResource::RegisterObserver(CResourceObserver *observer)\r
-{\r
- if (!observer) {\r
- SERVER_ERR("observer NULL");\r
- return;\r
- }\r
-\r
- m_observers.push_back(observer);\r
-}\r
-\r
-void CResource::UnregisterObserver(CResourceObserver *observer)\r
-{\r
- auto it = std::find(m_observers.begin(), m_observers.end(), observer);\r
-\r
- if (it == m_observers.end()) {\r
- SERVER_ERR("not registered observer");\r
- return;\r
- }\r
-\r
- m_observers.erase(it);\r
-\r
- SERVER_INFO("observer removed");\r
-}\r
-\r
-void CResource::NotifyObservers(resource_update_type_e type, const int consumer_id)\r
-{\r
- for (CResourceObserver *observer : m_observers) {\r
- observer->Update(type, m_id, consumer_id);\r
- }\r
-}\r
-\r
-bool CResource::Allocate(const int consumer_id, rms_requests_resource_state_e state, int mv_zone_id)\r
-{\r
- if (!ChangeStateByAllocation(state, consumer_id, mv_zone_id))\r
- return false;\r
-\r
- AddConsumer(consumer_id, state);\r
- return true;\r
-}\r
-\r
-void CResource::SetZoneId(int zone_id)\r
-{\r
- SERVER_INFO("(%d) > zone_id(%d)", m_id, zone_id);\r
- m_mv_zone_id = zone_id;\r
-}\r
-\r
-void CResource::UpdateAudioCodec(std::string codec_name)\r
-{\r
- m_audio_codec = codec_name;\r
-}\r
-\r
-bool CResource::IsAudioDevice(void)\r
-{\r
- if (m_category_type == RMS_CATEGORY_AUDIO_DECODER)\r
- return true;\r
- if (m_category_type == RMS_CATEGORY_AUDIO_DECODER_SUB)\r
- return true;\r
- if (m_category_type == RMS_CATEGORY_AUDIO_DECODER_PRIMARY)\r
- return true;\r
- if ((m_category_type > RMS_CATEGORY_AUDIO_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_AUDIO_DECODER_OPTION_MAX))\r
- return true;\r
-\r
- return false;\r
-}\r
-\r
-bool CResource::IsVideoDecoder(void)\r
-{\r
- if (m_category_type == RMS_CATEGORY_VIDEO_DECODER)\r
- return true;\r
- if (m_category_type == RMS_CATEGORY_VIDEO_DECODER_SUB)\r
- return true;\r
- if ((m_category_type > RMS_CATEGORY_VIDEO_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_VIDEO_DECODER_OPTION_MAX))\r
- return true;\r
- if (m_category_type == RMS_CATEGORY_MJPEG_DECODER)\r
- return true;\r
- if ((m_category_type > RMS_CATEGORY_MJPEG_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_MJPEG_DECODER_OPTION_MAX))\r
- return true;\r
-\r
- return false;\r
-}\r
-\r
-int CResource::GetFirstConsumer(void)\r
-{\r
- if (m_consumer_ids.empty())\r
- return -1;\r
-\r
- auto it = m_consumer_ids.begin();\r
- return *it;\r
-}\r
-\r
-int CResource::GetVirtualDeviceId(void)\r
-{\r
- return (m_virtual_id < RI_VIRTUAL_ID_SCALER) ? m_id : m_virtual_id;\r
-}\r
-\r
-bool CResource::IsJpegDecoder(void)\r
-{\r
- if (m_category_type == RMS_CATEGORY_JPEG_DECODER)\r
- return true;\r
- if ((m_category_type > RMS_CATEGORY_JPEG_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_JPEG_DECODER_OPTION_MAX))\r
- return true;\r
-\r
- return false;\r
-}\r
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <iostream>
+#include <string.h>
+#include <stdlib.h>
+#include <algorithm>
+#include <time.h>
+
+#include <trace.h>
+#include <vconf.h>
+
+#include <CDebugUtils.h>
+#include <rms_debug.h>
+#include <rms_type.h>
+#include <ri-common-type.h>
+#include <ri-module-api.h>
+
+#include <CResourceObserver.h>
+#include <CResource.h>
+
+#define RMS_SUBSCALER_FLAG "memory/rsc_mgr/subscaler_status"
+
+using namespace std;
+void CResource::m_SetSubScalerFlag(int next_state)
+{
+ if (next_state == RMS_INTERNAL_STATE_ERROR)
+ return;
+ int value = 0;
+ switch (next_state) {
+ case RMS_INTERNAL_STATE_FREE:
+ value = 0;
+ break;
+ case RMS_INTERNAL_STATE_SHARABLE:
+ case RMS_INTERNAL_STATE_SHARED:
+ case RMS_INTERNAL_STATE_EXCLUSIVE:
+ value = 1;
+ break;
+ }
+ if (vconf_set_int(RMS_SUBSCALER_FLAG,value) != 0) {
+ SERVER_ERR("Failed to Set vconf key - %s",RMS_SUBSCALER_FLAG);
+ return;
+ }
+ SERVER_INFO("Subscaler flag set to - %d", value);
+}
+
+CResource::CResource(const int device_id, const rms_rsc_category_e category_type, const char *name, const char *path,
+ std::set<unsigned int> mem_cluster, int is_main_device, const char *audio_codec, int sharable_count)
+:m_id(device_id), m_device_name(name), m_device_path(path), m_is_main_device(is_main_device), m_sharable_count(sharable_count)
+{
+ m_mem_clusters = mem_cluster;
+
+ if (audio_codec)
+ m_audio_codec.assign(audio_codec);
+
+ m_category_type = category_type;
+ m_cur_category = category_type;
+ m_is_scaler = IsScaler(category_type);
+}
+
+CResource::~CResource()
+{
+}
+
+bool CResource::IsScaler(rms_rsc_category_e category)
+{
+ bool result = false;
+
+ switch (category) {
+ case RMS_CATEGORY_SCALER:
+ case RMS_CATEGORY_SCALER_BG:
+ case RMS_CATEGORY_SCALER_SUB:
+ case RMS_CATEGORY_SCALER_SUB2:
+ case RMS_CATEGORY_SCALER_SUB3:
+ result = true;
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+void CResource::UpdateProperties(std::set<unsigned int> mem_clusters, int bw, int category, int category_class, int vrsc_id)
+{
+ m_mem_clusters = mem_clusters;
+ m_occupied_bw = bw;
+ m_cur_category = category;
+ m_category_class = category_class;
+ m_vrsc_id = vrsc_id;
+}
+
+int CResource::ReserveExclusive(int consumer_id)
+{
+ if (m_is_reserved && (consumer_id != m_reserved_consumer_id)) {
+ SERVER_ERR("rsc(%d) already reserved by(%d)", m_id, m_reserved_consumer_id);
+ return RMS_ERROR;
+ }
+
+ m_reserved_consumer_id = consumer_id;
+ m_is_reserved = true;
+
+ return RMS_OK;
+}
+
+int CResource::ReserveShared(int consumer_id)
+{
+ if (m_is_reserved) {
+ SERVER_ERR("rsc(%d) already reserved by (%d) with exclusive mode", m_id, m_reserved_consumer_id);
+ return RMS_ERROR;
+ }
+
+ m_reserved_count++;
+
+ if ( (m_shared_count + m_reserved_count) > m_sharable_count) {
+ SERVER_ERR("can't reserve(%d) shared(%d), reserved(%d), max(%d)", m_id, m_shared_count, m_reserved_count, m_sharable_count);
+ m_reserved_count--;
+ return RMS_ERROR;
+ }
+
+ SERVER_INFO("reserve share(%d) shared(%d), reserved(%d), max(%d)", m_id, m_shared_count, m_reserved_count, m_sharable_count);
+
+ return RMS_OK;
+}
+
+int CResource::Reserve(int consumer_id, rms_requests_resource_state_e state)
+{
+ return (state == RMS_STATE_SHARABLE) ? ReserveShared(consumer_id):ReserveExclusive(consumer_id);
+}
+
+void CResource::CancelReservation(rms_requests_resource_state_e state)
+{
+ if (state == RMS_STATE_SHARABLE)
+ m_reserved_count = (--m_reserved_count < 0) ? 0 : m_reserved_count;
+ else
+ m_is_reserved = false;
+}
+
+void CResource::AddConsumer(IN const int consumer_id, IN rms_requests_resource_state_e state)
+{
+ if (IsRegisteredConsumer(consumer_id)) {
+ IncreaseRefCount(consumer_id);
+ m_shared_count++;
+ SERVER_INFO("[rsc(%d)]increase ref count of (%d), shared(%d) by consumers(%zu)", m_id, consumer_id, m_shared_count, m_shared_consumers.size());
+ return;
+ }
+
+ m_consumers.insert(std::pair<int, int>(consumer_id, 1));
+ m_consumer_ids.insert(consumer_id);
+
+ if (state == RMS_STATE_SHARABLE) {
+ m_shared_consumers.insert(consumer_id);
+ m_shared_count++;
+ SERVER_INFO("[rsc(%d)] consumer(%d) shares resource, shared(%d) by consumers(%zu)", m_id, consumer_id, m_shared_count, m_shared_consumers.size());
+ }
+
+ return;
+}
+
+void CResource::ResetConsumer(std::set<int> new_consumers)
+{
+ m_consumers.clear();
+ m_consumer_ids.clear();
+ m_shared_consumers.clear();
+ m_shared_count = 0;
+
+ for (auto &it : new_consumers) {
+ AddConsumer(it, RMS_STATE_EXCLUSIVE);
+ }
+}
+
+bool CResource::IsRegisteredConsumer(int consumer_id)
+{
+ std::map<int, int>::iterator it = m_consumers.find(consumer_id);
+
+ return (it != m_consumers.end());
+}
+
+int CResource::IncreaseRefCount(int consumer_id)
+{
+ int ref_count = 0;
+ std::map<int, int>::iterator it = m_consumers.find(consumer_id);
+
+ if (it == m_consumers.end())
+ return 0;
+
+ ref_count = it->second;
+ m_consumers[consumer_id] = ++ref_count;
+
+ return ref_count;
+}
+
+int CResource::DecreaseRefCount(int consumer_id)
+{
+ int ref_count = 0;
+ std::map<int, int>::iterator it = m_consumers.find(consumer_id);
+
+ if (it == m_consumers.end())
+ return 0;
+
+ ref_count = it->second;
+ --ref_count;
+ ref_count = (ref_count < 0) ? 0 : ref_count;
+ m_consumers[consumer_id] = ref_count;
+
+ return ref_count;
+}
+
+int CResource::RemoveConsumer(IN int consumer_id, IN bool force)
+{
+ if (!IsRegisteredConsumer(consumer_id)) {
+ SERVER_ERR("[rsc(%d)] consumer(%d) is not found in list", m_id, consumer_id);
+ return 0;
+ }
+
+ int ref_count = DecreaseRefCount(consumer_id);
+
+ if (m_state == RMS_INTERNAL_STATE_SHARABLE || m_state == RMS_INTERNAL_STATE_SHARED) {
+ m_shared_count = (--m_shared_count < 0) ? 0 : m_shared_count;
+
+ if (force)
+ m_shared_count = ((m_shared_count -= ref_count) < 0) ? 0 : m_shared_count;
+ }
+
+ if (ref_count > 0 && !force) {
+ SERVER_INFO("consumer(%d) is still sharing resource(%d), ref(%d)", consumer_id, m_id, ref_count);
+ return ref_count;
+ }
+
+ m_consumer_ids.erase(consumer_id);
+ m_consumers.erase(consumer_id);
+ ChangeStateByRelease(consumer_id);
+
+ return 0;
+}
+
+void CResource::ChangeState(rms_resource_internal_state_e next_state)
+{
+ if (m_state == next_state)
+ return;
+
+ SERVER_INFO("state changed (%s : %s) - (%s -> %s)",
+ rm_convert_category_enum_to_string(m_category_type),
+ m_device_name,
+ rm_convert_state_enum_to_string(m_state),
+ rm_convert_state_enum_to_string(next_state));
+
+ m_state = next_state;
+
+ if (m_category_type == RMS_CATEGORY_SCALER_SUB)
+ m_SetSubScalerFlag(next_state);
+}
+
+bool CResource::ChangeStateByAllocation(IN rms_requests_resource_state_e requested_state, const int consumer_id, int mv_zone_id)
+{
+ if (requested_state == RMS_STATE_EXCLUSIVE_CONDITIONAL || requested_state == RMS_STATE_EXCLUSIVE_AUTO || requested_state == RMS_STATE_EXCLUSIVE_PREFERENCE)
+ requested_state = RMS_STATE_EXCLUSIVE;
+
+ rms_resource_internal_state_e allocation_resource_state_matrix[4][3] =
+ {{RMS_INTERNAL_STATE_ERROR, RMS_INTERNAL_STATE_SHARABLE, RMS_INTERNAL_STATE_EXCLUSIVE},
+ {RMS_INTERNAL_STATE_SHARABLE, RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_ERROR},
+ {RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_ERROR},
+ {RMS_INTERNAL_STATE_EXCLUSIVE, RMS_INTERNAL_STATE_ERROR, RMS_INTERNAL_STATE_ERROR}};
+
+ bool need_notify_by_alloc_matrix[4][3] = {{false, true, true},
+ {false, true, false},
+ {false, true, false},
+ {false, false, true}};
+
+ rms_resource_internal_state_e next_state = allocation_resource_state_matrix[m_state][requested_state];
+ SERVER_INFO("m_state %d requested_state %d next_state %d", m_state, requested_state, next_state);
+
+ bool need_notify = need_notify_by_alloc_matrix[m_state][requested_state];
+
+ m_is_reserved = false;
+ m_reserved_consumer_id = 0;
+
+ if (next_state == RMS_INTERNAL_STATE_ERROR) {
+ SERVER_ERR("state change error! device(%d) (%s) to (%s)", m_id, rm_convert_state_enum_to_string(m_state), rm_convert_state_enum_to_string(next_state));
+ return false;
+ }
+
+ m_state = next_state;
+
+ if (m_category_type == RMS_CATEGORY_SCALER_SUB)
+ m_SetSubScalerFlag(next_state);
+
+ if (mv_zone_id > 0) {
+ m_mv_zone_id = mv_zone_id;
+ SERVER_INFO("(%d) > zone_id(%d)", m_id, m_mv_zone_id);
+ }
+
+ if (need_notify)
+ NotifyObservers(UPDATED_BY_ALLOC, consumer_id);
+
+ return true;
+}
+
+bool CResource::ChangeStateByRelease(int consumer_id)
+{
+ rms_resource_internal_state_e current_state = m_state;
+ rms_resource_internal_state_e next_state = RMS_INTERNAL_STATE_ERROR;
+
+ bool need_notify = false;
+
+ SERVER_INFO("current_state %d m_shared_count %d", current_state, m_shared_count);
+
+ switch (current_state) {
+ case RMS_INTERNAL_STATE_SHARED:
+ m_shared_consumers.erase(consumer_id);
+ need_notify = true;
+
+ if (m_shared_count > 1) {
+ next_state = RMS_INTERNAL_STATE_SHARED;
+ } else if (m_shared_count == 1) {
+ next_state = RMS_INTERNAL_STATE_SHARABLE;
+ } else {
+ next_state = RMS_INTERNAL_STATE_FREE;
+ }
+ break;
+ case RMS_INTERNAL_STATE_EXCLUSIVE:
+ case RMS_INTERNAL_STATE_SHARABLE:
+ next_state = RMS_INTERNAL_STATE_FREE;
+ need_notify = true;
+ break;
+ case RMS_INTERNAL_STATE_FREE:
+ default:
+ SERVER_ERR("unexpected resource state (%d)", current_state);
+ next_state = RMS_INTERNAL_STATE_FREE;
+ break;
+ }
+
+ m_state = next_state;
+ SERVER_INFO("m_state %d need notify %d", m_state, need_notify);
+
+ if (m_category_type == RMS_CATEGORY_SCALER_SUB)
+ m_SetSubScalerFlag(next_state);
+
+ if (need_notify) {
+ m_mv_zone_id = -1;
+ NotifyObservers(UPDATED_BY_RELEASE, consumer_id);
+ }
+
+ return true;
+}
+
+bool CResource::IsAllocatableState(IN rms_requests_resource_state_e requested_state)
+{
+ bool can_allocation_matrix[4][6] =
+ /*requested_state*/ /* PASSIVE */ /*SHARABLE*/ /*EXCLUSIVE*/ /* EXCLUSIVE CON */ /* EXCLUSIVE AUTO */ /* EXCLUSIVE PREFERENCE */
+ /* m_state */ /* FREE */{ {false, true, true, true, true, true },
+ /* SHARABLE */ { true, true, false, false, false, false },
+ /* SHARED */ { true, true, false, false, false, false },
+ /* EXCLUSIVE */ { true, false, false, false, false, false } };
+
+ SERVER_INFO("Status - DevID[%d:%s] / CatID[%d] / CurState[%s] / ReqState[%s]",
+ m_id, m_device_name, m_category_type, rm_convert_state_enum_to_string(m_state), rm_convert_requested_state_enum_to_string(requested_state));
+
+ /* check requested_state is valid */
+ if ((requested_state < RMS_STATE_PASSIVE) || (requested_state > RMS_STATE_EXCLUSIVE_PREFERENCE)) {
+ SERVER_ERR("rquested state is invalid");
+ return false;
+ }
+
+ return can_allocation_matrix[m_state][requested_state];
+}
+
+void CResource::SetDefaultBW(unsigned int bw)
+{
+ m_default_bw = bw;
+ m_occupied_bw = bw;
+}
+void CResource::SetAllocatedTime(void)
+{
+ struct timespec t;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ unsigned long sec = t.tv_sec * 1000;
+ unsigned long nsec = t.tv_nsec / 1000000;
+ m_allocated_time = sec + nsec;
+}
+
+void CResource::RegisterObserver(CResourceObserver *observer)
+{
+ if (!observer) {
+ SERVER_ERR("observer NULL");
+ return;
+ }
+
+ m_observers.push_back(observer);
+}
+
+void CResource::UnregisterObserver(CResourceObserver *observer)
+{
+ auto it = std::find(m_observers.begin(), m_observers.end(), observer);
+
+ if (it == m_observers.end()) {
+ SERVER_ERR("not registered observer");
+ return;
+ }
+
+ m_observers.erase(it);
+
+ SERVER_INFO("observer removed");
+}
+
+void CResource::NotifyObservers(resource_update_type_e type, const int consumer_id)
+{
+ for (CResourceObserver *observer : m_observers) {
+ observer->Update(type, m_id, consumer_id);
+ }
+}
+
+bool CResource::Allocate(const int consumer_id, rms_requests_resource_state_e state, int mv_zone_id)
+{
+ if (!ChangeStateByAllocation(state, consumer_id, mv_zone_id))
+ return false;
+
+ AddConsumer(consumer_id, state);
+ return true;
+}
+
+void CResource::SetZoneId(int zone_id)
+{
+ SERVER_INFO("(%d) > zone_id(%d)", m_id, zone_id);
+ m_mv_zone_id = zone_id;
+}
+
+void CResource::UpdateAudioCodec(std::string codec_name)
+{
+ m_audio_codec = codec_name;
+}
+
+bool CResource::IsAudioDevice(void)
+{
+ if (m_category_type == RMS_CATEGORY_AUDIO_DECODER)
+ return true;
+ if (m_category_type == RMS_CATEGORY_AUDIO_DECODER_SUB)
+ return true;
+ if (m_category_type == RMS_CATEGORY_AUDIO_DECODER_PRIMARY)
+ return true;
+ if ((m_category_type > RMS_CATEGORY_AUDIO_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_AUDIO_DECODER_OPTION_MAX))
+ return true;
+
+ return false;
+}
+
+bool CResource::IsVideoDecoder(void)
+{
+ if (m_category_type == RMS_CATEGORY_VIDEO_DECODER)
+ return true;
+ if (m_category_type == RMS_CATEGORY_VIDEO_DECODER_SUB)
+ return true;
+ if ((m_category_type > RMS_CATEGORY_VIDEO_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_VIDEO_DECODER_OPTION_MAX))
+ return true;
+ if (m_category_type == RMS_CATEGORY_MJPEG_DECODER)
+ return true;
+ if ((m_category_type > RMS_CATEGORY_MJPEG_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_MJPEG_DECODER_OPTION_MAX))
+ return true;
+
+ return false;
+}
+
+int CResource::GetFirstConsumer(void)
+{
+ if (m_consumer_ids.empty())
+ return -1;
+
+ auto it = m_consumer_ids.begin();
+ return *it;
+}
+
+int CResource::GetVirtualDeviceId(void)
+{
+ return (m_virtual_id < RI_VIRTUAL_ID_SCALER) ? m_id : m_virtual_id;
+}
+
+bool CResource::IsJpegDecoder(void)
+{
+ if (m_category_type == RMS_CATEGORY_JPEG_DECODER)
+ return true;
+ if ((m_category_type > RMS_CATEGORY_JPEG_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_JPEG_DECODER_OPTION_MAX))
+ return true;
+
+ return false;
+}
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <stdlib.h>\r
-#include <iostream>\r
-\r
-#include <CResourceCategory.h>\r
-#include <CBandwidth.h>\r
-#include <CRequest.h>\r
-#include <CVirtualResource.h>\r
-#include <CDebugUtils.h>\r
-#include <CDependencyController.h>\r
-#include <CAllocateStrategy.h>\r
-#include <CAllocateStrategyProvider.h>\r
-#include <rms_debug.h>\r
-#include <rms_type.h>\r
-\r
-CResourceCategory::CResourceCategory(IN rms_rsc_category_e resource_category_id, IN int category_class)\r
-:m_categoryID(resource_category_id)\r
-{\r
- m_alloc_strategy = CAllocateStrategyProvider::getInstance()->GetStrategy(resource_category_id, category_class);\r
- assert(m_alloc_strategy);\r
-}\r
-\r
-CResourceCategory::~CResourceCategory()\r
-{\r
- delete m_alloc_strategy;\r
-}\r
-\r
-void CResourceCategory::AddVirtualResource(IN int device_id, IN CVirtualResource *vresource)\r
-{\r
- std::map<int, CVirtualResource *>::iterator it = m_device_id_to_vresource_map.find(device_id);\r
-\r
- if (it != m_device_id_to_vresource_map.end())\r
- return;\r
-\r
- m_device_id_to_vresource_map.insert(std::pair<int, CVirtualResource *>(device_id, vresource));\r
-}\r
-\r
-CResource *CResourceCategory::ReserveCandidate(CRequest *req, bool apply_promotion)\r
-{\r
- CVirtualResource *vrsc = m_alloc_strategy->findCandidate(m_device_id_to_vresource_map, req);\r
-\r
- if (!vrsc)\r
- return NULL;\r
-\r
- if (m_alloc_strategy->reserveResource(vrsc, req) != RMS_OK) {\r
- SERVER_INFO("can't find candidate (%d)", m_categoryID);\r
- return NULL;\r
- }\r
-\r
- SERVER_INFO("candidate found (%d:%d)", m_categoryID, vrsc->GetResource()->GetDeviceID());\r
-\r
- req->SetResult(RMS_OK);\r
- req->SetReason(RMS_ERR_TYPE_NONE);\r
-\r
- return vrsc->GetResource();\r
-}\r
-\r
-bool CResourceCategory::hasFreeStateResource(void)\r
-{\r
- for (auto& it : m_device_id_to_vresource_map) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *resource = vresource->GetResource();\r
-\r
- if (resource->IsFreeState())\r
- return true;\r
- }\r
-\r
- return false;\r
-}\r
-\r
-void CResourceCategory::MakeResourceMapSortedByAllocTime(std::multimap<unsigned long, CVirtualResource *> *resource_map)\r
-{\r
- for (auto& it : m_device_id_to_vresource_map) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *rsc = vresource->GetResource();\r
-\r
- resource_map->insert(std::pair<unsigned long, CVirtualResource *>(rsc->GetAllocatedTime(), vresource));\r
- }\r
-}\r
-\r
-void CResourceCategory::GetRetirableConsumers(CRequest *req,\r
- std::multimap<int, int>* return_ids_in_category,\r
- rms_error_type_e *err_type)\r
-{\r
- assert(return_ids_in_category);\r
-\r
- std::multimap<unsigned long, CVirtualResource *> sorted_resource_map;\r
- MakeResourceMapSortedByAllocTime(&sorted_resource_map);\r
- m_alloc_strategy->GetRetirableConsumers(sorted_resource_map, req, return_ids_in_category, err_type);\r
-}\r
-\r
-bool CResourceCategory::IsAvailableToUse(rms_requests_resource_state_e request_state)\r
-{\r
- CResource *resource;\r
- CDependencyController *dc = CDependencyController::getInstance();\r
- CBandwidth *bandwidth = CBandwidth::GetInstance();\r
-\r
- for (auto& it : m_device_id_to_vresource_map) {\r
- CVirtualResource *vresource = it.second;\r
- resource = vresource->GetResource();\r
-\r
- if (!dc->isAvailableMemClusters(vresource->GetMemClusters())) {\r
- SERVER_ERR("Not available: Mem Cluster is occupied.");\r
- continue;\r
- }\r
-\r
- if (vresource->GetBW() > bandwidth->GetAvail()) {\r
- SERVER_ERR("Not available: BW is insufficient!!");\r
- continue;\r
- }\r
-\r
- if ((request_state == RMS_STATE_SHARABLE) && (!resource->IsSharableDevice())) {\r
- SERVER_ERR("Not available: resource(%d) cannot be shared", resource->GetDeviceID());\r
- continue;\r
- }\r
-\r
- if (resource->IsAllocatableState(request_state))\r
- return true;\r
- }\r
-\r
- return false;\r
-}\r
-\r
-void CResourceCategory::GetResources(std::map<int, CResource*> *resource_map)\r
-{\r
- int i = 0;\r
- for (auto& it : m_device_id_to_vresource_map) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *resource = vresource->GetResource();\r
- resource_map->insert(std::pair<int, CResource*>(i++, resource));\r
- }\r
-}\r
-\r
-CResource *CResourceCategory::FindMainResource(void)\r
-{\r
- for (auto& it : m_device_id_to_vresource_map) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *resource = vresource->GetResource();\r
-\r
- if (resource->IsMainDevice())\r
- return resource;\r
- }\r
-\r
- return NULL;\r
-}\r
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <iostream>
+
+#include <CResourceCategory.h>
+#include <CBandwidth.h>
+#include <CRequest.h>
+#include <CVirtualResource.h>
+#include <CDebugUtils.h>
+#include <CDependencyController.h>
+#include <CAllocateStrategy.h>
+#include <CAllocateStrategyProvider.h>
+#include <rms_debug.h>
+#include <rms_type.h>
+
+CResourceCategory::CResourceCategory(IN rms_rsc_category_e resource_category_id, IN int category_class)
+:m_categoryID(resource_category_id)
+{
+ m_alloc_strategy = CAllocateStrategyProvider::getInstance()->GetStrategy(resource_category_id, category_class);
+ assert(m_alloc_strategy);
+}
+
+CResourceCategory::~CResourceCategory()
+{
+ delete m_alloc_strategy;
+}
+
+void CResourceCategory::AddVirtualResource(IN int device_id, IN CVirtualResource *vresource)
+{
+ std::map<int, CVirtualResource *>::iterator it = m_device_id_to_vresource_map.find(device_id);
+
+ if (it != m_device_id_to_vresource_map.end())
+ return;
+
+ m_device_id_to_vresource_map.insert(std::pair<int, CVirtualResource *>(device_id, vresource));
+}
+
+CResource *CResourceCategory::ReserveCandidate(CRequest *req, bool apply_promotion)
+{
+ CVirtualResource *vrsc = m_alloc_strategy->findCandidate(m_device_id_to_vresource_map, req);
+
+ if (!vrsc)
+ return NULL;
+
+ if (m_alloc_strategy->reserveResource(vrsc, req) != RMS_OK) {
+ SERVER_INFO("can't find candidate (%d)", m_categoryID);
+ return NULL;
+ }
+
+ SERVER_INFO("candidate found (%d:%d)", m_categoryID, vrsc->GetResource()->GetDeviceID());
+
+ req->SetResult(RMS_OK);
+ req->SetReason(RMS_ERR_TYPE_NONE);
+
+ return vrsc->GetResource();
+}
+
+bool CResourceCategory::hasFreeStateResource(void)
+{
+ for (auto& it : m_device_id_to_vresource_map) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+
+ if (resource->IsFreeState())
+ return true;
+ }
+
+ return false;
+}
+
+void CResourceCategory::MakeResourceMapSortedByAllocTime(std::multimap<unsigned long, CVirtualResource *> *resource_map)
+{
+ for (auto& it : m_device_id_to_vresource_map) {
+ CVirtualResource *vresource = it.second;
+ CResource *rsc = vresource->GetResource();
+
+ resource_map->insert(std::pair<unsigned long, CVirtualResource *>(rsc->GetAllocatedTime(), vresource));
+ }
+}
+
+void CResourceCategory::GetRetirableConsumers(CRequest *req,
+ std::multimap<int, int>* return_ids_in_category,
+ rms_error_type_e *err_type)
+{
+ assert(return_ids_in_category);
+
+ std::multimap<unsigned long, CVirtualResource *> sorted_resource_map;
+ MakeResourceMapSortedByAllocTime(&sorted_resource_map);
+ m_alloc_strategy->GetRetirableConsumers(sorted_resource_map, req, return_ids_in_category, err_type);
+}
+
+bool CResourceCategory::IsAvailableToUse(rms_requests_resource_state_e request_state)
+{
+ CResource *resource;
+ CDependencyController *dc = CDependencyController::getInstance();
+ CBandwidth *bandwidth = CBandwidth::GetInstance();
+
+ for (auto& it : m_device_id_to_vresource_map) {
+ CVirtualResource *vresource = it.second;
+ resource = vresource->GetResource();
+
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters())) {
+ SERVER_ERR("Not available: Mem Cluster is occupied.");
+ continue;
+ }
+
+ if (vresource->GetBW() > bandwidth->GetAvail()) {
+ SERVER_ERR("Not available: BW is insufficient!!");
+ continue;
+ }
+
+ if ((request_state == RMS_STATE_SHARABLE) && (!resource->IsSharableDevice())) {
+ SERVER_ERR("Not available: resource(%d) cannot be shared", resource->GetDeviceID());
+ continue;
+ }
+
+ if (resource->IsAllocatableState(request_state))
+ return true;
+ }
+
+ return false;
+}
+
+void CResourceCategory::GetResources(std::map<int, CResource*> *resource_map)
+{
+ int i = 0;
+ for (auto& it : m_device_id_to_vresource_map) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+ resource_map->insert(std::pair<int, CResource*>(i++, resource));
+ }
+}
+
+CResource *CResourceCategory::FindMainResource(void)
+{
+ for (auto& it : m_device_id_to_vresource_map) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+
+ if (resource->IsMainDevice())
+ return resource;
+ }
+
+ return NULL;
+}
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <iostream>\r
-#include <assert.h>\r
-#include <stdlib.h>\r
-#include <glib.h>\r
-#include <gio/gio.h>\r
-\r
-#include <ri-module-api.h>\r
-#include <vconf.h>\r
-\r
-#include <rms_debug.h>\r
-#include <rms_type.h>\r
-\r
-#include <CDebugUtils.h>\r
-#include <CAudioCodecCollection.h>\r
-#include <CBandwidth.h>\r
-#include <CVirtualResource.h>\r
-#include <CConsumer.h>\r
-#include <CConsumerContainer.h>\r
-#include <CDependencyController.h>\r
-#include <CResourceDB.h>\r
-#include <CVideoController.h>\r
-#include <CResourceState.h>\r
-\r
-CResourceDB *CResourceDB::m_instance = NULL;\r
-\r
-CResourceDB *CResourceDB::getInstance(void)\r
-{\r
- if (!m_instance) {\r
- m_instance = new(std::nothrow) CResourceDB;\r
- assert(m_instance);\r
- }\r
-\r
- return m_instance;\r
-}\r
-\r
-CResourceCategory *CResourceDB::FindResourceCategory(IN rms_rsc_category_e category_id)\r
-{\r
- std::map<rms_rsc_category_e, CResourceCategory*>::iterator it = m_resourceCategoryMap.find(category_id);\r
-\r
- if (it == m_resourceCategoryMap.end())\r
- return NULL;\r
-\r
- return (*it).second;\r
-}\r
-\r
-CResource *CResourceDB::FindResource(IN const int device_id)\r
-{\r
- std::map<int, CResource*>::iterator it = m_deviceid_to_rsc.find(device_id);\r
-\r
- if (it == m_deviceid_to_rsc.end()) {\r
- SERVER_ERR("no device id(%d) in DB", device_id);\r
- return NULL;\r
- }\r
-\r
- return (*it).second;\r
-}\r
-\r
-CVirtualResource *CResourceDB::FindVirtualResource(const int vid)\r
-{\r
- auto it = m_v_deviceid_to_rsc.find(vid);\r
-\r
- return (it == m_v_deviceid_to_rsc.end()) ? nullptr : it->second;\r
-}\r
-\r
-void CResourceDB::AddVirtualDeviceID(IN CVirtualResource *vresource)\r
-{\r
- int vrsc_id = vresource->GetVResourceID();\r
-\r
- std::map<int, CVirtualResource *>::iterator it = m_v_deviceid_to_rsc.find(vrsc_id);\r
-\r
- if (it != m_v_deviceid_to_rsc.end())\r
- return;\r
-\r
- m_v_deviceid_to_rsc.insert(std::pair<int, CVirtualResource *>(vrsc_id, vresource));\r
-}\r
-\r
-void CResourceDB::AddDeviceID(IN int device_id, IN CResource *resource)\r
-{\r
- std::map<int, CResource*>::iterator it = m_deviceid_to_rsc.find(device_id);\r
- \r
- if (it != m_deviceid_to_rsc.end())\r
- return;\r
-\r
- m_deviceid_to_rsc.insert(std::pair<int, CResource*>(device_id, resource));\r
-}\r
-\r
-void CResourceDB::AddDeviceName(IN const char *device_name, IN CResource *resource)\r
-{\r
- auto it = m_devicename_to_rsc.find(std::string(device_name));\r
- \r
- if (it != m_devicename_to_rsc.end()) {\r
- SERVER_DBG("already registered device name(%s) in DB", device_name);\r
- return;\r
- }\r
-\r
- m_devicename_to_rsc.insert(std::pair<std::string, CResource*>(std::string(device_name), resource));\r
-}\r
-\r
-void CResourceDB::AddResourceCategory(IN rms_rsc_category_e category_id, IN CResourceCategory *resource_category)\r
-{\r
- std::map<rms_rsc_category_e, CResourceCategory*>::iterator it = m_resourceCategoryMap.find(category_id);\r
-\r
- if (it != m_resourceCategoryMap.end())\r
- return;\r
-\r
- m_resourceCategoryMap.insert(std::pair<rms_rsc_category_e, CResourceCategory*>(category_id, resource_category));\r
-}\r
-\r
-CResource *CResourceDB::FindResource(const char *device_name)\r
-{\r
- auto it = m_devicename_to_rsc.find(std::string(device_name));\r
-\r
- return (it == m_devicename_to_rsc.end()) ? NULL : it->second;\r
-}\r
-\r
-void CResourceDB::AddVirtualResource(IN CVirtualResource *vrsc,\r
- IN rms_rsc_category_e resource_category_id,\r
- IN const char *name,\r
- IN const char *path,\r
- IN std::set<unsigned int> mem_cluster_info,\r
- IN unsigned int device_id_unique,\r
- IN int is_main_device,\r
- IN const char *audio_codec,\r
- IN int sharable_count,\r
- IN int mixing_count,\r
- IN CResourceObserver *observer)\r
-{\r
- assert(name);\r
- assert(path);\r
-\r
- CResource *rsc = FindResource(name);\r
-\r
- if (!rsc) {\r
- rsc = new CResource(device_id_unique, resource_category_id, name, path, mem_cluster_info, is_main_device, audio_codec, sharable_count);\r
-\r
- AddDeviceName(name, rsc);\r
- AddDeviceID(device_id_unique, rsc);\r
-\r
- rsc->RegisterObserver(this);\r
- rsc->RegisterObserver(observer);\r
- }\r
-\r
- vrsc->SetResource(rsc);\r
-\r
- CAudioCodecCollection::getInstance()->registerAudioCodec(audio_codec, mixing_count);\r
-\r
- if (rsc->GetDefaultBW() == 0)\r
- rsc->SetDefaultBW(vrsc->GetBW());\r
-\r
- AddVirtualDeviceID(vrsc);\r
-}\r
-\r
-void CResourceDB::UpdateBWbyRelease(CResource *rsc)\r
-{\r
- if (!rsc)\r
- return;\r
-\r
- if (rsc->GetBW() == 0)\r
- return;\r
-\r
- CBandwidth *bw = CBandwidth::GetInstance();\r
- bw->RemoveConsumer(rsc->GetDeviceID(), rsc->GetCurCategory(), rsc->GetCategoryClass());\r
- bw->Increase(rsc->GetBW(), rsc->GetCurCategory(), rsc->GetCategoryClass(), rsc->GetDeviceID());\r
-\r
- return;\r
-}\r
-\r
-void CResourceDB::UpdateByRelease(CResource *resource, const int device_id, const int consumer_id)\r
-{\r
- UpdateBWbyRelease(resource);\r
-\r
- if (resource->IsVideoDecoder())\r
- RemoveActiveVideoDecoder(device_id, resource->GetCategoryClass());\r
-\r
- if (resource->IsJpegDecoder())\r
- RemoveActiveJpegDecoder(device_id);\r
-\r
- RemoveResourceHasZoneId(resource->GetDeviceID());\r
-}\r
-\r
-void CResourceDB::UpdateBWbyAllocation(const unsigned int bandwidth, CResource *rsc)\r
-{\r
- CBandwidth *bw = CBandwidth::GetInstance();\r
- bw->Decrease(bandwidth, rsc->GetCurCategory(), rsc->GetCategoryClass(), rsc->GetDeviceID());\r
-\r
- //SERVER_INFO("bw updated avail(%d)/max(%d)", bw->GetAvail(), bw->GetMax());\r
-}\r
-\r
-void CResourceDB::UpdateByAllocation(CResource *resource, const int device_id, const int consumer_id)\r
-{\r
- unsigned int bw = resource->GetBW();\r
-\r
- if (bw > 0) {\r
- UpdateBWbyAllocation(bw, resource);\r
- CBandwidth::GetInstance()->AddConsumer(device_id, consumer_id, resource->GetCurCategory(), resource->GetCategoryClass());\r
- }\r
-\r
- if (resource->IsVideoDecoder())\r
- AddActiveVideoDecoder(device_id, consumer_id, resource->GetCategoryClass());\r
-\r
- if (resource->IsScaler())\r
- SetVirtualScalerId(resource);\r
-\r
- if (resource->IsJpegDecoder())\r
- AddActiveJpegDecoder(device_id, consumer_id);\r
-\r
- if (resource->GetZoneId() > 0)\r
- InsertResourceHasZoneId(resource);\r
-}\r
-\r
-void CResourceDB::SetVirtualScalerId(CResource *resource)\r
-{\r
- int scaler_id = GetVirtualScalerId(resource);\r
-\r
- SERVER_INFO("map scaler (%d:%d)", scaler_id, resource->GetDeviceID());\r
-\r
- resource->SetVirtualDeviceId(scaler_id);\r
- InsertVirtualScaler(scaler_id, resource);\r
-}\r
-\r
-void CResourceDB::PrintVirtualScalerMap(void)\r
-{\r
- for (auto &it : m_scaler_map) {\r
- if (it.second == nullptr) {\r
- //SERVER_INFO("[%d : %d (%s)]", it.first, 0, "null");\r
- continue;\r
- }\r
- //SERVER_INFO("[%d : %d (%s)/(%d)]", it.first, it.second->GetDeviceID(), it.second->GetName().c_str(), it.second->GetVirtualDeviceId());\r
- }\r
-}\r
-\r
-int CResourceDB::GetVirtualScalerId(CResource *resource)\r
-{\r
- CResource *rsc = nullptr;\r
-\r
- for (auto &it : m_scaler_map) {\r
- rsc = it.second;\r
- if (rsc == nullptr)\r
- continue;\r
- if (rsc->GetDeviceID() == resource->GetDeviceID())\r
- return it.first;\r
- }\r
-\r
- return resource->GetDedicatedVirtualDeviceId();\r
-}\r
-\r
-void CResourceDB::AddActiveVideoDecoder(const int device_id, const int consumer_id, const int category_class)\r
-{\r
- m_active_vdecs.insert(std::pair<int, int>(device_id, consumer_id));\r
-\r
- if (category_class == RMS_CATEGORY_CLASS_N_DECODING)\r
- m_active_nvdecs.insert(std::pair<int, int>(device_id, consumer_id));\r
-}\r
-\r
-void CResourceDB::RemoveActiveVideoDecoder(const int device_id, const int category_class)\r
-{\r
- m_active_vdecs.erase(device_id);\r
-\r
- if (category_class == RMS_CATEGORY_CLASS_N_DECODING)\r
- m_active_nvdecs.erase(device_id);\r
-}\r
-\r
-void CResourceDB::AddActiveJpegDecoder(const int device_id, const int consumer_id)\r
-{\r
- m_active_jdecs.insert(std::pair<int, int>(device_id, consumer_id));\r
-}\r
-\r
-void CResourceDB::RemoveActiveJpegDecoder(const int device_id)\r
-{\r
- m_active_jdecs.erase(device_id);\r
-}\r
-\r
-int CResourceDB::GetActiveDecoderNum(void)\r
-{\r
- int num = 0;\r
-\r
- num += m_active_vdecs.size();\r
- num += m_active_jdecs.size();\r
-\r
- return num;\r
-}\r
-\r
-void CResourceDB::PrintVideoDecoderConsumers(void)\r
-{\r
- for (auto const &it : m_active_vdecs) {\r
- SERVER_INFO("dev(%d) by (%d)", it.first, it.second);\r
- }\r
-}\r
-\r
-bool CResourceDB::HasAvailableDecoder(void)\r
-{\r
- int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;\r
- int active_vdecs = m_active_vdecs.size();\r
- int active_ndecs = m_active_nvdecs.size();\r
-\r
- SERVER_INFO("active(%d) / n_dec(%d) / max(%d / %d)", active_vdecs, active_ndecs, max_vdecs, m_max_vdecs);\r
-\r
- if (active_ndecs > 0)\r
- active_vdecs = active_vdecs + (1 - active_ndecs);\r
-\r
- if (active_vdecs >= max_vdecs)\r
- PrintVideoDecoderConsumers();\r
-\r
- return (active_vdecs < max_vdecs);\r
-}\r
-\r
-bool CResourceDB::HasAvailableDecoderNDecoding(void)\r
-{\r
- int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;\r
- int active_vdecs = m_active_vdecs.size();\r
- int active_ndecs = m_active_nvdecs.size();\r
-\r
- SERVER_INFO("active(%d) / n_dec(%d) / max(%d %d)", active_vdecs, active_ndecs, max_vdecs, m_max_vdecs);\r
-\r
- if (active_ndecs > 0) {\r
- active_vdecs = active_vdecs + (1 - active_ndecs);\r
- return true;\r
- }\r
-\r
- if (active_vdecs >= max_vdecs)\r
- PrintVideoDecoderConsumers();\r
-\r
- return (active_vdecs < max_vdecs);\r
-}\r
-\r
-bool CResourceDB::HasAvailableDecoder(std::multimap<int, int> retirables)\r
-{\r
- int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;\r
- std::map<int, int> retirables_vdecs;\r
-\r
- SERVER_INFO("max(%d %d)", max_vdecs, m_max_vdecs);\r
-\r
- for (auto &it : retirables) {\r
- CResource *rsc = FindResource(it.first);\r
- if (!rsc)\r
- continue;\r
-\r
- if (rsc->IsVideoDecoder())\r
- retirables_vdecs.insert(std::pair<int, int>(it.first, it.second));\r
- }\r
-\r
- int active_vdecs = m_active_vdecs.size();\r
- int active_ndecs = m_active_nvdecs.size();\r
- int retirable_vdecs = retirables_vdecs.size();\r
- int retirable_ndecs = CountNDecoders(retirables_vdecs);\r
-\r
- int remain = 0;\r
-\r
- if ((active_ndecs - retirable_ndecs) > 0)\r
- remain = (active_vdecs - retirable_vdecs) + (1 - (active_ndecs - retirable_ndecs));\r
- else\r
- remain = active_vdecs - retirable_vdecs;\r
-\r
- SERVER_INFO("remain(%d)/max(%d), av(%d)/an(%d)/rv(%d)/rn(%d)", remain, max_vdecs, active_vdecs, active_ndecs, retirable_vdecs, retirable_ndecs);\r
-\r
- if (remain >= max_vdecs)\r
- PrintVideoDecoderConsumers();\r
-\r
- return (remain < max_vdecs);\r
-}\r
-\r
-bool CResourceDB::HasAvailableDecoderNDecoding(std::multimap<int, int> retirables)\r
-{\r
- int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;\r
- std::map<int, int> retirables_vdecs;\r
-\r
- SERVER_INFO("max(%d %d)", max_vdecs, m_max_vdecs);\r
-\r
- for (auto &it : retirables) {\r
- CResource *rsc = FindResource(it.first);\r
- if (!rsc)\r
- continue;\r
-\r
- if (rsc->IsVideoDecoder())\r
- retirables_vdecs.insert(std::pair<int, int>(it.first, it.second));\r
- }\r
-\r
- int active_vdecs = m_active_vdecs.size();\r
- int active_ndecs = m_active_nvdecs.size();\r
- int retirable_vdecs = retirables_vdecs.size();\r
- int retirable_ndecs = CountNDecoders(retirables_vdecs);\r
-\r
- int remain = 0;\r
-\r
- if ((active_ndecs - retirable_ndecs) > 0)\r
- remain = (active_vdecs - retirable_vdecs) + (1 - (active_ndecs - retirable_ndecs));\r
- else\r
- remain = active_vdecs - retirable_vdecs;\r
-\r
- SERVER_INFO("remain(%d)/max(%d), av(%d)/an(%d)/rv(%d)/rn(%d)", remain, max_vdecs, active_vdecs, active_ndecs, retirable_vdecs, retirable_ndecs);\r
-\r
- if (active_ndecs > 0 && retirable_ndecs > 0)\r
- return true;\r
-\r
- if (remain >= max_vdecs)\r
- PrintVideoDecoderConsumers();\r
-\r
- return (remain < max_vdecs);\r
-}\r
-\r
-int CResourceDB::CountNDecoders(std::map<int, int> retirables_vdecs)\r
-{\r
- int ndecs = 0;\r
- for (auto &it_rsc : retirables_vdecs) {\r
- auto it_ndec = m_active_nvdecs.find(it_rsc.first);\r
-\r
- if (it_ndec != m_active_nvdecs.end())\r
- ndecs++;\r
- }\r
-\r
- SERVER_INFO("ndecs(%d) in retirables(%zu)", ndecs, retirables_vdecs.size());\r
- return ndecs;\r
-}\r
-\r
-void CResourceDB::Update(resource_update_type_e type, const int device_id, const int consumer_id)\r
-{\r
- CResource *resource = FindResource(device_id);\r
-\r
- if (!resource)\r
- return;\r
-\r
- switch (type) {\r
- case UPDATED_BY_ALLOC:\r
- SERVER_WARN("UPDATED_BY_ALLOC");\r
- UpdateByAllocation(resource, device_id, consumer_id);\r
- break;\r
- case UPDATED_BY_RELEASE:\r
- SERVER_WARN("UPDATED_BY_RELEASE");\r
- UpdateByRelease(resource, device_id, consumer_id);\r
- break;\r
- default:\r
- SERVER_ERR("unexpected update type (%d)", type);\r
- break;\r
- }\r
-\r
- NotifyResourceStateUpdatedAsync(resource, consumer_id);\r
-}\r
-\r
-void CResourceDB::AddReclaimResources(consumer_reclaim_s *consumers)\r
-{\r
- for (int i = 0; i < consumers->ret_quantity; i++) {\r
- for (int j = 0; j < consumers->consumer_info[i].n_conflicted; j++) {\r
- SERVER_INFO("add reclaim rsc (%d)", consumers->consumer_info[i].conflicted_resources[j].device_id);\r
- m_reclaim_rscs.insert(consumers->consumer_info[i].conflicted_resources[j].device_id);\r
- }\r
- }\r
-}\r
-\r
-void CResourceDB::ClearReclaimResources(void)\r
-{\r
- m_reclaim_rscs.clear();\r
-}\r
-\r
-gboolean CResourceDB::NotifyResourceStateUpdated(gpointer data)\r
-{\r
- if (!data) {\r
- SERVER_ERR("invalid data");\r
- return G_SOURCE_REMOVE;\r
- }\r
-\r
- CResourceState *state = (CResourceState*) data;\r
-\r
- GError *error = NULL;\r
- GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);\r
-\r
- if (!connection) {\r
- SERVER_ERR("failed to get connection (%s)", (error) ? error->message : "unknown");\r
- goto out;\r
- }\r
-\r
- SERVER_INFO("notify state changed (device id %d( type %d) : state %d)", state->GetDeviceId(), state->GetCategoryType(), state->GetState());\r
-\r
- if (!g_dbus_connection_emit_signal(connection,\r
- NULL,\r
- RM_DBUS_OBJ_PATH,\r
- RM_DBUS_INTERFACE_NAME,\r
- "RscStateChanged",\r
- g_variant_new("(iiiis)", state->GetDeviceId(), state->GetCategoryType(), state->GetState(), state->GetConsumerId(), state->GetAppId().c_str()),\r
- &error))\r
- SERVER_ERR("failed to send state changed (%d:%s)", state->GetDeviceId(), (error) ? error->message : "unknown");\r
-\r
-out:\r
- if (error)\r
- g_error_free(error);\r
-\r
- delete state;\r
- return G_SOURCE_REMOVE;\r
-}\r
-\r
-void CResourceDB::NotifyResourceStateUpdatedAsync(CResource *resource, int consumer_id)\r
-{\r
- int device_id = resource->GetDeviceID();\r
- CConsumer *consumer = CConsumerContainer::getInstance()->findConsumer(consumer_id);\r
-\r
- if (!consumer) {\r
- SERVER_WARN("Consumer %d is not found", consumer_id);\r
- return;\r
- }\r
-\r
- std::string app_id = consumer->GetAppID();\r
-\r
- if (app_id.empty())\r
- app_id = consumer->GetCmdName();\r
-\r
- SERVER_INFO("device id (%d) consumer id (%d)", device_id, consumer_id);\r
-\r
- if (m_reclaim_rscs.find(device_id) != m_reclaim_rscs.end()) {\r
- SERVER_DBG("skip to notify state updated (%d)", device_id);\r
- return;\r
- }\r
-\r
- CResourceState *state = new CResourceState(resource->GetDeviceID(), resource->GetCategoryType(), consumer_id, resource->GetState(), app_id);\r
- g_idle_add(&CResourceDB::NotifyResourceStateUpdated, state);\r
-}\r
-\r
-CResource *CResourceDB::FindMainResource(rms_rsc_category_e category_id)\r
-{\r
- CResourceCategory *category = FindResourceCategory(category_id);\r
- if (!category) {\r
- SERVER_ERR("category(%d) not found", category_id);\r
- return NULL;\r
- }\r
-\r
- return category->FindMainResource();\r
-}\r
-\r
-void CResourceDB::FindMainResources(IN std::map<int, CResource*> *resource_map)\r
-{\r
- rms_rsc_category_e categories[5] = {RMS_CATEGORY_VIDEO_DECODER,\r
- RMS_CATEGORY_VIDEO_DECODER_UHD,\r
- RMS_CATEGORY_SCALER,\r
- RMS_CATEGORY_AUDIO_DECODER,\r
- RMS_CATEGORY_AUDIO_MAIN_OUT};\r
- CResource *resource = NULL;\r
-\r
- for (int i = 0; i < 5; i++) {\r
- resource = FindMainResource(categories[i]);\r
- if (!resource) {\r
- SERVER_INFO("no main resource for (%d)", categories[i]);\r
- continue;\r
- }\r
-\r
- resource_map->insert(std::pair<int, CResource*>(resource->GetDeviceID(), resource));\r
- }\r
-}\r
-\r
-void CResourceDB::FindActiveVideoDecoders(IN std::map<int, CResource*> *resource_map)\r
-{\r
- CResource *rsc = nullptr;\r
- for (auto const &it : m_active_vdecs) {\r
- rsc = FindResource(it.first);\r
- if (!rsc)\r
- continue;\r
- resource_map->insert(std::pair<int, CResource*>(it.first, rsc));\r
- }\r
-}\r
-\r
-void CResourceDB::GetScalerList(std::map<int, CResource*> *scalers)\r
-{\r
- CResource *rsc = nullptr;\r
- for (auto &it : m_deviceid_to_rsc) {\r
- rsc = it.second;\r
- if (!rsc->IsScaler())\r
- continue;\r
-\r
- scalers->insert(std::pair<int, CResource*>(rsc->GetDeviceID(), rsc));\r
- }\r
-}\r
-\r
-void CResourceDB::InitScalerTable(void)\r
-{\r
- CResource *rsc = nullptr;\r
- int sub_scaler_count = 0;\r
- int vid = 0;\r
-\r
- std::map<int, CResource*> scalers;\r
- GetScalerList(&scalers);\r
-\r
- for (auto &it : scalers) {\r
- rsc = it.second;\r
-\r
- if (!rsc->IsMainDevice())\r
- sub_scaler_count++;\r
-\r
- vid = (rsc->IsMainDevice()) ? RI_VIRTUAL_ID_SCALER : (RI_VIRTUAL_ID_SCALER + sub_scaler_count);\r
- rsc->SetDedicatedVirtualDeviceId(vid);\r
- rsc->SetVirtualDeviceId(vid);\r
- //SERVER_INFO("insert scaler (%d:%d)", vid, rsc->GetDeviceID());\r
- m_scaler_map.insert(std::pair<int, CResource*>(vid, rsc));\r
- }\r
-}\r
-\r
-int CResourceDB::FindRealDeviceId(int virtual_id)\r
-{\r
- auto it = m_scaler_map.find(virtual_id);\r
-\r
- if (it == m_scaler_map.end())\r
- return virtual_id;\r
-\r
- CResource *rsc = it->second;\r
-\r
- return (rsc == nullptr) ? virtual_id : rsc->GetDeviceID();\r
-}\r
-\r
-CResource *CResourceDB::FindScaler(int virtual_id)\r
-{\r
- auto it = m_scaler_map.find(virtual_id);\r
- if (it == m_scaler_map.end())\r
- return nullptr;\r
-\r
- return it->second;\r
-}\r
-\r
-int CResourceDB::ToScalerId(int device_id)\r
-{\r
- const int SCALER_ID_MAIN = 0;\r
- const int SCALER_ID_SUB = 1;\r
- const int SCALER_ID_SUB2 = 2;\r
- const int SCALER_ID_SUB3 = 3;\r
- const int SCALER_ID_UNKNOWN = 99;\r
- int source_id = SCALER_ID_UNKNOWN;\r
-\r
- switch (device_id) {\r
- case RMS_DEVICE_SCALER:\r
- source_id = SCALER_ID_MAIN;\r
- break;\r
- case RMS_DEVICE_SCALER_SUB:\r
- source_id = SCALER_ID_SUB;\r
- break;\r
- case RMS_DEVICE_SCALER_SUB2:\r
- source_id = SCALER_ID_SUB2;\r
- break;\r
- case RMS_DEVICE_SCALER_SUB3:\r
- source_id = SCALER_ID_SUB3;\r
- break;\r
- default:\r
- SERVER_ERR("unexpected device_id(%d)", device_id);\r
- break;\r
- }\r
-\r
- return source_id;\r
-}\r
-\r
-void CResourceDB::UpdateVirtualScalerIds(void)\r
-{\r
- std::map<int, int> scaler_map;\r
- for (auto &it : m_scaler_map) {\r
- if (it.second == nullptr) {\r
- SERVER_INFO("[%d : %d (%s)]", it.first, 0, "null");\r
- continue;\r
- }\r
-\r
- scaler_map.insert(std::pair<int, int>(it.first, ToScalerId(it.second->GetDeviceID())));\r
- SERVER_INFO("[%d : %d (%s)/(%d)]", it.first, it.second->GetDeviceID(), it.second->GetName().c_str(), it.second->GetVirtualDeviceId());\r
- }\r
-\r
- CVideoController::GetInstance()->UpdateVirtualScalerIds(scaler_map);\r
-}\r
-\r
-void CResourceDB::InsertVirtualScaler(int virtual_id, CResource *resource)\r
-{\r
- m_scaler_map.erase(virtual_id);\r
- m_scaler_map.insert(std::pair<int, CResource*>(virtual_id, resource));\r
- PrintVirtualScalerMap();\r
-}\r
-\r
-int CResourceDB::SwapScaler(int id_a, int id_b)\r
-{\r
- CResource *rsc_a = FindScaler(id_a);\r
- CResource *rsc_b = FindScaler(id_b);\r
-\r
- SERVER_INFO("scaler swap (%d <-> %d)", id_a, id_b);\r
-\r
- if (!rsc_a || !rsc_b) {\r
- SERVER_ERR("invalid scaler id_a(%d)/id_b(%d)", id_a, id_b);\r
- return -1;\r
- }\r
-\r
- std::set<int> consumers_a = rsc_a->GetConsumers();\r
- std::set<int> consumers_b = rsc_b->GetConsumers();\r
-\r
- int zone_a = rsc_a->GetZoneId();\r
- int zone_b = rsc_b->GetZoneId();\r
-\r
- rsc_a->SetZoneId(zone_b);\r
- rsc_b->SetZoneId(zone_a);\r
-\r
- rms_resource_internal_state_e state_a = (rms_resource_internal_state_e) rsc_a->GetState();\r
- rms_resource_internal_state_e state_b = (rms_resource_internal_state_e) rsc_b->GetState();\r
- rsc_a->ChangeState(state_b);\r
- rsc_b->ChangeState(state_a);\r
-\r
- UpdateConsumerInfoOfResource(rsc_a, consumers_b, id_b);\r
- UpdateConsumerInfoOfResource(rsc_b, consumers_a, id_a);\r
-\r
- // update resource info of each consumer\r
- SwapResource(consumers_a, rsc_a->GetDeviceID(), rsc_b->GetDeviceID());\r
- SwapResource(consumers_b, rsc_b->GetDeviceID(), rsc_a->GetDeviceID());\r
-\r
- // update memcluster owners\r
- CDependencyController::getInstance()->SwapConsumers(rsc_a->GetDeviceID(), consumers_a, rsc_b->GetDeviceID(), consumers_b);\r
-\r
- // update virtual scaler table\r
- InsertVirtualScaler(id_a, rsc_b);\r
- InsertVirtualScaler(id_b, rsc_a);\r
- return 0;\r
-}\r
-\r
-void CResourceDB::UpdateConsumerInfoOfResource(CResource *resource, std::set<int> new_consumers, int new_virtual_id)\r
-{\r
- resource->ResetConsumer(new_consumers);\r
- resource->SetVirtualDeviceId(new_virtual_id);\r
-}\r
-\r
-void CResourceDB::SwapResource(std::set<int> consumers, int cur_device_id, int new_device_id)\r
-{\r
- CConsumer *consumer;\r
- for (auto &it : consumers) {\r
- consumer = CConsumerContainer::getInstance()->findConsumer(it);\r
- if (!consumer) {\r
- SERVER_ERR("invalid consumer (%d)", it);\r
- continue;\r
- }\r
-\r
- SERVER_INFO("swap resource (%d) :(%d>%d)", it, cur_device_id, new_device_id);\r
-\r
- if (consumer->IsUsingResource(new_device_id)) {\r
- SERVER_INFO("no need to swap (%d:%d)", it, new_device_id);\r
- continue;\r
- }\r
- consumer->ReleaseResource(cur_device_id);\r
- consumer->AddResource(new_device_id);\r
- }\r
-}\r
-\r
-void CResourceDB::InsertResourceHasZoneId(CResource *rsc)\r
-{\r
- int device_id = rsc->GetDeviceID();\r
- auto it = m_rscs_has_zone_id.find(device_id);\r
-\r
- if (it != m_rscs_has_zone_id.end())\r
- return;\r
-\r
- m_rscs_has_zone_id.insert(std::pair<int, CResource*>(device_id, rsc));\r
- SERVER_INFO("inserted (%d:%d:%zu)", device_id, rsc->GetZoneId(), m_rscs_has_zone_id.size());\r
-}\r
-\r
-void CResourceDB::RemoveResourceHasZoneId(int device_id)\r
-{\r
- if (m_rscs_has_zone_id.empty())\r
- return;\r
-\r
- auto it = m_rscs_has_zone_id.find(device_id);\r
- if (it != m_rscs_has_zone_id.end())\r
- return;\r
-\r
- m_rscs_has_zone_id.erase(device_id);\r
- SERVER_INFO("removed (%d:%zu)", device_id, m_rscs_has_zone_id.size());\r
-}\r
-\r
-void CResourceDB::ResetZoneIds(void)\r
-{\r
- CResource *rsc = nullptr;\r
- SERVER_INFO("Reset zone ids");\r
-\r
- for (auto &it : m_rscs_has_zone_id) {\r
- rsc = it.second;\r
- if (!rsc)\r
- continue;\r
- rsc->SetZoneId(-1);\r
- }\r
- m_rscs_has_zone_id.clear();\r
-}\r
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <iostream>
+#include <assert.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <ri-module-api.h>
+#include <vconf.h>
+
+#include <rms_debug.h>
+#include <rms_type.h>
+
+#include <CDebugUtils.h>
+#include <CAudioCodecCollection.h>
+#include <CBandwidth.h>
+#include <CVirtualResource.h>
+#include <CConsumer.h>
+#include <CConsumerContainer.h>
+#include <CDependencyController.h>
+#include <CResourceDB.h>
+#include <CVideoController.h>
+#include <CResourceState.h>
+
+CResourceDB *CResourceDB::m_instance = NULL;
+
+CResourceDB *CResourceDB::getInstance(void)
+{
+ if (!m_instance) {
+ m_instance = new(std::nothrow) CResourceDB;
+ assert(m_instance);
+ }
+
+ return m_instance;
+}
+
+CResourceCategory *CResourceDB::FindResourceCategory(IN rms_rsc_category_e category_id)
+{
+ std::map<rms_rsc_category_e, CResourceCategory*>::iterator it = m_resourceCategoryMap.find(category_id);
+
+ if (it == m_resourceCategoryMap.end())
+ return NULL;
+
+ return (*it).second;
+}
+
+CResource *CResourceDB::FindResource(IN const int device_id)
+{
+ std::map<int, CResource*>::iterator it = m_deviceid_to_rsc.find(device_id);
+
+ if (it == m_deviceid_to_rsc.end()) {
+ SERVER_ERR("no device id(%d) in DB", device_id);
+ return NULL;
+ }
+
+ return (*it).second;
+}
+
+CVirtualResource *CResourceDB::FindVirtualResource(const int vid)
+{
+ auto it = m_v_deviceid_to_rsc.find(vid);
+
+ return (it == m_v_deviceid_to_rsc.end()) ? nullptr : it->second;
+}
+
+void CResourceDB::AddVirtualDeviceID(IN CVirtualResource *vresource)
+{
+ int vrsc_id = vresource->GetVResourceID();
+
+ std::map<int, CVirtualResource *>::iterator it = m_v_deviceid_to_rsc.find(vrsc_id);
+
+ if (it != m_v_deviceid_to_rsc.end())
+ return;
+
+ m_v_deviceid_to_rsc.insert(std::pair<int, CVirtualResource *>(vrsc_id, vresource));
+}
+
+void CResourceDB::AddDeviceID(IN int device_id, IN CResource *resource)
+{
+ std::map<int, CResource*>::iterator it = m_deviceid_to_rsc.find(device_id);
+
+ if (it != m_deviceid_to_rsc.end())
+ return;
+
+ m_deviceid_to_rsc.insert(std::pair<int, CResource*>(device_id, resource));
+}
+
+void CResourceDB::AddDeviceName(IN const char *device_name, IN CResource *resource)
+{
+ auto it = m_devicename_to_rsc.find(std::string(device_name));
+
+ if (it != m_devicename_to_rsc.end()) {
+ SERVER_DBG("already registered device name(%s) in DB", device_name);
+ return;
+ }
+
+ m_devicename_to_rsc.insert(std::pair<std::string, CResource*>(std::string(device_name), resource));
+}
+
+void CResourceDB::AddResourceCategory(IN rms_rsc_category_e category_id, IN CResourceCategory *resource_category)
+{
+ std::map<rms_rsc_category_e, CResourceCategory*>::iterator it = m_resourceCategoryMap.find(category_id);
+
+ if (it != m_resourceCategoryMap.end())
+ return;
+
+ m_resourceCategoryMap.insert(std::pair<rms_rsc_category_e, CResourceCategory*>(category_id, resource_category));
+}
+
+CResource *CResourceDB::FindResource(const char *device_name)
+{
+ auto it = m_devicename_to_rsc.find(std::string(device_name));
+
+ return (it == m_devicename_to_rsc.end()) ? NULL : it->second;
+}
+
+void CResourceDB::AddVirtualResource(IN CVirtualResource *vrsc,
+ IN rms_rsc_category_e resource_category_id,
+ IN const char *name,
+ IN const char *path,
+ IN std::set<unsigned int> mem_cluster_info,
+ IN unsigned int device_id_unique,
+ IN int is_main_device,
+ IN const char *audio_codec,
+ IN int sharable_count,
+ IN int mixing_count,
+ IN CResourceObserver *observer)
+{
+ assert(name);
+ assert(path);
+
+ CResource *rsc = FindResource(name);
+
+ if (!rsc) {
+ rsc = new CResource(device_id_unique, resource_category_id, name, path, mem_cluster_info, is_main_device, audio_codec, sharable_count);
+
+ AddDeviceName(name, rsc);
+ AddDeviceID(device_id_unique, rsc);
+
+ rsc->RegisterObserver(this);
+ rsc->RegisterObserver(observer);
+ }
+
+ vrsc->SetResource(rsc);
+
+ CAudioCodecCollection::getInstance()->registerAudioCodec(audio_codec, mixing_count);
+
+ if (rsc->GetDefaultBW() == 0)
+ rsc->SetDefaultBW(vrsc->GetBW());
+
+ AddVirtualDeviceID(vrsc);
+}
+
+void CResourceDB::UpdateBWbyRelease(CResource *rsc)
+{
+ if (!rsc)
+ return;
+
+ if (rsc->GetBW() == 0)
+ return;
+
+ CBandwidth *bw = CBandwidth::GetInstance();
+ bw->RemoveConsumer(rsc->GetDeviceID(), rsc->GetCurCategory(), rsc->GetCategoryClass());
+ bw->Increase(rsc->GetBW(), rsc->GetCurCategory(), rsc->GetCategoryClass(), rsc->GetDeviceID());
+
+ return;
+}
+
+void CResourceDB::UpdateByRelease(CResource *resource, const int device_id, const int consumer_id)
+{
+ UpdateBWbyRelease(resource);
+
+ if (resource->IsVideoDecoder())
+ RemoveActiveVideoDecoder(device_id, resource->GetCategoryClass());
+
+ if (resource->IsJpegDecoder())
+ RemoveActiveJpegDecoder(device_id);
+
+ RemoveResourceHasZoneId(resource->GetDeviceID());
+}
+
+void CResourceDB::UpdateBWbyAllocation(const unsigned int bandwidth, CResource *rsc)
+{
+ CBandwidth *bw = CBandwidth::GetInstance();
+ bw->Decrease(bandwidth, rsc->GetCurCategory(), rsc->GetCategoryClass(), rsc->GetDeviceID());
+
+ //SERVER_INFO("bw updated avail(%d)/max(%d)", bw->GetAvail(), bw->GetMax());
+}
+
+void CResourceDB::UpdateByAllocation(CResource *resource, const int device_id, const int consumer_id)
+{
+ unsigned int bw = resource->GetBW();
+
+ if (bw > 0) {
+ UpdateBWbyAllocation(bw, resource);
+ CBandwidth::GetInstance()->AddConsumer(device_id, consumer_id, resource->GetCurCategory(), resource->GetCategoryClass());
+ }
+
+ if (resource->IsVideoDecoder())
+ AddActiveVideoDecoder(device_id, consumer_id, resource->GetCategoryClass());
+
+ if (resource->IsScaler())
+ SetVirtualScalerId(resource);
+
+ if (resource->IsJpegDecoder())
+ AddActiveJpegDecoder(device_id, consumer_id);
+
+ if (resource->GetZoneId() > 0)
+ InsertResourceHasZoneId(resource);
+}
+
+void CResourceDB::SetVirtualScalerId(CResource *resource)
+{
+ int scaler_id = GetVirtualScalerId(resource);
+
+ SERVER_INFO("map scaler (%d:%d)", scaler_id, resource->GetDeviceID());
+
+ resource->SetVirtualDeviceId(scaler_id);
+ InsertVirtualScaler(scaler_id, resource);
+}
+
+void CResourceDB::PrintVirtualScalerMap(void)
+{
+ for (auto &it : m_scaler_map) {
+ if (it.second == nullptr) {
+ //SERVER_INFO("[%d : %d (%s)]", it.first, 0, "null");
+ continue;
+ }
+ //SERVER_INFO("[%d : %d (%s)/(%d)]", it.first, it.second->GetDeviceID(), it.second->GetName().c_str(), it.second->GetVirtualDeviceId());
+ }
+}
+
+int CResourceDB::GetVirtualScalerId(CResource *resource)
+{
+ CResource *rsc = nullptr;
+
+ for (auto &it : m_scaler_map) {
+ rsc = it.second;
+ if (rsc == nullptr)
+ continue;
+ if (rsc->GetDeviceID() == resource->GetDeviceID())
+ return it.first;
+ }
+
+ return resource->GetDedicatedVirtualDeviceId();
+}
+
+void CResourceDB::AddActiveVideoDecoder(const int device_id, const int consumer_id, const int category_class)
+{
+ m_active_vdecs.insert(std::pair<int, int>(device_id, consumer_id));
+
+ if (category_class == RMS_CATEGORY_CLASS_N_DECODING)
+ m_active_nvdecs.insert(std::pair<int, int>(device_id, consumer_id));
+}
+
+void CResourceDB::RemoveActiveVideoDecoder(const int device_id, const int category_class)
+{
+ m_active_vdecs.erase(device_id);
+
+ if (category_class == RMS_CATEGORY_CLASS_N_DECODING)
+ m_active_nvdecs.erase(device_id);
+}
+
+void CResourceDB::AddActiveJpegDecoder(const int device_id, const int consumer_id)
+{
+ m_active_jdecs.insert(std::pair<int, int>(device_id, consumer_id));
+}
+
+void CResourceDB::RemoveActiveJpegDecoder(const int device_id)
+{
+ m_active_jdecs.erase(device_id);
+}
+
+int CResourceDB::GetActiveDecoderNum(void)
+{
+ int num = 0;
+
+ num += m_active_vdecs.size();
+ num += m_active_jdecs.size();
+
+ return num;
+}
+
+void CResourceDB::PrintVideoDecoderConsumers(void)
+{
+ for (auto const &it : m_active_vdecs) {
+ SERVER_INFO("dev(%d) by (%d)", it.first, it.second);
+ }
+}
+
+bool CResourceDB::HasAvailableDecoder(void)
+{
+ int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;
+ int active_vdecs = m_active_vdecs.size();
+ int active_ndecs = m_active_nvdecs.size();
+
+ SERVER_INFO("active(%d) / n_dec(%d) / max(%d / %d)", active_vdecs, active_ndecs, max_vdecs, m_max_vdecs);
+
+ if (active_ndecs > 0)
+ active_vdecs = active_vdecs + (1 - active_ndecs);
+
+ if (active_vdecs >= max_vdecs)
+ PrintVideoDecoderConsumers();
+
+ return (active_vdecs < max_vdecs);
+}
+
+bool CResourceDB::HasAvailableDecoderNDecoding(void)
+{
+ int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;
+ int active_vdecs = m_active_vdecs.size();
+ int active_ndecs = m_active_nvdecs.size();
+
+ SERVER_INFO("active(%d) / n_dec(%d) / max(%d %d)", active_vdecs, active_ndecs, max_vdecs, m_max_vdecs);
+
+ if (active_ndecs > 0) {
+ active_vdecs = active_vdecs + (1 - active_ndecs);
+ return true;
+ }
+
+ if (active_vdecs >= max_vdecs)
+ PrintVideoDecoderConsumers();
+
+ return (active_vdecs < max_vdecs);
+}
+
+bool CResourceDB::HasAvailableDecoder(std::multimap<int, int> retirables)
+{
+ int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;
+ std::map<int, int> retirables_vdecs;
+
+ SERVER_INFO("max(%d %d)", max_vdecs, m_max_vdecs);
+
+ for (auto &it : retirables) {
+ CResource *rsc = FindResource(it.first);
+ if (!rsc)
+ continue;
+
+ if (rsc->IsVideoDecoder())
+ retirables_vdecs.insert(std::pair<int, int>(it.first, it.second));
+ }
+
+ int active_vdecs = m_active_vdecs.size();
+ int active_ndecs = m_active_nvdecs.size();
+ int retirable_vdecs = retirables_vdecs.size();
+ int retirable_ndecs = CountNDecoders(retirables_vdecs);
+
+ int remain = 0;
+
+ if ((active_ndecs - retirable_ndecs) > 0)
+ remain = (active_vdecs - retirable_vdecs) + (1 - (active_ndecs - retirable_ndecs));
+ else
+ remain = active_vdecs - retirable_vdecs;
+
+ SERVER_INFO("remain(%d)/max(%d), av(%d)/an(%d)/rv(%d)/rn(%d)", remain, max_vdecs, active_vdecs, active_ndecs, retirable_vdecs, retirable_ndecs);
+
+ if (remain >= max_vdecs)
+ PrintVideoDecoderConsumers();
+
+ return (remain < max_vdecs);
+}
+
+bool CResourceDB::HasAvailableDecoderNDecoding(std::multimap<int, int> retirables)
+{
+ int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;
+ std::map<int, int> retirables_vdecs;
+
+ SERVER_INFO("max(%d %d)", max_vdecs, m_max_vdecs);
+
+ for (auto &it : retirables) {
+ CResource *rsc = FindResource(it.first);
+ if (!rsc)
+ continue;
+
+ if (rsc->IsVideoDecoder())
+ retirables_vdecs.insert(std::pair<int, int>(it.first, it.second));
+ }
+
+ int active_vdecs = m_active_vdecs.size();
+ int active_ndecs = m_active_nvdecs.size();
+ int retirable_vdecs = retirables_vdecs.size();
+ int retirable_ndecs = CountNDecoders(retirables_vdecs);
+
+ int remain = 0;
+
+ if ((active_ndecs - retirable_ndecs) > 0)
+ remain = (active_vdecs - retirable_vdecs) + (1 - (active_ndecs - retirable_ndecs));
+ else
+ remain = active_vdecs - retirable_vdecs;
+
+ SERVER_INFO("remain(%d)/max(%d), av(%d)/an(%d)/rv(%d)/rn(%d)", remain, max_vdecs, active_vdecs, active_ndecs, retirable_vdecs, retirable_ndecs);
+
+ if (active_ndecs > 0 && retirable_ndecs > 0)
+ return true;
+
+ if (remain >= max_vdecs)
+ PrintVideoDecoderConsumers();
+
+ return (remain < max_vdecs);
+}
+
+int CResourceDB::CountNDecoders(std::map<int, int> retirables_vdecs)
+{
+ int ndecs = 0;
+ for (auto &it_rsc : retirables_vdecs) {
+ auto it_ndec = m_active_nvdecs.find(it_rsc.first);
+
+ if (it_ndec != m_active_nvdecs.end())
+ ndecs++;
+ }
+
+ SERVER_INFO("ndecs(%d) in retirables(%zu)", ndecs, retirables_vdecs.size());
+ return ndecs;
+}
+
+void CResourceDB::Update(resource_update_type_e type, const int device_id, const int consumer_id)
+{
+ CResource *resource = FindResource(device_id);
+
+ if (!resource)
+ return;
+
+ switch (type) {
+ case UPDATED_BY_ALLOC:
+ SERVER_WARN("UPDATED_BY_ALLOC");
+ UpdateByAllocation(resource, device_id, consumer_id);
+ break;
+ case UPDATED_BY_RELEASE:
+ SERVER_WARN("UPDATED_BY_RELEASE");
+ UpdateByRelease(resource, device_id, consumer_id);
+ break;
+ default:
+ SERVER_ERR("unexpected update type (%d)", type);
+ break;
+ }
+
+ NotifyResourceStateUpdatedAsync(resource, consumer_id);
+}
+
+void CResourceDB::AddReclaimResources(consumer_reclaim_s *consumers)
+{
+ for (int i = 0; i < consumers->ret_quantity; i++) {
+ for (int j = 0; j < consumers->consumer_info[i].n_conflicted; j++) {
+ SERVER_INFO("add reclaim rsc (%d)", consumers->consumer_info[i].conflicted_resources[j].device_id);
+ m_reclaim_rscs.insert(consumers->consumer_info[i].conflicted_resources[j].device_id);
+ }
+ }
+}
+
+void CResourceDB::ClearReclaimResources(void)
+{
+ m_reclaim_rscs.clear();
+}
+
+gboolean CResourceDB::NotifyResourceStateUpdated(gpointer data)
+{
+ if (!data) {
+ SERVER_ERR("invalid data");
+ return G_SOURCE_REMOVE;
+ }
+
+ CResourceState *state = (CResourceState*) data;
+
+ GError *error = NULL;
+ GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+
+ if (!connection) {
+ SERVER_ERR("failed to get connection (%s)", (error) ? error->message : "unknown");
+ goto out;
+ }
+
+ SERVER_INFO("notify state changed (device id %d( type %d) : state %d)", state->GetDeviceId(), state->GetCategoryType(), state->GetState());
+
+ if (!g_dbus_connection_emit_signal(connection,
+ NULL,
+ RM_DBUS_OBJ_PATH,
+ RM_DBUS_INTERFACE_NAME,
+ "RscStateChanged",
+ g_variant_new("(iiiis)", state->GetDeviceId(), state->GetCategoryType(), state->GetState(), state->GetConsumerId(), state->GetAppId().c_str()),
+ &error))
+ SERVER_ERR("failed to send state changed (%d:%s)", state->GetDeviceId(), (error) ? error->message : "unknown");
+
+out:
+ if (error)
+ g_error_free(error);
+
+ delete state;
+ return G_SOURCE_REMOVE;
+}
+
+void CResourceDB::NotifyResourceStateUpdatedAsync(CResource *resource, int consumer_id)
+{
+ int device_id = resource->GetDeviceID();
+ CConsumer *consumer = CConsumerContainer::getInstance()->findConsumer(consumer_id);
+
+ if (!consumer) {
+ SERVER_WARN("Consumer %d is not found", consumer_id);
+ return;
+ }
+
+ std::string app_id = consumer->GetAppID();
+
+ if (app_id.empty())
+ app_id = consumer->GetCmdName();
+
+ SERVER_INFO("device id (%d) consumer id (%d)", device_id, consumer_id);
+
+ if (m_reclaim_rscs.find(device_id) != m_reclaim_rscs.end()) {
+ SERVER_DBG("skip to notify state updated (%d)", device_id);
+ return;
+ }
+
+ CResourceState *state = new CResourceState(resource->GetDeviceID(), resource->GetCategoryType(), consumer_id, resource->GetState(), app_id);
+ g_idle_add(&CResourceDB::NotifyResourceStateUpdated, state);
+}
+
+CResource *CResourceDB::FindMainResource(rms_rsc_category_e category_id)
+{
+ CResourceCategory *category = FindResourceCategory(category_id);
+ if (!category) {
+ SERVER_ERR("category(%d) not found", category_id);
+ return NULL;
+ }
+
+ return category->FindMainResource();
+}
+
+void CResourceDB::FindMainResources(IN std::map<int, CResource*> *resource_map)
+{
+ rms_rsc_category_e categories[5] = {RMS_CATEGORY_VIDEO_DECODER,
+ RMS_CATEGORY_VIDEO_DECODER_UHD,
+ RMS_CATEGORY_SCALER,
+ RMS_CATEGORY_AUDIO_DECODER,
+ RMS_CATEGORY_AUDIO_MAIN_OUT};
+ CResource *resource = NULL;
+
+ for (int i = 0; i < 5; i++) {
+ resource = FindMainResource(categories[i]);
+ if (!resource) {
+ SERVER_INFO("no main resource for (%d)", categories[i]);
+ continue;
+ }
+
+ resource_map->insert(std::pair<int, CResource*>(resource->GetDeviceID(), resource));
+ }
+}
+
+void CResourceDB::FindActiveVideoDecoders(IN std::map<int, CResource*> *resource_map)
+{
+ CResource *rsc = nullptr;
+ for (auto const &it : m_active_vdecs) {
+ rsc = FindResource(it.first);
+ if (!rsc)
+ continue;
+ resource_map->insert(std::pair<int, CResource*>(it.first, rsc));
+ }
+}
+
+void CResourceDB::GetScalerList(std::map<int, CResource*> *scalers)
+{
+ CResource *rsc = nullptr;
+ for (auto &it : m_deviceid_to_rsc) {
+ rsc = it.second;
+ if (!rsc->IsScaler())
+ continue;
+
+ scalers->insert(std::pair<int, CResource*>(rsc->GetDeviceID(), rsc));
+ }
+}
+
+void CResourceDB::InitScalerTable(void)
+{
+ CResource *rsc = nullptr;
+ int sub_scaler_count = 0;
+ int vid = 0;
+
+ std::map<int, CResource*> scalers;
+ GetScalerList(&scalers);
+
+ for (auto &it : scalers) {
+ rsc = it.second;
+
+ if (!rsc->IsMainDevice())
+ sub_scaler_count++;
+
+ vid = (rsc->IsMainDevice()) ? RI_VIRTUAL_ID_SCALER : (RI_VIRTUAL_ID_SCALER + sub_scaler_count);
+ rsc->SetDedicatedVirtualDeviceId(vid);
+ rsc->SetVirtualDeviceId(vid);
+ //SERVER_INFO("insert scaler (%d:%d)", vid, rsc->GetDeviceID());
+ m_scaler_map.insert(std::pair<int, CResource*>(vid, rsc));
+ }
+}
+
+int CResourceDB::FindRealDeviceId(int virtual_id)
+{
+ auto it = m_scaler_map.find(virtual_id);
+
+ if (it == m_scaler_map.end())
+ return virtual_id;
+
+ CResource *rsc = it->second;
+
+ return (rsc == nullptr) ? virtual_id : rsc->GetDeviceID();
+}
+
+CResource *CResourceDB::FindScaler(int virtual_id)
+{
+ auto it = m_scaler_map.find(virtual_id);
+ if (it == m_scaler_map.end())
+ return nullptr;
+
+ return it->second;
+}
+
+int CResourceDB::ToScalerId(int device_id)
+{
+ const int SCALER_ID_MAIN = 0;
+ const int SCALER_ID_SUB = 1;
+ const int SCALER_ID_SUB2 = 2;
+ const int SCALER_ID_SUB3 = 3;
+ const int SCALER_ID_UNKNOWN = 99;
+ int source_id = SCALER_ID_UNKNOWN;
+
+ switch (device_id) {
+ case RMS_DEVICE_SCALER:
+ source_id = SCALER_ID_MAIN;
+ break;
+ case RMS_DEVICE_SCALER_SUB:
+ source_id = SCALER_ID_SUB;
+ break;
+ case RMS_DEVICE_SCALER_SUB2:
+ source_id = SCALER_ID_SUB2;
+ break;
+ case RMS_DEVICE_SCALER_SUB3:
+ source_id = SCALER_ID_SUB3;
+ break;
+ default:
+ SERVER_ERR("unexpected device_id(%d)", device_id);
+ break;
+ }
+
+ return source_id;
+}
+
+void CResourceDB::UpdateVirtualScalerIds(void)
+{
+ std::map<int, int> scaler_map;
+ for (auto &it : m_scaler_map) {
+ if (it.second == nullptr) {
+ SERVER_INFO("[%d : %d (%s)]", it.first, 0, "null");
+ continue;
+ }
+
+ scaler_map.insert(std::pair<int, int>(it.first, ToScalerId(it.second->GetDeviceID())));
+ SERVER_INFO("[%d : %d (%s)/(%d)]", it.first, it.second->GetDeviceID(), it.second->GetName().c_str(), it.second->GetVirtualDeviceId());
+ }
+
+ CVideoController::GetInstance()->UpdateVirtualScalerIds(scaler_map);
+}
+
+void CResourceDB::InsertVirtualScaler(int virtual_id, CResource *resource)
+{
+ m_scaler_map.erase(virtual_id);
+ m_scaler_map.insert(std::pair<int, CResource*>(virtual_id, resource));
+ PrintVirtualScalerMap();
+}
+
+int CResourceDB::SwapScaler(int id_a, int id_b)
+{
+ CResource *rsc_a = FindScaler(id_a);
+ CResource *rsc_b = FindScaler(id_b);
+
+ SERVER_INFO("scaler swap (%d <-> %d)", id_a, id_b);
+
+ if (!rsc_a || !rsc_b) {
+ SERVER_ERR("invalid scaler id_a(%d)/id_b(%d)", id_a, id_b);
+ return -1;
+ }
+
+ std::set<int> consumers_a = rsc_a->GetConsumers();
+ std::set<int> consumers_b = rsc_b->GetConsumers();
+
+ int zone_a = rsc_a->GetZoneId();
+ int zone_b = rsc_b->GetZoneId();
+
+ rsc_a->SetZoneId(zone_b);
+ rsc_b->SetZoneId(zone_a);
+
+ rms_resource_internal_state_e state_a = (rms_resource_internal_state_e) rsc_a->GetState();
+ rms_resource_internal_state_e state_b = (rms_resource_internal_state_e) rsc_b->GetState();
+ rsc_a->ChangeState(state_b);
+ rsc_b->ChangeState(state_a);
+
+ UpdateConsumerInfoOfResource(rsc_a, consumers_b, id_b);
+ UpdateConsumerInfoOfResource(rsc_b, consumers_a, id_a);
+
+ // update resource info of each consumer
+ SwapResource(consumers_a, rsc_a->GetDeviceID(), rsc_b->GetDeviceID());
+ SwapResource(consumers_b, rsc_b->GetDeviceID(), rsc_a->GetDeviceID());
+
+ // update memcluster owners
+ CDependencyController::getInstance()->SwapConsumers(rsc_a->GetDeviceID(), consumers_a, rsc_b->GetDeviceID(), consumers_b);
+
+ // update virtual scaler table
+ InsertVirtualScaler(id_a, rsc_b);
+ InsertVirtualScaler(id_b, rsc_a);
+ return 0;
+}
+
+void CResourceDB::UpdateConsumerInfoOfResource(CResource *resource, std::set<int> new_consumers, int new_virtual_id)
+{
+ resource->ResetConsumer(new_consumers);
+ resource->SetVirtualDeviceId(new_virtual_id);
+}
+
+void CResourceDB::SwapResource(std::set<int> consumers, int cur_device_id, int new_device_id)
+{
+ CConsumer *consumer;
+ for (auto &it : consumers) {
+ consumer = CConsumerContainer::getInstance()->findConsumer(it);
+ if (!consumer) {
+ SERVER_ERR("invalid consumer (%d)", it);
+ continue;
+ }
+
+ SERVER_INFO("swap resource (%d) :(%d>%d)", it, cur_device_id, new_device_id);
+
+ if (consumer->IsUsingResource(new_device_id)) {
+ SERVER_INFO("no need to swap (%d:%d)", it, new_device_id);
+ continue;
+ }
+ consumer->ReleaseResource(cur_device_id);
+ consumer->AddResource(new_device_id);
+ }
+}
+
+void CResourceDB::InsertResourceHasZoneId(CResource *rsc)
+{
+ int device_id = rsc->GetDeviceID();
+ auto it = m_rscs_has_zone_id.find(device_id);
+
+ if (it != m_rscs_has_zone_id.end())
+ return;
+
+ m_rscs_has_zone_id.insert(std::pair<int, CResource*>(device_id, rsc));
+ SERVER_INFO("inserted (%d:%d:%zu)", device_id, rsc->GetZoneId(), m_rscs_has_zone_id.size());
+}
+
+void CResourceDB::RemoveResourceHasZoneId(int device_id)
+{
+ if (m_rscs_has_zone_id.empty())
+ return;
+
+ auto it = m_rscs_has_zone_id.find(device_id);
+ if (it != m_rscs_has_zone_id.end())
+ return;
+
+ m_rscs_has_zone_id.erase(device_id);
+ SERVER_INFO("removed (%d:%zu)", device_id, m_rscs_has_zone_id.size());
+}
+
+void CResourceDB::ResetZoneIds(void)
+{
+ CResource *rsc = nullptr;
+ SERVER_INFO("Reset zone ids");
+
+ for (auto &it : m_rscs_has_zone_id) {
+ rsc = it.second;
+ if (!rsc)
+ continue;
+ rsc->SetZoneId(-1);
+ }
+ m_rscs_has_zone_id.clear();
+}
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <new>\r
-#include <assert.h>\r
-#include <unistd.h>\r
-#include <trace.h>\r
-#include <rms_debug.h>\r
-#include <CVideoController.h>\r
-\r
-#define LWIPC_WM_READY "/tmp/.wm_ready"\r
-#define LWIPC_TIMEOUT_MS 10000\r
-#define LWIPC_SWAP_DONE "/tmp/.scaler_swap_done"\r
-#define LWIPC_SWAP_DONE_TIMEOUT_MS 3000\r
-#define LWIPC_SWAP_DONE_TIMEOUT_DBG_MS 4000\r
-#define RMS_IS_DEBUG_IMAGE (access("/etc/debug", F_OK) == 0)\r
-\r
-CVideoController *CVideoController::m_instance = nullptr;\r
-\r
-static void registry_handle_global(void *data, struct wl_registry *wl_registry, uint32_t id, const char *interface, uint32_t version)\r
-{\r
- void **tizen_video_rsc = (void**)data;\r
-\r
- if (strncmp(interface, "tizen_video_rsc", sizeof("tizen_video_rsc")))\r
- return;\r
-\r
- SERVER_INFO("%p : %s", tizen_video_rsc, interface);\r
- //*tizen_video_rsc = wl_registry_bind(wl_registry, id, &tizen_video_rsc_interface, 1);\r
-}\r
-\r
-static void registry_handle_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name)\r
-{\r
-\r
-}\r
-\r
-void CVideoController::WaylandDisplayCreate(void)\r
-{\r
- SERVER_INFO("Create Start");\r
-\r
- SERVER_INFO("%s is created", LWIPC_WM_READY);\r
- m_wl_display = wl_display_connect(nullptr);\r
-\r
- if (!m_wl_display) {\r
- SERVER_ERR("Failed to connect to the wayland display");\r
- return;\r
- }\r
-\r
- m_wl_registry = wl_display_get_registry(m_wl_display);\r
- wl_registry_add_listener(m_wl_registry, &m_registry_listener, &m_tizen_video_rsc);\r
- SERVER_INFO("Add listener : %p", &m_tizen_video_rsc);\r
-\r
- wl_display_roundtrip(m_wl_display);\r
-\r
- if (!m_tizen_video_rsc)\r
- SERVER_ERR("Failed to get tizen_video_rsc");\r
-\r
- SERVER_INFO("Create Done");\r
-}\r
-\r
-void CVideoController::WaylandDisplayDestroy(void)\r
-{\r
- if (m_tizen_video_rsc) {\r
- //tizen_video_rsc_destroy(m_tizen_video_rsc);\r
- m_tizen_video_rsc = nullptr;\r
- }\r
-\r
- if (m_wl_registry) {\r
- wl_registry_destroy(m_wl_registry);\r
- m_wl_registry = nullptr;\r
- }\r
-\r
- SERVER_INFO("Display disconnect");\r
-\r
- if (m_wl_display) {\r
- wl_display_roundtrip(m_wl_display);\r
- wl_display_disconnect(m_wl_display);\r
- m_wl_display = nullptr;\r
- }\r
-\r
- SERVER_INFO("Destroy Done");\r
-}\r
-\r
-CVideoController::CVideoController(void) : m_wl_display(nullptr), m_wl_registry(nullptr), m_tizen_video_rsc(nullptr), m_waiting_thread(nullptr)\r
-{\r
- m_registry_listener.global = registry_handle_global;\r
- m_registry_listener.global_remove = registry_handle_global_remove;\r
- WaylandDisplayCreate();\r
- m_lock_ctr = CLockController::GetInstance();\r
-\r
- SERVER_INFO("Initialize Done");\r
-}\r
-\r
-CVideoController::~CVideoController(void)\r
-{\r
- WaylandDisplayDestroy();\r
- SERVER_INFO("Finalize Done");\r
-}\r
-\r
-CVideoController *CVideoController::GetInstance(void)\r
-{\r
- if (m_instance == nullptr)\r
- {\r
- m_instance = new(std::nothrow) CVideoController();\r
- assert(m_instance);\r
- }\r
-\r
- return m_instance;\r
-}\r
-\r
-void CVideoController::UpdateVirtualScalerIds(std::map<int, int> scaler_id_map)\r
-{\r
- struct wl_array mapping_list;\r
- scaler_id_pair_t *scaler_id_pair = NULL;\r
-\r
- wl_array_init(&mapping_list);\r
- SERVER_ERR("Update virtual scaler ids");\r
-\r
- for (auto it = scaler_id_map.begin(); it != scaler_id_map.end(); it++) {\r
- scaler_id_pair = (scaler_id_pair_t*)wl_array_add(&mapping_list, sizeof(scaler_id_pair_t));\r
- scaler_id_pair->virtual_scaler_id = it->first;\r
- scaler_id_pair->scaler_id = it->second;\r
- SERVER_ERR("scaler(%d:%d)", it->first, it->second);\r
- }\r
-\r
- //tizen_video_rsc_map_scaler_id(m_tizen_video_rsc, &mapping_list);\r
-\r
- wl_display_roundtrip(m_wl_display);\r
- wl_array_release(&mapping_list);\r
-\r
- RunWaitingThread();\r
-}\r
-\r
-gpointer CVideoController::WaitingThread(gpointer data)\r
-{\r
- assert(data);\r
- CVideoController *ctr = (CVideoController*) data;\r
-\r
- ctr->m_lock_ctr->Unlock(ResourceType::VIDEO_SCALER);\r
- ctr->m_waiting_thread = nullptr;\r
- return 0;\r
-}\r
-\r
-void CVideoController::RunWaitingThread(void)\r
-{\r
- if (m_waiting_thread)\r
- {\r
- SERVER_ERR("already created");\r
- return;\r
- }\r
-\r
- m_lock_ctr->Lock(ResourceType::VIDEO_SCALER);\r
-\r
- m_waiting_thread = g_thread_new("waiting_swap_done", WaitingThread, this);\r
- if (m_waiting_thread == nullptr) {\r
- m_lock_ctr->Unlock(ResourceType::VIDEO_SCALER);\r
- SERVER_ERR("failed to create waiting_swap_done thread");\r
- return;\r
- }\r
-\r
- SERVER_ERR("waiting_swap_done thread created");\r
-}\r
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <new>
+#include <assert.h>
+#include <unistd.h>
+#include <trace.h>
+#include <rms_debug.h>
+#include <CVideoController.h>
+
+#define LWIPC_WM_READY "/tmp/.wm_ready"
+#define LWIPC_TIMEOUT_MS 10000
+#define LWIPC_SWAP_DONE "/tmp/.scaler_swap_done"
+#define LWIPC_SWAP_DONE_TIMEOUT_MS 3000
+#define LWIPC_SWAP_DONE_TIMEOUT_DBG_MS 4000
+#define RMS_IS_DEBUG_IMAGE (access("/etc/debug", F_OK) == 0)
+
+CVideoController *CVideoController::m_instance = nullptr;
+
+static void registry_handle_global(void *data, struct wl_registry *wl_registry, uint32_t id, const char *interface, uint32_t version)
+{
+ void **tizen_video_rsc = (void**)data;
+
+ if (strncmp(interface, "tizen_video_rsc", sizeof("tizen_video_rsc")))
+ return;
+
+ SERVER_INFO("%p : %s", tizen_video_rsc, interface);
+ //*tizen_video_rsc = wl_registry_bind(wl_registry, id, &tizen_video_rsc_interface, 1);
+}
+
+static void registry_handle_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name)
+{
+
+}
+
+void CVideoController::WaylandDisplayCreate(void)
+{
+ SERVER_INFO("Create Start");
+
+ SERVER_INFO("%s is created", LWIPC_WM_READY);
+ m_wl_display = wl_display_connect(nullptr);
+
+ if (!m_wl_display) {
+ SERVER_ERR("Failed to connect to the wayland display");
+ return;
+ }
+
+ m_wl_registry = wl_display_get_registry(m_wl_display);
+ wl_registry_add_listener(m_wl_registry, &m_registry_listener, &m_tizen_video_rsc);
+ SERVER_INFO("Add listener : %p", &m_tizen_video_rsc);
+
+ wl_display_roundtrip(m_wl_display);
+
+ if (!m_tizen_video_rsc)
+ SERVER_ERR("Failed to get tizen_video_rsc");
+
+ SERVER_INFO("Create Done");
+}
+
+void CVideoController::WaylandDisplayDestroy(void)
+{
+ if (m_tizen_video_rsc) {
+ //tizen_video_rsc_destroy(m_tizen_video_rsc);
+ m_tizen_video_rsc = nullptr;
+ }
+
+ if (m_wl_registry) {
+ wl_registry_destroy(m_wl_registry);
+ m_wl_registry = nullptr;
+ }
+
+ SERVER_INFO("Display disconnect");
+
+ if (m_wl_display) {
+ wl_display_roundtrip(m_wl_display);
+ wl_display_disconnect(m_wl_display);
+ m_wl_display = nullptr;
+ }
+
+ SERVER_INFO("Destroy Done");
+}
+
+CVideoController::CVideoController(void) : m_wl_display(nullptr), m_wl_registry(nullptr), m_tizen_video_rsc(nullptr), m_waiting_thread(nullptr)
+{
+ m_registry_listener.global = registry_handle_global;
+ m_registry_listener.global_remove = registry_handle_global_remove;
+ WaylandDisplayCreate();
+ m_lock_ctr = CLockController::GetInstance();
+
+ SERVER_INFO("Initialize Done");
+}
+
+CVideoController::~CVideoController(void)
+{
+ WaylandDisplayDestroy();
+ SERVER_INFO("Finalize Done");
+}
+
+CVideoController *CVideoController::GetInstance(void)
+{
+ if (m_instance == nullptr)
+ {
+ m_instance = new(std::nothrow) CVideoController();
+ assert(m_instance);
+ }
+
+ return m_instance;
+}
+
+void CVideoController::UpdateVirtualScalerIds(std::map<int, int> scaler_id_map)
+{
+ struct wl_array mapping_list;
+ scaler_id_pair_t *scaler_id_pair = NULL;
+
+ wl_array_init(&mapping_list);
+ SERVER_ERR("Update virtual scaler ids");
+
+ for (auto it = scaler_id_map.begin(); it != scaler_id_map.end(); it++) {
+ scaler_id_pair = (scaler_id_pair_t*)wl_array_add(&mapping_list, sizeof(scaler_id_pair_t));
+ scaler_id_pair->virtual_scaler_id = it->first;
+ scaler_id_pair->scaler_id = it->second;
+ SERVER_ERR("scaler(%d:%d)", it->first, it->second);
+ }
+
+ //tizen_video_rsc_map_scaler_id(m_tizen_video_rsc, &mapping_list);
+
+ wl_display_roundtrip(m_wl_display);
+ wl_array_release(&mapping_list);
+
+ RunWaitingThread();
+}
+
+gpointer CVideoController::WaitingThread(gpointer data)
+{
+ assert(data);
+ CVideoController *ctr = (CVideoController*) data;
+
+ ctr->m_lock_ctr->Unlock(ResourceType::VIDEO_SCALER);
+ ctr->m_waiting_thread = nullptr;
+ return 0;
+}
+
+void CVideoController::RunWaitingThread(void)
+{
+ if (m_waiting_thread)
+ {
+ SERVER_ERR("already created");
+ return;
+ }
+
+ m_lock_ctr->Lock(ResourceType::VIDEO_SCALER);
+
+ m_waiting_thread = g_thread_new("waiting_swap_done", WaitingThread, this);
+ if (m_waiting_thread == nullptr) {
+ m_lock_ctr->Unlock(ResourceType::VIDEO_SCALER);
+ SERVER_ERR("failed to create waiting_swap_done thread");
+ return;
+ }
+
+ SERVER_ERR("waiting_swap_done thread created");
+}
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <CVirtualResource.h>\r
-#include <rms_debug.h>\r
-#include <CResource.h>\r
-\r
-CVirtualResource::CVirtualResource(const int virtual_device_id, const rms_rsc_category_e category_type, unsigned int bw, std::set<unsigned int> dependent, bool is_main_device, const char *audio_codec, int category_class)\r
-:m_vir_rsc_id(virtual_device_id), m_category_type(category_type), m_vir_rsc_bw(bw), m_is_main_device(is_main_device), m_category_class(category_class), m_rsc()\r
-{\r
- m_mem_clusters = dependent;\r
-\r
- if (audio_codec)\r
- m_audio_codec.assign(audio_codec);\r
-}\r
-\r
-void CVirtualResource::SetResource(CResource *resource)\r
-{\r
- m_rsc = resource;\r
-}\r
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <CVirtualResource.h>
+#include <rms_debug.h>
+#include <CResource.h>
+
+CVirtualResource::CVirtualResource(const int virtual_device_id, const rms_rsc_category_e category_type, unsigned int bw, std::set<unsigned int> dependent, bool is_main_device, const char *audio_codec, int category_class)
+:m_vir_rsc_id(virtual_device_id), m_category_type(category_type), m_vir_rsc_bw(bw), m_is_main_device(is_main_device), m_category_class(category_class), m_rsc()
+{
+ m_mem_clusters = dependent;
+
+ if (audio_codec)
+ m_audio_codec.assign(audio_codec);
+}
+
+void CVirtualResource::SetResource(CResource *resource)
+{
+ m_rsc = resource;
+}