Name: rscmgr-service
Summary: Daemon for resource manager
Version: 0.1
-Release: 12
+Release: 13
Group: Multimedia/Libraries
License: Apache-2.0
Source0: %{name}-%{version}.tar.gz
snprintf(callback_path, 256, "/run/rsc_mgr/%d.%d.s2c.cb", pid, cid);
- if ((fd = open(callback_path, O_WRONLY|O_NONBLOCK)) < 0) {
+ if ((fd = open(callback_path, O_WRONLY | O_NONBLOCK)) < 0) {
SERVER_ERR("open error (%s), errno(%d)", callback_path, errno);
*err = errno;
return RMS_ERROR;
m_rsc_mgr->ReleaseResourcesOfPid(pid);
ReleaseInvalidProcessResources(pid, cid);
free(callback_data);
-
if (!IsRegisteredHandle(requester_cid)) {
SERVER_ERR("requester(%d:%d) terminated as well", pid, requester_cid);
*need_response = 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_debug.h>\r
-#include <CAudioCodec.h>\r
-\r
-CAudioCodec::CAudioCodec(const char * name)\r
-:m_ref_count(0), m_ref_count_max(0)\r
-{\r
- m_name.assign(name);\r
-}\r
-\r
-CAudioCodec::~CAudioCodec()\r
-{\r
-}\r
-\r
-void CAudioCodec::increaseRef(int device_id, int consumer_id)\r
-{\r
- if (m_ref_count_max == 0)\r
- return;\r
-\r
- if (m_ref_count >= m_ref_count_max) {\r
- SERVER_ERR("(%s) can't increase ref count (%d, %d) by %d", m_name.c_str(), m_ref_count, m_ref_count_max, consumer_id);\r
- return;\r
- }\r
-\r
- m_ref_count++;\r
-\r
- auto it = m_consumers.find(consumer_id);\r
-\r
- m_resources.insert(std::pair<int, int>(device_id, consumer_id));\r
-\r
- if (it == m_consumers.end()) {\r
- m_consumers.insert(std::pair<int, int>(consumer_id, 1));\r
- return;\r
- }\r
-\r
- (*it).second = ++it->second ;\r
-}\r
-\r
-void CAudioCodec::decreaseRef(int device_id, int consumer_id)\r
-{\r
- if (m_ref_count_max == 0)\r
- return;\r
-\r
- if (m_ref_count <= 0) {\r
- SERVER_ERR("(%s) can't decrease ref count (%d, %d) by %d", m_name.c_str(), m_ref_count, m_ref_count_max, consumer_id);\r
- return;\r
- }\r
-\r
- auto it = m_consumers.find(consumer_id);\r
-\r
- if (it == m_consumers.end()) {\r
- SERVER_ERR("not registered consumer(%d)", consumer_id);\r
- return;\r
- }\r
-\r
- m_resources.erase(device_id);\r
-\r
- m_ref_count--;\r
-\r
- if (it->second <= 1) {\r
- m_consumers.erase(consumer_id);\r
- return;\r
- }\r
-\r
- (*it).second = --it->second;\r
-}\r
-\r
-void CAudioCodec::increaseMaxRef(void)\r
-{\r
- m_ref_count_max++;\r
-}\r
-\r
-bool CAudioCodec::isAvailableToUse(void)\r
-{\r
- if (isUnknownCodec())\r
- return true;\r
-\r
- SERVER_INFO("%s > cur(%d), max(%d)", m_name.c_str(), m_ref_count, m_ref_count_max);\r
-\r
- return (m_ref_count < m_ref_count_max);\r
-}\r
-\r
-std::set<int> CAudioCodec::getResourcesOfConsumer(int consumer_id)\r
-{\r
- std::set<int> resources;\r
-\r
- for (auto const &it : m_resources) {\r
- if (it.second == consumer_id)\r
- resources.insert(it.first);\r
- }\r
-\r
- return resources;\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_debug.h>
+#include <CAudioCodec.h>
+
+CAudioCodec::CAudioCodec(const char * name)
+:m_ref_count(0), m_ref_count_max(0)
+{
+ m_name.assign(name);
+}
+
+CAudioCodec::~CAudioCodec()
+{
+}
+
+void CAudioCodec::increaseRef(int device_id, int consumer_id)
+{
+ if (m_ref_count_max == 0)
+ return;
+
+ if (m_ref_count >= m_ref_count_max) {
+ SERVER_ERR("(%s) can't increase ref count (%d, %d) by %d", m_name.c_str(), m_ref_count, m_ref_count_max, consumer_id);
+ return;
+ }
+
+ m_ref_count++;
+
+ auto it = m_consumers.find(consumer_id);
+
+ m_resources.insert(std::pair<int, int>(device_id, consumer_id));
+
+ if (it == m_consumers.end()) {
+ m_consumers.insert(std::pair<int, int>(consumer_id, 1));
+ return;
+ }
+
+ (*it).second = ++it->second ;
+}
+
+void CAudioCodec::decreaseRef(int device_id, int consumer_id)
+{
+ if (m_ref_count_max == 0)
+ return;
+
+ if (m_ref_count <= 0) {
+ SERVER_ERR("(%s) can't decrease ref count (%d, %d) by %d", m_name.c_str(), m_ref_count, m_ref_count_max, consumer_id);
+ return;
+ }
+
+ auto it = m_consumers.find(consumer_id);
+
+ if (it == m_consumers.end()) {
+ SERVER_ERR("not registered consumer(%d)", consumer_id);
+ return;
+ }
+
+ m_resources.erase(device_id);
+
+ m_ref_count--;
+
+ if (it->second <= 1) {
+ m_consumers.erase(consumer_id);
+ return;
+ }
+
+ (*it).second = --it->second;
+}
+
+void CAudioCodec::increaseMaxRef(void)
+{
+ m_ref_count_max++;
+}
+
+bool CAudioCodec::isAvailableToUse(void)
+{
+ if (isUnknownCodec())
+ return true;
+
+ SERVER_INFO("%s > cur(%d), max(%d)", m_name.c_str(), m_ref_count, m_ref_count_max);
+
+ return (m_ref_count < m_ref_count_max);
+}
+
+std::set<int> CAudioCodec::getResourcesOfConsumer(int consumer_id)
+{
+ std::set<int> resources;
+
+ for (auto const &it : m_resources) {
+ if (it.second == consumer_id)
+ resources.insert(it.first);
+ }
+
+ return resources;
+}
-/*\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
-\r
-#include <CAudioCodec.h>\r
-#include <CAudioCodecCollection.h>\r
-\r
-CAudioCodecCollection *CAudioCodecCollection::m_instance = NULL;\r
-\r
-CAudioCodecCollection::CAudioCodecCollection()\r
-{\r
-\r
-}\r
-\r
-CAudioCodecCollection *CAudioCodecCollection::getInstance(void)\r
-{\r
- if (!m_instance)\r
- m_instance = new CAudioCodecCollection();\r
-\r
- return m_instance;\r
-}\r
-\r
-CAudioCodecCollection::~CAudioCodecCollection()\r
-{\r
-}\r
-\r
-CAudioCodec *CAudioCodecCollection::findAudioCodec(std::string name)\r
-{\r
- auto it = m_audio_codecs.find(name);\r
-\r
- return (it == m_audio_codecs.end()) ? NULL : it->second;\r
-}\r
-\r
-void CAudioCodecCollection::registerAudioCodec(const char *name, int count)\r
-{\r
- if (!name)\r
- return;\r
-\r
- CAudioCodec *audio_codec = findAudioCodec(name);\r
-\r
- if (!audio_codec) {\r
- audio_codec = new CAudioCodec(name);\r
- m_audio_codecs.insert(std::pair<std::string, CAudioCodec*>(std::string(name), audio_codec));\r
- }\r
-\r
- if (count > 0)\r
- audio_codec->increaseMaxRef();\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 <CAudioCodec.h>
+#include <CAudioCodecCollection.h>
+
+CAudioCodecCollection *CAudioCodecCollection::m_instance = NULL;
+
+CAudioCodecCollection::CAudioCodecCollection()
+{
+
+}
+
+CAudioCodecCollection *CAudioCodecCollection::getInstance(void)
+{
+ if (!m_instance)
+ m_instance = new CAudioCodecCollection();
+
+ return m_instance;
+}
+
+CAudioCodecCollection::~CAudioCodecCollection()
+{
+}
+
+CAudioCodec *CAudioCodecCollection::findAudioCodec(std::string name)
+{
+ auto it = m_audio_codecs.find(name);
+
+ return (it == m_audio_codecs.end()) ? NULL : it->second;
+}
+
+void CAudioCodecCollection::registerAudioCodec(const char *name, int count)
+{
+ if (!name)
+ return;
+
+ CAudioCodec *audio_codec = findAudioCodec(name);
+
+ if (!audio_codec) {
+ audio_codec = new CAudioCodec(name);
+ m_audio_codecs.insert(std::pair<std::string, CAudioCodec*>(std::string(name), audio_codec));
+ }
+
+ if (count > 0)
+ audio_codec->increaseMaxRef();
+}
-/*\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_debug.h>\r
-#include <rms_type.h>\r
-#include <CResourceDB.h>\r
-#include <CResource.h>\r
-#include <CVirtualResource.h>\r
-#include <CBandwidth.h>\r
-\r
-CBandwidth *CBandwidth::m_instance = NULL;\r
-\r
-CBandwidth *CBandwidth::GetInstance(void)\r
-{\r
- if (!m_instance)\r
- {\r
- m_instance = new CBandwidth();\r
- }\r
-\r
- return m_instance;\r
-}\r
-\r
-void CBandwidth::AddConsumerNDec(int device_id, int consumer_id, int category_id)\r
-{\r
- auto it = m_ndec_consumers.find(category_id);\r
- if (it == m_ndec_consumers.end())\r
- {\r
- std::map<int, int> consumers;\r
- consumers.insert(std::pair<int, int>(device_id, consumer_id));\r
- m_ndec_consumers.insert(std::pair<int, std::map<int, int>>(category_id, consumers));\r
- }\r
- else\r
- {\r
- std::map<int, int> *consumers = &it->second;\r
- consumers->insert(std::pair<int, int>(device_id, consumer_id));\r
- }\r
-}\r
-\r
-void CBandwidth::RemoveConsumerNDec(int device_id, int category_id)\r
-{\r
- auto it = m_ndec_consumers.find(category_id);\r
- if (it == m_ndec_consumers.end())\r
- return;\r
-\r
- it->second.erase(device_id);\r
-}\r
-\r
-void CBandwidth::GetConsumersNDec(int category_id, std::map<int, int> *consumers)\r
-{\r
- auto it = m_ndec_consumers.find(category_id);\r
- if (it == m_ndec_consumers.end())\r
- return;\r
-\r
- consumers->insert(it->second.begin(), it->second.end());\r
-}\r
-\r
-void CBandwidth::AddConsumer(int device_id, int consumer_id, int category_id, int category_class)\r
-{\r
- m_consumers.insert(std::pair<int, int>(device_id, consumer_id));\r
-\r
- if (category_class == RMS_CATEGORY_CLASS_N_DECODING)\r
- AddConsumerNDec(device_id, consumer_id, category_id);\r
-}\r
-\r
-void CBandwidth::RemoveConsumer(int device_id, int category_id, int category_class)\r
-{\r
- auto it = m_consumers.find(device_id);\r
- if (it == m_consumers.end())\r
- return;\r
-\r
- m_consumers.erase(device_id);\r
-\r
- if (category_class == RMS_CATEGORY_CLASS_N_DECODING)\r
- RemoveConsumerNDec(device_id, category_id);\r
-}\r
-\r
-int CBandwidth::GetNConsumersNDec(int category_id)\r
-{\r
- auto it = m_ndec_consumers.find(category_id);\r
- if (it == m_ndec_consumers.end())\r
- return 0;\r
-\r
- return it->second.size();\r
-}\r
-\r
-void CBandwidth::Increase(unsigned int bw, int category_id, int category_class, int device_id)\r
-{\r
- if ((category_class == RMS_CATEGORY_CLASS_N_DECODING) && IncludeSameDeviceGroup(category_id, device_id))\r
- return;\r
-\r
- m_avail += bw;\r
- m_avail = (m_avail > m_max) ? m_max : m_avail;\r
-}\r
-\r
-void CBandwidth::Decrease(unsigned int bw, int category_id, int category_class, int device_id)\r
-{\r
- if (category_class == RMS_CATEGORY_CLASS_N_DECODING && IncludeSameDeviceGroup(category_id, device_id))\r
- return;\r
-\r
- m_avail -= bw;\r
-}\r
-\r
-bool CBandwidth::IncludeSameDeviceGroup(int category_id, int device_id)\r
-{\r
- if (GetNConsumersNDec(category_id) == 0)\r
- return false;\r
-\r
- CResource *c_rsc;\r
- CVirtualResource *c_vrsc;\r
- std::set<unsigned int> c_mc;\r
-\r
- CResourceDB *db = CResourceDB::getInstance();\r
- CResource *u_rsc = db->FindResource(device_id);\r
- CVirtualResource *u_vrsc = db->FindVirtualResource(u_rsc->GetVirtualResourceID());\r
-\r
- std::set<unsigned int> u_mc = u_vrsc->GetMemClusters();\r
-\r
- std::map<int, int> consumers; // device_id, consumer_id\r
- GetConsumersNDec(category_id, &consumers);\r
-\r
- for (auto const &it : consumers)\r
- {\r
- c_rsc = db->FindResource(it.first);\r
- c_vrsc = db->FindVirtualResource(c_rsc->GetVirtualResourceID());\r
- c_mc = c_vrsc->GetMemClusters();\r
-\r
- if (c_rsc->GetDeviceID() == u_rsc->GetDeviceID())\r
- continue;\r
-\r
- if (IsSameMemClusters(c_mc, u_mc))\r
- {\r
- SERVER_INFO("same mc (%d = %d) found", device_id, it.first);\r
- return true;\r
- }\r
- }\r
-\r
- return false;\r
-}\r
-\r
-bool CBandwidth::IsSameMemClusters(std::set<unsigned int> c_mc, std::set<unsigned int> u_mc)\r
-{\r
- if (c_mc.size() != u_mc.size())\r
- return false;\r
-\r
- for (auto const &it : u_mc)\r
- {\r
- if (c_mc.find(it) == c_mc.end())\r
- return false;\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 <rms_debug.h>
+#include <rms_type.h>
+#include <CResourceDB.h>
+#include <CResource.h>
+#include <CVirtualResource.h>
+#include <CBandwidth.h>
+
+CBandwidth *CBandwidth::m_instance = NULL;
+
+CBandwidth *CBandwidth::GetInstance(void)
+{
+ if (!m_instance)
+ {
+ m_instance = new CBandwidth();
+ }
+
+ return m_instance;
+}
+
+void CBandwidth::AddConsumerNDec(int device_id, int consumer_id, int category_id)
+{
+ auto it = m_ndec_consumers.find(category_id);
+ if (it == m_ndec_consumers.end())
+ {
+ std::map<int, int> consumers;
+ consumers.insert(std::pair<int, int>(device_id, consumer_id));
+ m_ndec_consumers.insert(std::pair<int, std::map<int, int>>(category_id, consumers));
+ }
+ else
+ {
+ std::map<int, int> *consumers = &it->second;
+ consumers->insert(std::pair<int, int>(device_id, consumer_id));
+ }
+}
+
+void CBandwidth::RemoveConsumerNDec(int device_id, int category_id)
+{
+ auto it = m_ndec_consumers.find(category_id);
+ if (it == m_ndec_consumers.end())
+ return;
+
+ it->second.erase(device_id);
+}
+
+void CBandwidth::GetConsumersNDec(int category_id, std::map<int, int> *consumers)
+{
+ auto it = m_ndec_consumers.find(category_id);
+ if (it == m_ndec_consumers.end())
+ return;
+
+ consumers->insert(it->second.begin(), it->second.end());
+}
+
+void CBandwidth::AddConsumer(int device_id, int consumer_id, int category_id, int category_class)
+{
+ m_consumers.insert(std::pair<int, int>(device_id, consumer_id));
+
+ if (category_class == RMS_CATEGORY_CLASS_N_DECODING)
+ AddConsumerNDec(device_id, consumer_id, category_id);
+}
+
+void CBandwidth::RemoveConsumer(int device_id, int category_id, int category_class)
+{
+ auto it = m_consumers.find(device_id);
+ if (it == m_consumers.end())
+ return;
+
+ m_consumers.erase(device_id);
+
+ if (category_class == RMS_CATEGORY_CLASS_N_DECODING)
+ RemoveConsumerNDec(device_id, category_id);
+}
+
+int CBandwidth::GetNConsumersNDec(int category_id)
+{
+ auto it = m_ndec_consumers.find(category_id);
+ if (it == m_ndec_consumers.end())
+ return 0;
+
+ return it->second.size();
+}
+
+void CBandwidth::Increase(unsigned int bw, int category_id, int category_class, int device_id)
+{
+ if ((category_class == RMS_CATEGORY_CLASS_N_DECODING) && IncludeSameDeviceGroup(category_id, device_id))
+ return;
+
+ m_avail += bw;
+ m_avail = (m_avail > m_max) ? m_max : m_avail;
+}
+
+void CBandwidth::Decrease(unsigned int bw, int category_id, int category_class, int device_id)
+{
+ if (category_class == RMS_CATEGORY_CLASS_N_DECODING && IncludeSameDeviceGroup(category_id, device_id))
+ return;
+
+ m_avail -= bw;
+}
+
+bool CBandwidth::IncludeSameDeviceGroup(int category_id, int device_id)
+{
+ if (GetNConsumersNDec(category_id) == 0)
+ return false;
+
+ CResource *c_rsc;
+ CVirtualResource *c_vrsc;
+ std::set<unsigned int> c_mc;
+
+ CResourceDB *db = CResourceDB::getInstance();
+ CResource *u_rsc = db->FindResource(device_id);
+ CVirtualResource *u_vrsc = db->FindVirtualResource(u_rsc->GetVirtualResourceID());
+
+ std::set<unsigned int> u_mc = u_vrsc->GetMemClusters();
+
+ std::map<int, int> consumers; // device_id, consumer_id
+ GetConsumersNDec(category_id, &consumers);
+
+ for (auto const &it : consumers)
+ {
+ c_rsc = db->FindResource(it.first);
+ c_vrsc = db->FindVirtualResource(c_rsc->GetVirtualResourceID());
+ c_mc = c_vrsc->GetMemClusters();
+
+ if (c_rsc->GetDeviceID() == u_rsc->GetDeviceID())
+ continue;
+
+ if (IsSameMemClusters(c_mc, u_mc))
+ {
+ SERVER_INFO("same mc (%d = %d) found", device_id, it.first);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool CBandwidth::IsSameMemClusters(std::set<unsigned int> c_mc, std::set<unsigned int> u_mc)
+{
+ if (c_mc.size() != u_mc.size())
+ return false;
+
+ for (auto const &it : u_mc)
+ {
+ if (c_mc.find(it) == c_mc.end())
+ return false;
+ }
+ 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 <stdio.h>\r
-\r
-#include <rms_debug.h>\r
-#include <rms_type.h>\r
-#include <CResourceDB.h>\r
-#include <CMemCluster.h>\r
-#include <CMixingMode.h>\r
-#include <CAudioCodec.h>\r
-#include <CAudioCodecCollection.h>\r
-#include <CPriority.h>\r
-#include <CResourceCategory.h>\r
-#include <CResourceObserver.h>\r
-#include <CDependencyController.h>\r
-#include <CConsumer.h>\r
-#include <CConsumerContainer.h>\r
-\r
-#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))\r
-\r
-static rms_mixing_mode_e supported_mixing_modes[] =\r
-{\r
- RMS_MIXING_MODE_DEFAULT,\r
- RMS_MIXING_MODE_MULTIVIEW,\r
- RMS_MIXING_MODE_INTERACTION_SOUND\r
-};\r
-\r
-CDependencyController *CDependencyController::m_instance = NULL;\r
-\r
-CDependencyController::CDependencyController()\r
-{\r
- registerMixingModes();\r
- m_cur_mixing_mode = NULL;\r
-}\r
-\r
-CDependencyController *CDependencyController::getInstance(void)\r
-{\r
- if (!m_instance)\r
- m_instance = new CDependencyController();\r
-\r
- return m_instance;\r
-}\r
-\r
-CDependencyController::~CDependencyController()\r
-{\r
-}\r
-\r
-void CDependencyController::registerMixingModes(void)\r
-{\r
- for (unsigned int i = 0; i < ARRAY_SIZE(supported_mixing_modes); i++) {\r
- CMixingMode *mixing_mode = new CMixingMode(supported_mixing_modes[i]);\r
- m_mixing_modes.insert(std::pair<rms_mixing_mode_e, CMixingMode*>(supported_mixing_modes[i], mixing_mode));\r
- }\r
-}\r
-\r
-bool CDependencyController::IsRegisteredMemCluster(unsigned int id)\r
-{\r
- auto it = m_mem_clusters.find(id);\r
- return (it != m_mem_clusters.end());\r
-}\r
-\r
-CMemCluster *CDependencyController::findMemCluster(unsigned int id)\r
-{\r
- auto it = m_mem_clusters.find(id);\r
-\r
- if (it == m_mem_clusters.end())\r
- {\r
- SERVER_ERR("not existing mem cluster(%d)", id);\r
- return NULL;\r
- }\r
-\r
- return it->second;\r
-}\r
-\r
-void CDependencyController::RegisterMemCluster(unsigned int id)\r
-{\r
- if (IsRegisteredMemCluster(id))\r
- return;\r
-\r
- CMemCluster *mc = new CMemCluster(id);\r
- SERVER_INFO("register mem cluster (%d)", id);\r
- m_mem_clusters.insert(std::pair<unsigned int, CMemCluster*>(id, mc));\r
-}\r
-\r
-bool CDependencyController::isAvailableMemClusters(std::set<unsigned int> mc_ids)\r
-{\r
- CMemCluster *mc = NULL;\r
-\r
- for (auto it : mc_ids) {\r
- mc = findMemCluster(it);\r
- if (!mc) {\r
- SERVER_INFO("mem cluster NULL");\r
- return false;\r
- }\r
-\r
- if (mc->IsUsed()) {\r
- SERVER_INFO("mem cluster (%d) is being used", mc->GetId());\r
- return false;\r
- }\r
- }\r
-\r
- return true;\r
-}\r
-\r
-bool CDependencyController::isAvailableMemClusters(std::set<unsigned int> mc_ids, std::string app_id)\r
-{\r
- CMemCluster *mc = NULL;\r
-\r
- for (auto it : mc_ids) {\r
- mc = findMemCluster(it);\r
- if (!mc) {\r
- SERVER_INFO("mem cluster NULL");\r
- return false;\r
- }\r
-\r
- if (mc->IsUsed() && !mc->IsUsedBy(app_id)) {\r
- SERVER_INFO("mem cluster (%d) is being used", mc->GetId());\r
- return false;\r
- }\r
- }\r
-\r
- return true;\r
-}\r
-\r
-bool CDependencyController::isAvailableMemClusters(std::set<unsigned int> mc_ids, int category_class, int category_id)\r
-{\r
- CMemCluster *mc = NULL;\r
-\r
- for (auto it : mc_ids) {\r
- mc = findMemCluster(it);\r
- if (!mc) {\r
- SERVER_INFO("mem cluster NULL");\r
- return false;\r
- }\r
-\r
- if (!mc->IsUsed())\r
- continue;\r
-\r
- if (mc->GetCategoryClass() != category_class) {\r
- SERVER_INFO("mem cluster (%d) is in use, mc_class(%d)/category(%d)", mc->GetId(), mc->GetCategoryClass(), category_class);\r
- return false;\r
- }\r
-\r
- if (mc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING && (mc->GetCategoryId() != category_id)) {\r
- SERVER_INFO("mem cluster (%d) is in use, mc_category(%d)/category(%d)", mc->GetId(), mc->GetCategoryId(), category_id);\r
- return false;\r
- }\r
- }\r
-\r
- return true;\r
-}\r
-\r
-bool CDependencyController::isSharableMemClusters(std::set<unsigned int> mc_ids, int device_id)\r
-{\r
- CMemCluster *mc = NULL;\r
-\r
- for (auto it : mc_ids) {\r
- mc = findMemCluster(it);\r
- if (!mc) {\r
- SERVER_INFO("mem cluster NULL");\r
- return false;\r
- }\r
-\r
- if (!mc->IsSharable(device_id)) {\r
- SERVER_INFO("mem cluster (%d) is not sharable", mc->GetId());\r
- return false;\r
- }\r
- }\r
-\r
- return true;\r
-}\r
-\r
-\r
-bool CDependencyController::canReclaimMemClusters(std::set<unsigned int> mc_ids, int consumer_id)\r
-{\r
- CMemCluster *mc = NULL;\r
-\r
- for (auto const &it : mc_ids) {\r
- mc = findMemCluster(it);\r
- if (!mc) {\r
- SERVER_INFO("mem cluster NULL");\r
- return false;\r
- }\r
-\r
- std::set<int> consumers = mc->GetConsumers();\r
-\r
- for (auto const &it_consumer : consumers) {\r
- if (!CPriority::isReclaimableConsumer(it_consumer, consumer_id, NULL)) {\r
- SERVER_ERR("can't reclaim mc(%d) from (%d)", mc->GetId(), it_consumer);\r
- return false;\r
- }\r
- }\r
- }\r
-\r
- return true;\r
-}\r
-\r
-bool CDependencyController::canReclaimMemClusters(std::set<unsigned int> mc_ids, int consumer_id, std::string app_id)\r
-{\r
- CMemCluster *mc = NULL;\r
- CConsumerContainer *c_container = CConsumerContainer::getInstance();\r
- CConsumer *consumer = NULL;\r
-\r
- for (auto const &it : mc_ids) {\r
- mc = findMemCluster(it);\r
- if (!mc) {\r
- SERVER_INFO("mem cluster NULL");\r
- return false;\r
- }\r
-\r
- std::set<int> consumers = mc->GetConsumers();\r
-\r
- for (auto const &it_consumer : consumers) {\r
- consumer = c_container->findConsumer(it_consumer);\r
- if (consumer) {\r
- if (!consumer->GetAppID().compare(app_id)) {\r
- SERVER_INFO("skip to check priority against same app (%s:%s)", consumer->GetAppID().c_str(), app_id.c_str());\r
- continue;\r
- }\r
- }\r
-\r
- if (!CPriority::isReclaimableConsumer(it_consumer, consumer_id, NULL)) {\r
- SERVER_ERR("can't reclaim mc(%d) from (%d)", mc->GetId(), it_consumer);\r
- return false;\r
- }\r
- }\r
- }\r
-\r
- return true;\r
-}\r
-\r
-int CDependencyController::getReclaimableMemClusterConsumers(std::set<unsigned int> mc_ids, int consumer_id, std::multimap<int, int>* reclaimables)\r
-{\r
- CMemCluster *mc = NULL;\r
-\r
- for (auto const &it : mc_ids) {\r
- mc = findMemCluster(it);\r
- if (!mc) {\r
- SERVER_INFO("mem cluster NULL");\r
- return RMS_ERROR;\r
- }\r
-\r
- std::set<int> consumers = mc->GetConsumers();\r
-\r
- for (auto const &it_consumer : consumers) {\r
- if (!CPriority::isReclaimableConsumer(it_consumer, consumer_id, NULL)) {\r
- SERVER_ERR("can't reclaim mc(%d) from (%d)", mc->GetId(), it_consumer);\r
- return RMS_ERROR;\r
- }\r
-\r
- std::set<int> device_ids = mc->GetAssignedDeviceId(it_consumer);\r
- for (auto const &it_dev_id : device_ids) {\r
- SERVER_INFO("[mc:%d] add (%d:%d)", mc->GetId(), it_dev_id, it_consumer);\r
- reclaimables->insert(std::pair<int, int>(it_dev_id, it_consumer));\r
- }\r
- }\r
- }\r
-\r
- return RMS_OK;\r
-}\r
-\r
-int CDependencyController::getReclaimableMemClusterConsumers(std::set<unsigned int> mc_ids, int consumer_id, std::multimap<int, int>* reclaimables, std::string app_id)\r
-{\r
- CMemCluster *mc = NULL;\r
- CConsumerContainer *c_container = CConsumerContainer::getInstance();\r
- CConsumer *consumer = NULL;\r
-\r
- for (auto const &it : mc_ids) {\r
- mc = findMemCluster(it);\r
- if (!mc) {\r
- SERVER_INFO("mem cluster NULL");\r
- return RMS_ERROR;\r
- }\r
-\r
- std::set<int> consumers = mc->GetConsumers();\r
-\r
- for (auto const &it_consumer : consumers) {\r
- consumer = c_container->findConsumer(it_consumer);\r
- if (!consumer) {\r
- SERVER_WARN("Consumer not found");\r
- continue;\r
- }\r
-\r
- if (!consumer->GetAppID().compare(app_id)) {\r
- SERVER_INFO("skip to check priority against same app (%s:%s)", consumer->GetAppID().c_str(), app_id.c_str());\r
- continue;\r
- }\r
-\r
- if (!CPriority::isReclaimableConsumer(it_consumer, consumer_id, NULL)) {\r
- SERVER_ERR("can't reclaim mc(%d) from (%d)", mc->GetId(), it_consumer);\r
- return RMS_ERROR;\r
- }\r
-\r
- std::set<int> device_ids = mc->GetAssignedDeviceId(it_consumer);\r
- for (auto const &it_dev_id : device_ids) {\r
- SERVER_INFO("[mc:%d] add (%d:%d)", mc->GetId(), it_dev_id, it_consumer);\r
- reclaimables->insert(std::pair<int, int>(it_dev_id, it_consumer));\r
- }\r
- }\r
- }\r
-\r
- return RMS_OK;\r
-}\r
-\r
-void CDependencyController::SwapConsumers(int device_id_a, std::set<int> consumers_a, int device_id_b, std::set<int> consumers_b)\r
-{\r
- ClearMemClusterConsumer(device_id_a);\r
- ClearMemClusterConsumer(device_id_b);\r
-\r
- for (auto const &it : consumers_a)\r
- addMemClusterConsumer(device_id_b, it);\r
-\r
- for (auto const &it : consumers_b)\r
- addMemClusterConsumer(device_id_a, it);\r
-}\r
-\r
-void CDependencyController::addMemClusterConsumer(int device_id, int consumer_id)\r
-{\r
- CMemCluster *mc = NULL;\r
- CResource *rsc = CResourceDB::getInstance()->FindResource(device_id);\r
-\r
- if (!rsc)\r
- return;\r
-\r
- if (rsc->GetCurCategory() == RMS_CATEGORY_VIDEO_ENCODER_EXCLUSIVE)\r
- return;\r
-\r
- int category_class = rsc->GetCategoryClass();\r
-\r
- std::set<unsigned int> mc_mc_ids = rsc->GetMemClusters();\r
- for (auto const &it : mc_mc_ids) {\r
- mc = findMemCluster(it);\r
- if (!mc)\r
- continue;\r
-\r
- mc->AddConsumer(consumer_id, device_id, category_class, rsc->GetCurCategory());\r
- SERVER_INFO("add consumer(%d) to mem_cluster(%d)/class(%d)", consumer_id, mc->GetId(), category_class);\r
- }\r
-}\r
-\r
-void CDependencyController::removeMemClusterConsumer(int device_id, int consumer_id)\r
-{\r
- CMemCluster *mc = NULL;\r
- CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
-\r
- if (!resource)\r
- return;\r
-\r
- std::set<unsigned int> mc_mc_ids = resource->GetMemClusters();\r
-\r
- for (auto const &it : mc_mc_ids) {\r
- mc = findMemCluster(it);\r
- if (!mc)\r
- continue;\r
-\r
- mc->RemoveConsumer(consumer_id, device_id);\r
- SERVER_INFO("remove consumer(%d) from mem_cluster(%d)", consumer_id, mc->GetId());\r
- }\r
-}\r
-\r
-void CDependencyController::ClearMemClusterConsumer(int device_id)\r
-{\r
- CMemCluster *mc = NULL;\r
- CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
- if (!resource)\r
- return;\r
-\r
- std::set<unsigned int> mc_mc_ids = resource->GetMemClusters();\r
-\r
- for (auto const &it : mc_mc_ids) {\r
- mc = findMemCluster(it);\r
- if (!mc)\r
- continue;\r
-\r
- mc->ClearConsumers();\r
- SERVER_INFO("clear consumers from mem_cluster(%d)", mc->GetId());\r
- }\r
-}\r
-\r
-void CDependencyController::Update(resource_update_type_e type, const int device_id, const int consumer_id)\r
-{\r
- switch (type) {\r
- case UPDATED_BY_ALLOC:\r
- addMemClusterConsumer(device_id, consumer_id);\r
- addAudioCodecConsumer(device_id, consumer_id);\r
- setCurMixingMode(device_id, consumer_id);\r
- break;\r
- case UPDATED_BY_RELEASE:\r
- removeMemClusterConsumer(device_id, consumer_id);\r
- removeAudioCodecConsumer(device_id, consumer_id);\r
- resetCurMixingMode(device_id, consumer_id);\r
- break;\r
- default:\r
- SERVER_ERR("unexpected update type (%d)", type);\r
- break;\r
- }\r
-}\r
-\r
-void CDependencyController::addAudioCodecConsumer(int device_id, int consumer_id)\r
-{\r
- CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
-\r
- if (!resource->IsAudioDevice())\r
- return;\r
-\r
- m_acodec_consumers.insert(std::pair<int, int> (device_id, consumer_id));\r
-\r
- std::string codec_name = resource->GetAudioCodec();\r
- CAudioCodec *codec = CAudioCodecCollection::getInstance()->findAudioCodec(codec_name);\r
-\r
- codec->increaseRef(device_id, consumer_id);\r
-}\r
-\r
-void CDependencyController::removeAudioCodecConsumer(int device_id, int consumer_id)\r
-{\r
- CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
-\r
- if (!resource->IsAudioDevice())\r
- return;\r
-\r
- m_acodec_consumers.erase(device_id);\r
-\r
- std::string codec_name = resource->GetAudioCodec();\r
- CAudioCodec *codec = CAudioCodecCollection::getInstance()->findAudioCodec(codec_name);\r
-\r
- codec->decreaseRef(device_id, consumer_id);\r
-}\r
-\r
-CMixingMode *CDependencyController::findMixingMode(rms_mixing_mode_e mode)\r
-{\r
- auto it = m_mixing_modes.find(mode);\r
-\r
- return (it == m_mixing_modes.end()) ? NULL : it->second;\r
-}\r
-\r
-void CDependencyController::setCurMixingMode(int device_id, int consumer_id)\r
-{\r
- CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
-\r
- if (!resource->IsAudioDevice())\r
- return;\r
-\r
- rms_mixing_mode_e mode_id = resource->GetMixingMode();\r
- CMixingMode *mode = findMixingMode(mode_id);\r
-\r
- if (!mode) {\r
- SERVER_ERR("undefined mixing mode (%d)", mode_id);\r
- return;\r
- }\r
-\r
- mode->AddConsumer(device_id, consumer_id);\r
-\r
- m_cur_mixing_mode = mode;\r
-}\r
-\r
-void CDependencyController::resetCurMixingMode(int device_id, int consumer_id)\r
-{\r
- CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
-\r
- if (!resource->IsAudioDevice())\r
- return;\r
-\r
- rms_mixing_mode_e mode_id = resource->GetMixingMode();\r
- CMixingMode *mode = findMixingMode(mode_id);\r
-\r
- if (!mode) {\r
- SERVER_ERR("undefined mixing mode (%d)", mode_id);\r
- return;\r
- }\r
-\r
- if (mode->RemoveConsumer(device_id, consumer_id) > 0)\r
- return;\r
-\r
- m_cur_mixing_mode = NULL;\r
-}\r
-\r
-bool CDependencyController::isAvailableAudioCodec(std::string name)\r
-{\r
- SERVER_DBG("cur(%zu)/max(%d)", m_acodec_consumers.size(), m_acodec_ref_count_max);\r
- return (m_acodec_consumers.size() >= m_acodec_ref_count_max); //???\r
-}\r
-\r
-std::map<unsigned long, std::pair<int, int>> CDependencyController::getAudioCodecConsumers(void)\r
-{\r
- std::map<unsigned long, std::pair<int, int>> consumers;\r
-\r
- for (auto const &it : m_acodec_consumers) {\r
- CResource *rsc = CResourceDB::getInstance()->FindResource(it.first);\r
- consumers.insert(std::pair<unsigned long, std::pair<int, int>>(rsc->GetAllocatedTime(), std::make_pair(it.first, it.second)));\r
- }\r
-\r
- return consumers;\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 <stdio.h>
+
+#include <rms_debug.h>
+#include <rms_type.h>
+#include <CResourceDB.h>
+#include <CMemCluster.h>
+#include <CMixingMode.h>
+#include <CAudioCodec.h>
+#include <CAudioCodecCollection.h>
+#include <CPriority.h>
+#include <CResourceCategory.h>
+#include <CResourceObserver.h>
+#include <CDependencyController.h>
+#include <CConsumer.h>
+#include <CConsumerContainer.h>
+
+#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
+
+static rms_mixing_mode_e supported_mixing_modes[] =
+{
+ RMS_MIXING_MODE_DEFAULT,
+ RMS_MIXING_MODE_MULTIVIEW,
+ RMS_MIXING_MODE_INTERACTION_SOUND
+};
+
+CDependencyController *CDependencyController::m_instance = NULL;
+
+CDependencyController::CDependencyController()
+{
+ registerMixingModes();
+ m_cur_mixing_mode = NULL;
+}
+
+CDependencyController *CDependencyController::getInstance(void)
+{
+ if (!m_instance)
+ m_instance = new CDependencyController();
+
+ return m_instance;
+}
+
+CDependencyController::~CDependencyController()
+{
+}
+
+void CDependencyController::registerMixingModes(void)
+{
+ for (unsigned int i = 0; i < ARRAY_SIZE(supported_mixing_modes); i++) {
+ CMixingMode *mixing_mode = new CMixingMode(supported_mixing_modes[i]);
+ m_mixing_modes.insert(std::pair<rms_mixing_mode_e, CMixingMode*>(supported_mixing_modes[i], mixing_mode));
+ }
+}
+
+bool CDependencyController::IsRegisteredMemCluster(unsigned int id)
+{
+ auto it = m_mem_clusters.find(id);
+ return (it != m_mem_clusters.end());
+}
+
+CMemCluster *CDependencyController::findMemCluster(unsigned int id)
+{
+ auto it = m_mem_clusters.find(id);
+
+ if (it == m_mem_clusters.end())
+ {
+ SERVER_ERR("not existing mem cluster(%d)", id);
+ return NULL;
+ }
+
+ return it->second;
+}
+
+void CDependencyController::RegisterMemCluster(unsigned int id)
+{
+ if (IsRegisteredMemCluster(id))
+ return;
+
+ CMemCluster *mc = new CMemCluster(id);
+ SERVER_INFO("register mem cluster (%d)", id);
+ m_mem_clusters.insert(std::pair<unsigned int, CMemCluster*>(id, mc));
+}
+
+bool CDependencyController::isAvailableMemClusters(std::set<unsigned int> mc_ids)
+{
+ CMemCluster *mc = NULL;
+
+ for (auto it : mc_ids) {
+ mc = findMemCluster(it);
+ if (!mc) {
+ SERVER_INFO("mem cluster NULL");
+ return false;
+ }
+
+ if (mc->IsUsed()) {
+ SERVER_INFO("mem cluster (%d) is being used", mc->GetId());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CDependencyController::isAvailableMemClusters(std::set<unsigned int> mc_ids, std::string app_id)
+{
+ CMemCluster *mc = NULL;
+
+ for (auto it : mc_ids) {
+ mc = findMemCluster(it);
+ if (!mc) {
+ SERVER_INFO("mem cluster NULL");
+ return false;
+ }
+
+ if (mc->IsUsed() && !mc->IsUsedBy(app_id)) {
+ SERVER_INFO("mem cluster (%d) is being used", mc->GetId());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CDependencyController::isAvailableMemClusters(std::set<unsigned int> mc_ids, int category_class, int category_id)
+{
+ CMemCluster *mc = NULL;
+
+ for (auto it : mc_ids) {
+ mc = findMemCluster(it);
+ if (!mc) {
+ SERVER_INFO("mem cluster NULL");
+ return false;
+ }
+
+ if (!mc->IsUsed())
+ continue;
+
+ if (mc->GetCategoryClass() != category_class) {
+ SERVER_INFO("mem cluster (%d) is in use, mc_class(%d)/category(%d)", mc->GetId(), mc->GetCategoryClass(), category_class);
+ return false;
+ }
+
+ if (mc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING && (mc->GetCategoryId() != category_id)) {
+ SERVER_INFO("mem cluster (%d) is in use, mc_category(%d)/category(%d)", mc->GetId(), mc->GetCategoryId(), category_id);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CDependencyController::isSharableMemClusters(std::set<unsigned int> mc_ids, int device_id)
+{
+ CMemCluster *mc = NULL;
+
+ for (auto it : mc_ids) {
+ mc = findMemCluster(it);
+ if (!mc) {
+ SERVER_INFO("mem cluster NULL");
+ return false;
+ }
+
+ if (!mc->IsSharable(device_id)) {
+ SERVER_INFO("mem cluster (%d) is not sharable", mc->GetId());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+bool CDependencyController::canReclaimMemClusters(std::set<unsigned int> mc_ids, int consumer_id)
+{
+ CMemCluster *mc = NULL;
+
+ for (auto const &it : mc_ids) {
+ mc = findMemCluster(it);
+ if (!mc) {
+ SERVER_INFO("mem cluster NULL");
+ return false;
+ }
+
+ std::set<int> consumers = mc->GetConsumers();
+
+ for (auto const &it_consumer : consumers) {
+ if (!CPriority::isReclaimableConsumer(it_consumer, consumer_id, NULL)) {
+ SERVER_ERR("can't reclaim mc(%d) from (%d)", mc->GetId(), it_consumer);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool CDependencyController::canReclaimMemClusters(std::set<unsigned int> mc_ids, int consumer_id, std::string app_id)
+{
+ CMemCluster *mc = NULL;
+ CConsumerContainer *c_container = CConsumerContainer::getInstance();
+ CConsumer *consumer = NULL;
+
+ for (auto const &it : mc_ids) {
+ mc = findMemCluster(it);
+ if (!mc) {
+ SERVER_INFO("mem cluster NULL");
+ return false;
+ }
+
+ std::set<int> consumers = mc->GetConsumers();
+
+ for (auto const &it_consumer : consumers) {
+ consumer = c_container->findConsumer(it_consumer);
+ if (consumer) {
+ if (!consumer->GetAppID().compare(app_id)) {
+ SERVER_INFO("skip to check priority against same app (%s:%s)", consumer->GetAppID().c_str(), app_id.c_str());
+ continue;
+ }
+ }
+
+ if (!CPriority::isReclaimableConsumer(it_consumer, consumer_id, NULL)) {
+ SERVER_ERR("can't reclaim mc(%d) from (%d)", mc->GetId(), it_consumer);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+int CDependencyController::getReclaimableMemClusterConsumers(std::set<unsigned int> mc_ids, int consumer_id, std::multimap<int, int>* reclaimables)
+{
+ CMemCluster *mc = NULL;
+
+ for (auto const &it : mc_ids) {
+ mc = findMemCluster(it);
+ if (!mc) {
+ SERVER_INFO("mem cluster NULL");
+ return RMS_ERROR;
+ }
+
+ std::set<int> consumers = mc->GetConsumers();
+
+ for (auto const &it_consumer : consumers) {
+ if (!CPriority::isReclaimableConsumer(it_consumer, consumer_id, NULL)) {
+ SERVER_ERR("can't reclaim mc(%d) from (%d)", mc->GetId(), it_consumer);
+ return RMS_ERROR;
+ }
+
+ std::set<int> device_ids = mc->GetAssignedDeviceId(it_consumer);
+ for (auto const &it_dev_id : device_ids) {
+ SERVER_INFO("[mc:%d] add (%d:%d)", mc->GetId(), it_dev_id, it_consumer);
+ reclaimables->insert(std::pair<int, int>(it_dev_id, it_consumer));
+ }
+ }
+ }
+
+ return RMS_OK;
+}
+
+int CDependencyController::getReclaimableMemClusterConsumers(std::set<unsigned int> mc_ids, int consumer_id, std::multimap<int, int>* reclaimables, std::string app_id)
+{
+ CMemCluster *mc = NULL;
+ CConsumerContainer *c_container = CConsumerContainer::getInstance();
+ CConsumer *consumer = NULL;
+
+ for (auto const &it : mc_ids) {
+ mc = findMemCluster(it);
+ if (!mc) {
+ SERVER_INFO("mem cluster NULL");
+ return RMS_ERROR;
+ }
+
+ std::set<int> consumers = mc->GetConsumers();
+
+ for (auto const &it_consumer : consumers) {
+ consumer = c_container->findConsumer(it_consumer);
+ if (!consumer) {
+ SERVER_WARN("Consumer not found");
+ continue;
+ }
+
+ if (!consumer->GetAppID().compare(app_id)) {
+ SERVER_INFO("skip to check priority against same app (%s:%s)", consumer->GetAppID().c_str(), app_id.c_str());
+ continue;
+ }
+
+ if (!CPriority::isReclaimableConsumer(it_consumer, consumer_id, NULL)) {
+ SERVER_ERR("can't reclaim mc(%d) from (%d)", mc->GetId(), it_consumer);
+ return RMS_ERROR;
+ }
+
+ std::set<int> device_ids = mc->GetAssignedDeviceId(it_consumer);
+ for (auto const &it_dev_id : device_ids) {
+ SERVER_INFO("[mc:%d] add (%d:%d)", mc->GetId(), it_dev_id, it_consumer);
+ reclaimables->insert(std::pair<int, int>(it_dev_id, it_consumer));
+ }
+ }
+ }
+
+ return RMS_OK;
+}
+
+void CDependencyController::SwapConsumers(int device_id_a, std::set<int> consumers_a, int device_id_b, std::set<int> consumers_b)
+{
+ ClearMemClusterConsumer(device_id_a);
+ ClearMemClusterConsumer(device_id_b);
+
+ for (auto const &it : consumers_a)
+ addMemClusterConsumer(device_id_b, it);
+
+ for (auto const &it : consumers_b)
+ addMemClusterConsumer(device_id_a, it);
+}
+
+void CDependencyController::addMemClusterConsumer(int device_id, int consumer_id)
+{
+ CMemCluster *mc = NULL;
+ CResource *rsc = CResourceDB::getInstance()->FindResource(device_id);
+
+ if (!rsc)
+ return;
+
+ if (rsc->GetCurCategory() == RMS_CATEGORY_VIDEO_ENCODER_EXCLUSIVE)
+ return;
+
+ int category_class = rsc->GetCategoryClass();
+
+ std::set<unsigned int> mc_mc_ids = rsc->GetMemClusters();
+ for (auto const &it : mc_mc_ids) {
+ mc = findMemCluster(it);
+ if (!mc)
+ continue;
+
+ mc->AddConsumer(consumer_id, device_id, category_class, rsc->GetCurCategory());
+ SERVER_INFO("add consumer(%d) to mem_cluster(%d)/class(%d)", consumer_id, mc->GetId(), category_class);
+ }
+}
+
+void CDependencyController::removeMemClusterConsumer(int device_id, int consumer_id)
+{
+ CMemCluster *mc = NULL;
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);
+
+ if (!resource)
+ return;
+
+ std::set<unsigned int> mc_mc_ids = resource->GetMemClusters();
+
+ for (auto const &it : mc_mc_ids) {
+ mc = findMemCluster(it);
+ if (!mc)
+ continue;
+
+ mc->RemoveConsumer(consumer_id, device_id);
+ SERVER_INFO("remove consumer(%d) from mem_cluster(%d)", consumer_id, mc->GetId());
+ }
+}
+
+void CDependencyController::ClearMemClusterConsumer(int device_id)
+{
+ CMemCluster *mc = NULL;
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);
+ if (!resource)
+ return;
+
+ std::set<unsigned int> mc_mc_ids = resource->GetMemClusters();
+
+ for (auto const &it : mc_mc_ids) {
+ mc = findMemCluster(it);
+ if (!mc)
+ continue;
+
+ mc->ClearConsumers();
+ SERVER_INFO("clear consumers from mem_cluster(%d)", mc->GetId());
+ }
+}
+
+void CDependencyController::Update(resource_update_type_e type, const int device_id, const int consumer_id)
+{
+ switch (type) {
+ case UPDATED_BY_ALLOC:
+ addMemClusterConsumer(device_id, consumer_id);
+ addAudioCodecConsumer(device_id, consumer_id);
+ setCurMixingMode(device_id, consumer_id);
+ break;
+ case UPDATED_BY_RELEASE:
+ removeMemClusterConsumer(device_id, consumer_id);
+ removeAudioCodecConsumer(device_id, consumer_id);
+ resetCurMixingMode(device_id, consumer_id);
+ break;
+ default:
+ SERVER_ERR("unexpected update type (%d)", type);
+ break;
+ }
+}
+
+void CDependencyController::addAudioCodecConsumer(int device_id, int consumer_id)
+{
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);
+
+ if (!resource->IsAudioDevice())
+ return;
+
+ m_acodec_consumers.insert(std::pair<int, int> (device_id, consumer_id));
+
+ std::string codec_name = resource->GetAudioCodec();
+ CAudioCodec *codec = CAudioCodecCollection::getInstance()->findAudioCodec(codec_name);
+
+ codec->increaseRef(device_id, consumer_id);
+}
+
+void CDependencyController::removeAudioCodecConsumer(int device_id, int consumer_id)
+{
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);
+
+ if (!resource->IsAudioDevice())
+ return;
+
+ m_acodec_consumers.erase(device_id);
+
+ std::string codec_name = resource->GetAudioCodec();
+ CAudioCodec *codec = CAudioCodecCollection::getInstance()->findAudioCodec(codec_name);
+
+ codec->decreaseRef(device_id, consumer_id);
+}
+
+CMixingMode *CDependencyController::findMixingMode(rms_mixing_mode_e mode)
+{
+ auto it = m_mixing_modes.find(mode);
+
+ return (it == m_mixing_modes.end()) ? NULL : it->second;
+}
+
+void CDependencyController::setCurMixingMode(int device_id, int consumer_id)
+{
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);
+
+ if (!resource->IsAudioDevice())
+ return;
+
+ rms_mixing_mode_e mode_id = resource->GetMixingMode();
+ CMixingMode *mode = findMixingMode(mode_id);
+
+ if (!mode) {
+ SERVER_ERR("undefined mixing mode (%d)", mode_id);
+ return;
+ }
+
+ mode->AddConsumer(device_id, consumer_id);
+
+ m_cur_mixing_mode = mode;
+}
+
+void CDependencyController::resetCurMixingMode(int device_id, int consumer_id)
+{
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);
+
+ if (!resource->IsAudioDevice())
+ return;
+
+ rms_mixing_mode_e mode_id = resource->GetMixingMode();
+ CMixingMode *mode = findMixingMode(mode_id);
+
+ if (!mode) {
+ SERVER_ERR("undefined mixing mode (%d)", mode_id);
+ return;
+ }
+
+ if (mode->RemoveConsumer(device_id, consumer_id) > 0)
+ return;
+
+ m_cur_mixing_mode = NULL;
+}
+
+bool CDependencyController::isAvailableAudioCodec(std::string name)
+{
+ SERVER_DBG("cur(%zu)/max(%d)", m_acodec_consumers.size(), m_acodec_ref_count_max);
+ return (m_acodec_consumers.size() >= m_acodec_ref_count_max); //???
+}
+
+std::map<unsigned long, std::pair<int, int>> CDependencyController::getAudioCodecConsumers(void)
+{
+ std::map<unsigned long, std::pair<int, int>> consumers;
+
+ for (auto const &it : m_acodec_consumers) {
+ CResource *rsc = CResourceDB::getInstance()->FindResource(it.first);
+ consumers.insert(std::pair<unsigned long, std::pair<int, int>>(rsc->GetAllocatedTime(), std::make_pair(it.first, it.second)));
+ }
+
+ return consumers;
+}
-/*\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 "CMemCluster.h"\r
-#include "CConsumerContainer.h"\r
-#include "CConsumer.h"\r
-\r
-CMemCluster::CMemCluster(unsigned int id)\r
-{\r
- m_id = id;\r
- m_category_class = 0;\r
- m_category_id = 0;\r
-}\r
-\r
-CMemCluster::~CMemCluster()\r
-{\r
-}\r
-\r
-bool CMemCluster::IsUsed(void)\r
-{\r
- return (m_consumers.size() > 0);\r
-}\r
-\r
-bool CMemCluster::IsUsedBy(std::string app_id)\r
-{\r
- CConsumerContainer *cc = CConsumerContainer::getInstance();\r
- CConsumer *c = NULL;\r
- bool result = false;\r
-\r
- if (m_consumers.size() == 0)\r
- return false;\r
-\r
- for (const auto& it : m_consumers) {\r
- c = cc->findConsumer(it.first);\r
- if (!c)\r
- continue;\r
- if (!c->GetAppID().compare(app_id)) {\r
- SERVER_INFO("mc(%d) is used by (%s)", m_id, app_id.c_str());\r
- return true;\r
- }\r
- }\r
-\r
- return result;\r
-}\r
-\r
-bool CMemCluster::IsSharable(int device_id)\r
-{\r
- if (m_consumers.size() == 0)\r
- return true;\r
-\r
- for (auto it : m_consumers) {\r
- auto it_dev_id = it.second.find(device_id);\r
- if (it_dev_id != it.second.end())\r
- return true;\r
- }\r
- return false;\r
-}\r
-\r
-void CMemCluster::AddConsumer(int consumer_id, int device_id, int category_class, int category_id)\r
-{\r
- auto it = m_consumers.find(consumer_id);\r
- if (it == m_consumers.end()) {\r
- std::set<int> device_ids;\r
- device_ids.insert(device_id);\r
- m_consumers.insert(std::pair<int, std::set<int>>(consumer_id, device_ids));\r
- m_category_class = category_class;\r
- m_category_id = category_id;\r
- } else {\r
- std::set<int> &pdevice_ids = it->second;\r
- pdevice_ids.insert(device_id);\r
- }\r
-}\r
-\r
-void CMemCluster::RemoveConsumer(int consumer_id, int device_id)\r
-{\r
- auto it = m_consumers.find(consumer_id);\r
- if (it == m_consumers.end())\r
- return;\r
-\r
- std::set<int> &device_ids = it->second;\r
-\r
- auto id_it = device_ids.find(device_id);\r
- if (id_it == device_ids.end())\r
- return;\r
-\r
- device_ids.erase(device_id);\r
- if (device_ids.empty())\r
- m_consumers.erase(consumer_id);\r
-\r
- if (m_consumers.empty()) {\r
- m_category_class = 0;\r
- m_category_id = 0;\r
- }\r
-}\r
-\r
-std::set<int> CMemCluster::GetConsumers(void)\r
-{\r
- std::set<int> consumers;\r
-\r
- for (const auto& it : m_consumers)\r
- consumers.insert(it.first);\r
-\r
- return consumers;\r
-}\r
-\r
-void CMemCluster::ClearConsumers(void)\r
-{\r
- for (auto &it : m_consumers) {\r
- std::set<int> &id_it = it.second;\r
- id_it.clear();\r
- }\r
- m_consumers.clear();\r
-}\r
-\r
-std::set<int> CMemCluster::GetAssignedDeviceId(int consumer_id)\r
-{\r
- std::set<int> device_ids;\r
- auto it = m_consumers.find(consumer_id);\r
-\r
- if (it == m_consumers.end())\r
- return device_ids;\r
-\r
- device_ids.insert(it->second.begin(), it->second.end());\r
-\r
- return device_ids;\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 "CMemCluster.h"
+#include "CConsumerContainer.h"
+#include "CConsumer.h"
+
+CMemCluster::CMemCluster(unsigned int id)
+{
+ m_id = id;
+ m_category_class = 0;
+ m_category_id = 0;
+}
+
+CMemCluster::~CMemCluster()
+{
+}
+
+bool CMemCluster::IsUsed(void)
+{
+ return (m_consumers.size() > 0);
+}
+
+bool CMemCluster::IsUsedBy(std::string app_id)
+{
+ CConsumerContainer *cc = CConsumerContainer::getInstance();
+ CConsumer *c = NULL;
+ bool result = false;
+
+ if (m_consumers.size() == 0)
+ return false;
+
+ for (const auto& it : m_consumers) {
+ c = cc->findConsumer(it.first);
+ if (!c)
+ continue;
+ if (!c->GetAppID().compare(app_id)) {
+ SERVER_INFO("mc(%d) is used by (%s)", m_id, app_id.c_str());
+ return true;
+ }
+ }
+
+ return result;
+}
+
+bool CMemCluster::IsSharable(int device_id)
+{
+ if (m_consumers.size() == 0)
+ return true;
+
+ for (auto it : m_consumers) {
+ auto it_dev_id = it.second.find(device_id);
+ if (it_dev_id != it.second.end())
+ return true;
+ }
+ return false;
+}
+
+void CMemCluster::AddConsumer(int consumer_id, int device_id, int category_class, int category_id)
+{
+ auto it = m_consumers.find(consumer_id);
+ if (it == m_consumers.end()) {
+ std::set<int> device_ids;
+ device_ids.insert(device_id);
+ m_consumers.insert(std::pair<int, std::set<int>>(consumer_id, device_ids));
+ m_category_class = category_class;
+ m_category_id = category_id;
+ } else {
+ std::set<int> &pdevice_ids = it->second;
+ pdevice_ids.insert(device_id);
+ }
+}
+
+void CMemCluster::RemoveConsumer(int consumer_id, int device_id)
+{
+ auto it = m_consumers.find(consumer_id);
+ if (it == m_consumers.end())
+ return;
+
+ std::set<int> &device_ids = it->second;
+
+ auto id_it = device_ids.find(device_id);
+ if (id_it == device_ids.end())
+ return;
+
+ device_ids.erase(device_id);
+ if (device_ids.empty())
+ m_consumers.erase(consumer_id);
+
+ if (m_consumers.empty()) {
+ m_category_class = 0;
+ m_category_id = 0;
+ }
+}
+
+std::set<int> CMemCluster::GetConsumers(void)
+{
+ std::set<int> consumers;
+
+ for (const auto& it : m_consumers)
+ consumers.insert(it.first);
+
+ return consumers;
+}
+
+void CMemCluster::ClearConsumers(void)
+{
+ for (auto &it : m_consumers) {
+ std::set<int> &id_it = it.second;
+ id_it.clear();
+ }
+ m_consumers.clear();
+}
+
+std::set<int> CMemCluster::GetAssignedDeviceId(int consumer_id)
+{
+ std::set<int> device_ids;
+ auto it = m_consumers.find(consumer_id);
+
+ if (it == m_consumers.end())
+ return device_ids;
+
+ device_ids.insert(it->second.begin(), it->second.end());
+
+ return device_ids;
+}
-/*\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_debug.h>\r
-#include <CMixingMode.h>\r
-\r
-int CMixingMode::AddConsumer(int device_id, int consumer_id)\r
-{\r
- auto it = m_consumers.find(device_id);\r
-\r
- if (it != m_consumers.end()) {\r
- SERVER_ERR("already registered device(%d) by (%d)", device_id, it->second);\r
- return m_consumers.size();\r
- }\r
-\r
- SERVER_INFO("add consumer(%d:%d) to mode(%d)", consumer_id, device_id, m_mode);\r
- m_consumers.insert(std::pair<int, int>(device_id, consumer_id));\r
-\r
- return m_consumers.size();\r
-}\r
-\r
-int CMixingMode::RemoveConsumer(int device_id, int consumer_id)\r
-{\r
- auto it = m_consumers.find(device_id);\r
-\r
- if (it == m_consumers.end())\r
- return m_consumers.size();\r
-\r
- SERVER_INFO("remove consumer(%d:%d) from mode(%d)", consumer_id, device_id, m_mode);\r
-\r
- m_consumers.erase(device_id);\r
-\r
- return m_consumers.size();\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 <rms_debug.h>
+#include <CMixingMode.h>
+
+int CMixingMode::AddConsumer(int device_id, int consumer_id)
+{
+ auto it = m_consumers.find(device_id);
+
+ if (it != m_consumers.end()) {
+ SERVER_ERR("already registered device(%d) by (%d)", device_id, it->second);
+ return m_consumers.size();
+ }
+
+ SERVER_INFO("add consumer(%d:%d) to mode(%d)", consumer_id, device_id, m_mode);
+ m_consumers.insert(std::pair<int, int>(device_id, consumer_id));
+
+ return m_consumers.size();
+}
+
+int CMixingMode::RemoveConsumer(int device_id, int consumer_id)
+{
+ auto it = m_consumers.find(device_id);
+
+ if (it == m_consumers.end())
+ return m_consumers.size();
+
+ SERVER_INFO("remove consumer(%d:%d) from mode(%d)", consumer_id, device_id, m_mode);
+
+ m_consumers.erase(device_id);
+
+ return m_consumers.size();
+}
+
-/*\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
-\r
-#include <CAllocateModeStrategy.h>\r
-#include <CNormalModeStrategy.h>\r
-#include <CInvalidModeStrategy.h>\r
-#include <CPreferenceModeStrategy.h>\r
-#include <CAllocateModeStrategyProvider.h>\r
-\r
-enum {\r
- INIT_MODE = -1,\r
- NORMAL_MODE,\r
- PREFERENCE_MODE,\r
- INVALID_MODE\r
-};\r
-\r
-CAllocateModeStrategyProvider *CAllocateModeStrategyProvider::m_instance = NULL;\r
-\r
-CAllocateModeStrategyProvider::CAllocateModeStrategyProvider()\r
-{\r
-}\r
-\r
-CAllocateModeStrategyProvider::~CAllocateModeStrategyProvider()\r
-{\r
-}\r
-\r
-\r
-CAllocateModeStrategyProvider *CAllocateModeStrategyProvider::getInstance()\r
-{\r
- if (!m_instance)\r
- m_instance = new CAllocateModeStrategyProvider();\r
-\r
- return m_instance;\r
-}\r
-\r
-int CAllocateModeStrategyProvider::getAllocateMode(rms_msg_request *req)\r
-{\r
- int mode = INIT_MODE;\r
-\r
- for (int i = 0; i < req->request_num; i++) {\r
- if (req->state[i] == RMS_STATE_EXCLUSIVE_PREFERENCE) {\r
- if (mode == INIT_MODE) {\r
- mode = PREFERENCE_MODE;\r
- } else if (mode == NORMAL_MODE) {\r
- mode = INVALID_MODE;\r
- break;\r
- }\r
- } else {\r
- if (mode == INIT_MODE) {\r
- mode = NORMAL_MODE;\r
- } else if (mode == PREFERENCE_MODE) {\r
- mode = INVALID_MODE;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- return mode;\r
-}\r
-\r
-CAllocateModeStrategy *CAllocateModeStrategyProvider::GetStrategy(rms_msg_request *req)\r
-{\r
- CAllocateModeStrategy *strategy = NULL;\r
-\r
- switch (getAllocateMode(req)) {\r
- case NORMAL_MODE:\r
- strategy = new CNormalModeStrategy();\r
- break;\r
- case PREFERENCE_MODE:\r
- strategy = new CPreferenceModeStrategy();\r
- break;\r
- default:\r
- strategy = new CInvalidModeStrategy();\r
- break;\r
- }\r
-\r
- return strategy;\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 <CAllocateModeStrategy.h>
+#include <CNormalModeStrategy.h>
+#include <CInvalidModeStrategy.h>
+#include <CPreferenceModeStrategy.h>
+#include <CAllocateModeStrategyProvider.h>
+
+enum {
+ INIT_MODE = -1,
+ NORMAL_MODE,
+ PREFERENCE_MODE,
+ INVALID_MODE
+};
+
+CAllocateModeStrategyProvider *CAllocateModeStrategyProvider::m_instance = NULL;
+
+CAllocateModeStrategyProvider::CAllocateModeStrategyProvider()
+{
+}
+
+CAllocateModeStrategyProvider::~CAllocateModeStrategyProvider()
+{
+}
+
+
+CAllocateModeStrategyProvider *CAllocateModeStrategyProvider::getInstance()
+{
+ if (!m_instance)
+ m_instance = new CAllocateModeStrategyProvider();
+
+ return m_instance;
+}
+
+int CAllocateModeStrategyProvider::getAllocateMode(rms_msg_request *req)
+{
+ int mode = INIT_MODE;
+
+ for (int i = 0; i < req->request_num; i++) {
+ if (req->state[i] == RMS_STATE_EXCLUSIVE_PREFERENCE) {
+ if (mode == INIT_MODE) {
+ mode = PREFERENCE_MODE;
+ } else if (mode == NORMAL_MODE) {
+ mode = INVALID_MODE;
+ break;
+ }
+ } else {
+ if (mode == INIT_MODE) {
+ mode = NORMAL_MODE;
+ } else if (mode == PREFERENCE_MODE) {
+ mode = INVALID_MODE;
+ break;
+ }
+ }
+ }
+
+ return mode;
+}
+
+CAllocateModeStrategy *CAllocateModeStrategyProvider::GetStrategy(rms_msg_request *req)
+{
+ CAllocateModeStrategy *strategy = NULL;
+
+ switch (getAllocateMode(req)) {
+ case NORMAL_MODE:
+ strategy = new CNormalModeStrategy();
+ break;
+ case PREFERENCE_MODE:
+ strategy = new CPreferenceModeStrategy();
+ break;
+ default:
+ strategy = new CInvalidModeStrategy();
+ break;
+ }
+
+ return strategy;
+}
-/*\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 <assert.h>\r
-#include <map>\r
-#include <algorithm>\r
-\r
-#include <rms_type.h>\r
-#include <rms_debug.h>\r
-#include <CResource.h>\r
-#include <CVirtualResource.h>\r
-#include <CResourceDB.h>\r
-#include <CRequest.h>\r
-#include <CRequester.h>\r
-#include <CPriority.h>\r
-#include <CAllocateStrategy.h>\r
-\r
-void CAllocateStrategy::ExcludeResources(std::map<int, CVirtualResource*> vresources, std::map<int, CVirtualResource*>* filtered_resources, CRequest *req)\r
-{\r
- for (auto const &it : vresources) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *resource = vresource->GetResource();\r
-\r
- if (req->IsMainDeviceRequest() && !vresource->IsMainDevice())\r
- continue;\r
- if (req->IsSubDeviceRequest() && vresource->IsMainDevice())\r
- continue;\r
- if (req->IsAIDeviceRequest() && !vresource->IsAIDevice())\r
- continue;\r
- if (req->IsRequestByDevice() && resource->GetDeviceID() != req->GetDevice())\r
- continue;\r
- if (req->GetState() == RMS_STATE_SHARABLE && !resource->IsSharableDevice())\r
- continue;\r
- if (req->GetState() != RMS_STATE_SHARABLE && resource->IsSharableDevice())\r
- continue;\r
-\r
- filtered_resources->insert(std::pair<int, CVirtualResource*>(it.first, it.second));\r
- }\r
-}\r
-\r
-void CAllocateStrategy::ExcludeResources(std::multimap<unsigned long, CVirtualResource*> vresources, std::multimap<unsigned long, CVirtualResource*>* filtered_resources, CRequest *req)\r
-{\r
- for (auto const &it : vresources) {\r
- CVirtualResource *vresource = it.second;\r
-\r
- if (req->IsMainDeviceRequest() && !vresource->IsMainDevice())\r
- continue;\r
- if (req->IsSubDeviceRequest() && vresource->IsMainDevice())\r
- continue;\r
- if (req->IsAIDeviceRequest() && !vresource->IsAIDevice())\r
- continue;\r
-\r
- filtered_resources->insert(std::pair<unsigned long, CVirtualResource*>(it.first, it.second));\r
- }\r
-}\r
-\r
-void CAllocateStrategy::updateReasonByResourceState(int device_id, CRequest *req)\r
-{\r
- if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
- return;\r
- }\r
-\r
- if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)\r
- return;\r
-\r
- bool low_priority_consumer_using = (CPriority::compareCurConsumers(device_id, req->getRequester()->getHandle()) == HIGH_PRIORITY);\r
-\r
- if (low_priority_consumer_using) {\r
- req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
- SERVER_INFO("RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER");\r
- } else {\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
- SERVER_INFO("RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS");\r
- }\r
-}\r
-\r
-void CAllocateStrategy::updateReasonBySharableCount(int device_id, CRequest *req)\r
-{\r
- if (req->GetState() != RMS_STATE_SHARABLE)\r
- return;\r
-\r
- if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)\r
- return;\r
-\r
- bool low_priority_consumer_using = (CPriority::compareCurConsumers(device_id, req->getRequester()->getHandle()) == HIGH_PRIORITY);\r
-\r
- if (low_priority_consumer_using)\r
- req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
- else\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
-}\r
-\r
-int CAllocateStrategy::GetReclaimedBW(std::multimap<int, int> *retirables)\r
-{\r
- CResourceDB *db = CResourceDB::getInstance();\r
- std::set<int> rsc_ids;\r
- int bw = 0;\r
-\r
- ExcludeDuplicatedNDecoders(retirables, &rsc_ids);\r
-\r
- for (auto const &it : rsc_ids) {\r
- CResource *rsc = db->FindResource(it);\r
- if (!rsc)\r
- continue;\r
- bw += rsc->GetBW();\r
- }\r
-\r
- //SERVER_INFO("reclaimed bw(%d) from (%d)", bw, retirables->size());\r
- return bw;\r
-}\r
-\r
-void CAllocateStrategy::ExcludeDuplicatedNDecoders(std::multimap<int, int> *retirables, std::set<int> *excluded)\r
-{\r
- assert(retirables);\r
- assert(excluded);\r
- std::map<int, int> rscs_by_category; //category id, device_id\r
- CResourceDB *db = CResourceDB::getInstance();\r
-\r
- for (auto &it : *retirables) {\r
- CResource *rsc = db->FindResource(it.first);\r
- if (!rsc)\r
- continue;\r
- if (rsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) {\r
- //SERVER_INFO("insert (%d:%d)", rsc->GetCurCategory(), it.first);\r
- rscs_by_category.insert(std::pair<int, int>(rsc->GetCurCategory(), it.first));\r
- } else {\r
- //SERVER_INFO("insert (%d)", it.first);\r
- excluded->insert(it.first);\r
- }\r
- }\r
-\r
- for (auto &itn : rscs_by_category) {\r
- //SERVER_INFO("insert (%d)", itn.second);\r
- excluded->insert(itn.second);\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 <stdlib.h>
+#include <assert.h>
+#include <map>
+#include <algorithm>
+
+#include <rms_type.h>
+#include <rms_debug.h>
+#include <CResource.h>
+#include <CVirtualResource.h>
+#include <CResourceDB.h>
+#include <CRequest.h>
+#include <CRequester.h>
+#include <CPriority.h>
+#include <CAllocateStrategy.h>
+
+void CAllocateStrategy::ExcludeResources(std::map<int, CVirtualResource*> vresources, std::map<int, CVirtualResource*>* filtered_resources, CRequest *req)
+{
+ for (auto const &it : vresources) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+
+ if (req->IsMainDeviceRequest() && !vresource->IsMainDevice())
+ continue;
+ if (req->IsSubDeviceRequest() && vresource->IsMainDevice())
+ continue;
+ if (req->IsAIDeviceRequest() && !vresource->IsAIDevice())
+ continue;
+ if (req->IsRequestByDevice() && resource->GetDeviceID() != req->GetDevice())
+ continue;
+ if (req->GetState() == RMS_STATE_SHARABLE && !resource->IsSharableDevice())
+ continue;
+ if (req->GetState() != RMS_STATE_SHARABLE && resource->IsSharableDevice())
+ continue;
+
+ filtered_resources->insert(std::pair<int, CVirtualResource*>(it.first, it.second));
+ }
+}
+
+void CAllocateStrategy::ExcludeResources(std::multimap<unsigned long, CVirtualResource*> vresources, std::multimap<unsigned long, CVirtualResource*>* filtered_resources, CRequest *req)
+{
+ for (auto const &it : vresources) {
+ CVirtualResource *vresource = it.second;
+
+ if (req->IsMainDeviceRequest() && !vresource->IsMainDevice())
+ continue;
+ if (req->IsSubDeviceRequest() && vresource->IsMainDevice())
+ continue;
+ if (req->IsAIDeviceRequest() && !vresource->IsAIDevice())
+ continue;
+
+ filtered_resources->insert(std::pair<unsigned long, CVirtualResource*>(it.first, it.second));
+ }
+}
+
+void CAllocateStrategy::updateReasonByResourceState(int device_id, CRequest *req)
+{
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+ return;
+ }
+
+ if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)
+ return;
+
+ bool low_priority_consumer_using = (CPriority::compareCurConsumers(device_id, req->getRequester()->getHandle()) == HIGH_PRIORITY);
+
+ if (low_priority_consumer_using) {
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);
+ SERVER_INFO("RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER");
+ } else {
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+ SERVER_INFO("RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS");
+ }
+}
+
+void CAllocateStrategy::updateReasonBySharableCount(int device_id, CRequest *req)
+{
+ if (req->GetState() != RMS_STATE_SHARABLE)
+ return;
+
+ if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)
+ return;
+
+ bool low_priority_consumer_using = (CPriority::compareCurConsumers(device_id, req->getRequester()->getHandle()) == HIGH_PRIORITY);
+
+ if (low_priority_consumer_using)
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);
+ else
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+}
+
+int CAllocateStrategy::GetReclaimedBW(std::multimap<int, int> *retirables)
+{
+ CResourceDB *db = CResourceDB::getInstance();
+ std::set<int> rsc_ids;
+ int bw = 0;
+
+ ExcludeDuplicatedNDecoders(retirables, &rsc_ids);
+
+ for (auto const &it : rsc_ids) {
+ CResource *rsc = db->FindResource(it);
+ if (!rsc)
+ continue;
+ bw += rsc->GetBW();
+ }
+
+ //SERVER_INFO("reclaimed bw(%d) from (%d)", bw, retirables->size());
+ return bw;
+}
+
+void CAllocateStrategy::ExcludeDuplicatedNDecoders(std::multimap<int, int> *retirables, std::set<int> *excluded)
+{
+ assert(retirables);
+ assert(excluded);
+ std::map<int, int> rscs_by_category; //category id, device_id
+ CResourceDB *db = CResourceDB::getInstance();
+
+ for (auto &it : *retirables) {
+ CResource *rsc = db->FindResource(it.first);
+ if (!rsc)
+ continue;
+ if (rsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) {
+ //SERVER_INFO("insert (%d:%d)", rsc->GetCurCategory(), it.first);
+ rscs_by_category.insert(std::pair<int, int>(rsc->GetCurCategory(), it.first));
+ } else {
+ //SERVER_INFO("insert (%d)", it.first);
+ excluded->insert(it.first);
+ }
+ }
+
+ for (auto &itn : rscs_by_category) {
+ //SERVER_INFO("insert (%d)", itn.second);
+ excluded->insert(itn.second);
+ }
+}
-/*\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 <rms_debug.h>\r
-#include <CAllocateStrategy.h>\r
-#include <CNormalStrategy.h>\r
-#include <CAudioDecoderStrategy.h>\r
-#include <CNDecodingVideoDecoderStrategy.h>\r
-#include <CVideoDecoderStrategy.h>\r
-#include <CScalerStrategy.h>\r
-#include <CExclusiveStrategy.h>\r
-#include <CAllocateStrategyProvider.h>\r
-#include <CVideoEncoderExclusiveStrategy.h>\r
-\r
-CAllocateStrategyProvider *CAllocateStrategyProvider::m_instance = NULL;\r
-\r
-CAllocateStrategyProvider::CAllocateStrategyProvider()\r
-{\r
-}\r
-\r
-bool CAllocateStrategyProvider::IsAudioDecoderCategory(rms_rsc_category_e category)\r
-{\r
- bool result = false;\r
-\r
- switch (category) {\r
- case RMS_CATEGORY_AUDIO_DECODER:\r
- case RMS_CATEGORY_AUDIO_DECODER_SUB:\r
- case RMS_CATEGORY_AUDIO_DECODER_PRIMARY:\r
- case RMS_CATEGORY_AUDIO_DECODER_ANY:\r
- result = true;\r
- break;\r
- default:\r
- result = false;\r
- break;\r
- }\r
-\r
- if (category > RMS_CATEGORY_AUDIO_DECODER_OPTION && category < RMS_CATEGORY_AUDIO_DECODER_OPTION_MAX)\r
- result = true;\r
-\r
- return result;\r
-}\r
-\r
-bool CAllocateStrategyProvider::IsVideoDecoderCategory(rms_rsc_category_e category)\r
-{\r
- bool result = false;\r
-\r
- switch (category) {\r
- case RMS_CATEGORY_VIDEO_DECODER:\r
- case RMS_CATEGORY_VIDEO_DECODER_SUB:\r
- case RMS_CATEGORY_JPEG_DECODER:\r
- case RMS_CATEGORY_MJPEG_DECODER:\r
- case RMS_CATEGORY_JPEG_DECODER_FHD:\r
- case RMS_CATEGORY_JPEG_DECODER_UHD:\r
- case RMS_CATEGORY_JPEG_DECODER_8K:\r
- case RMS_CATEGORY_MJPEG_DECODER_FHD:\r
- case RMS_CATEGORY_MJPEG_DECODER_UHD:\r
- case RMS_CATEGORY_MJPEG_DECODER_8K:\r
- case RMS_CATEGORY_HEIC_DECODER:\r
- result = true;\r
- break;\r
- default:\r
- result = false;\r
- break;\r
- }\r
-\r
- if (category > RMS_CATEGORY_VIDEO_DECODER_OPTION && category < RMS_CATEGORY_VIDEO_DECODER_OPTION_MAX)\r
- result = true;\r
-\r
- return result;\r
-}\r
-\r
-bool CAllocateStrategyProvider::IsNDecordingVideoDecoderCategory(int category_class)\r
-{\r
- return (category_class == RMS_CATEGORY_CLASS_N_DECODING);\r
-}\r
-\r
-bool CAllocateStrategyProvider::IsBGScalerCategory(rms_rsc_category_e category)\r
-{\r
- return (category == RMS_CATEGORY_SCALER_BG);\r
-}\r
-\r
-bool CAllocateStrategyProvider::IsMultiviewScalerCategory(rms_rsc_category_e category)\r
-{\r
- return (category == RMS_CATEGORY_SCALER_MULTIVIEW || category == RMS_CATEGORY_SCALER_INTERLACED);\r
-}\r
-\r
-bool CAllocateStrategyProvider::IsSubScalerCategory(rms_rsc_category_e category)\r
-{\r
- bool result = false;\r
-\r
- switch (category) {\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
- result = false;\r
- break;\r
- }\r
-\r
- return result;\r
-}\r
-\r
-CAllocateStrategyProvider *CAllocateStrategyProvider::getInstance()\r
-{\r
- if (!m_instance)\r
- m_instance = new CAllocateStrategyProvider();\r
-\r
- return m_instance;\r
-}\r
-\r
-CAllocateStrategyProvider::~CAllocateStrategyProvider()\r
-{\r
-}\r
-\r
-CAllocateStrategy *CAllocateStrategyProvider::GetStrategy(rms_rsc_category_e category, int category_class)\r
-{\r
- CAllocateStrategy *strategy = NULL;\r
-\r
- if (IsVideoDecoderCategory(category)) {\r
- if (IsNDecordingVideoDecoderCategory(category_class))\r
- strategy = new CNDecodingVideoDecoderStrategy();\r
- else\r
- strategy = new CVideoDecoderStrategy();\r
- } else if (IsAudioDecoderCategory(category)) {\r
- strategy = new CAudioDecoderStrategy();\r
- } else if (IsBGScalerCategory(category) || IsSubScalerCategory(category)) {\r
- strategy = new CExclusiveStrategy();\r
- } else if (IsMultiviewScalerCategory(category)) {\r
- strategy = new CScalerStrategy();\r
- } else if (category == RMS_CATEGORY_VIDEO_ENCODER_EXCLUSIVE) {\r
- strategy = new CVideoEncoderExclusiveStrategy();\r
- } else {\r
- strategy = new CNormalStrategy();\r
- }\r
-\r
- return strategy;\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 <rms_debug.h>
+#include <CAllocateStrategy.h>
+#include <CNormalStrategy.h>
+#include <CAudioDecoderStrategy.h>
+#include <CNDecodingVideoDecoderStrategy.h>
+#include <CVideoDecoderStrategy.h>
+#include <CScalerStrategy.h>
+#include <CExclusiveStrategy.h>
+#include <CAllocateStrategyProvider.h>
+#include <CVideoEncoderExclusiveStrategy.h>
+
+CAllocateStrategyProvider *CAllocateStrategyProvider::m_instance = NULL;
+
+CAllocateStrategyProvider::CAllocateStrategyProvider()
+{
+}
+
+bool CAllocateStrategyProvider::IsAudioDecoderCategory(rms_rsc_category_e category)
+{
+ bool result = false;
+
+ switch (category) {
+ case RMS_CATEGORY_AUDIO_DECODER:
+ case RMS_CATEGORY_AUDIO_DECODER_SUB:
+ case RMS_CATEGORY_AUDIO_DECODER_PRIMARY:
+ case RMS_CATEGORY_AUDIO_DECODER_ANY:
+ result = true;
+ break;
+ default:
+ result = false;
+ break;
+ }
+
+ if (category > RMS_CATEGORY_AUDIO_DECODER_OPTION && category < RMS_CATEGORY_AUDIO_DECODER_OPTION_MAX)
+ result = true;
+
+ return result;
+}
+
+bool CAllocateStrategyProvider::IsVideoDecoderCategory(rms_rsc_category_e category)
+{
+ bool result = false;
+
+ switch (category) {
+ case RMS_CATEGORY_VIDEO_DECODER:
+ case RMS_CATEGORY_VIDEO_DECODER_SUB:
+ case RMS_CATEGORY_JPEG_DECODER:
+ case RMS_CATEGORY_MJPEG_DECODER:
+ case RMS_CATEGORY_JPEG_DECODER_FHD:
+ case RMS_CATEGORY_JPEG_DECODER_UHD:
+ case RMS_CATEGORY_JPEG_DECODER_8K:
+ case RMS_CATEGORY_MJPEG_DECODER_FHD:
+ case RMS_CATEGORY_MJPEG_DECODER_UHD:
+ case RMS_CATEGORY_MJPEG_DECODER_8K:
+ case RMS_CATEGORY_HEIC_DECODER:
+ result = true;
+ break;
+ default:
+ result = false;
+ break;
+ }
+
+ if (category > RMS_CATEGORY_VIDEO_DECODER_OPTION && category < RMS_CATEGORY_VIDEO_DECODER_OPTION_MAX)
+ result = true;
+
+ return result;
+}
+
+bool CAllocateStrategyProvider::IsNDecordingVideoDecoderCategory(int category_class)
+{
+ return (category_class == RMS_CATEGORY_CLASS_N_DECODING);
+}
+
+bool CAllocateStrategyProvider::IsBGScalerCategory(rms_rsc_category_e category)
+{
+ return (category == RMS_CATEGORY_SCALER_BG);
+}
+
+bool CAllocateStrategyProvider::IsMultiviewScalerCategory(rms_rsc_category_e category)
+{
+ return (category == RMS_CATEGORY_SCALER_MULTIVIEW || category == RMS_CATEGORY_SCALER_INTERLACED);
+}
+
+bool CAllocateStrategyProvider::IsSubScalerCategory(rms_rsc_category_e category)
+{
+ bool result = false;
+
+ switch (category) {
+ case RMS_CATEGORY_SCALER_SUB:
+ case RMS_CATEGORY_SCALER_SUB2:
+ case RMS_CATEGORY_SCALER_SUB3:
+ result = true;
+ break;
+ default:
+ result = false;
+ break;
+ }
+
+ return result;
+}
+
+CAllocateStrategyProvider *CAllocateStrategyProvider::getInstance()
+{
+ if (!m_instance)
+ m_instance = new CAllocateStrategyProvider();
+
+ return m_instance;
+}
+
+CAllocateStrategyProvider::~CAllocateStrategyProvider()
+{
+}
+
+CAllocateStrategy *CAllocateStrategyProvider::GetStrategy(rms_rsc_category_e category, int category_class)
+{
+ CAllocateStrategy *strategy = NULL;
+
+ if (IsVideoDecoderCategory(category)) {
+ if (IsNDecordingVideoDecoderCategory(category_class))
+ strategy = new CNDecodingVideoDecoderStrategy();
+ else
+ strategy = new CVideoDecoderStrategy();
+ } else if (IsAudioDecoderCategory(category)) {
+ strategy = new CAudioDecoderStrategy();
+ } else if (IsBGScalerCategory(category) || IsSubScalerCategory(category)) {
+ strategy = new CExclusiveStrategy();
+ } else if (IsMultiviewScalerCategory(category)) {
+ strategy = new CScalerStrategy();
+ } else if (category == RMS_CATEGORY_VIDEO_ENCODER_EXCLUSIVE) {
+ strategy = new CVideoEncoderExclusiveStrategy();
+ } else {
+ strategy = new CNormalStrategy();
+ }
+
+ return strategy;
+}
-/*\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 <map>\r
-#include <rms_type.h>\r
-#include <rms_debug.h>\r
-#include <CResource.h>\r
-#include <CVirtualResource.h>\r
-#include <CRequest.h>\r
-#include <CRequester.h>\r
-#include <CPriority.h>\r
-#include <CAllocateStrategy.h>\r
-#include <CAudioDecoderStrategy.h>\r
-#include <CMixingStrategy.h>\r
-#include <CDependencyController.h>\r
-#include <CSysInfo.h>\r
-\r
-CVirtualResource *CAudioDecoderStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)\r
-{\r
- std::map<int, CVirtualResource*> filtered_vresources;\r
- ExcludeResources(vresources, &filtered_vresources, req);\r
-\r
- req->SetResult(RMS_ERROR);\r
- req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);\r
-\r
- CRequester *requester = req->getRequester();\r
- CMixingStrategy *strategy = CMixingStrategy::getInstance();\r
- bool mixing_supported = CSysInfo::GetInstance()->IsAudioMixingSupported();\r
-\r
- for (auto const &it : filtered_vresources) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *resource = vresource->GetResource();\r
- int device_id = resource->GetDeviceID();\r
-\r
- SERVER_INFO("vresource id(%d), codec(%s)", vresource->GetVResourceID(), vresource->GetAudioCodec().c_str());\r
-\r
- rms_error_type_e reason = RMS_ERR_TYPE_NONE;\r
-\r
- if (mixing_supported) {\r
- if (!strategy->isAvailableMixingMode(req->GetMixingMode())) {\r
- strategy->updateReasonByMixingMode(vresource, req, reason);\r
- continue;\r
- }\r
-\r
- if (!strategy->isAvailableAudioCodec(vresource->GetAudioCodec(), requester->getHandle(), &reason)) {\r
- strategy->updateReasonByAudioCodec(vresource, req, reason);\r
- continue;\r
- }\r
- }\r
-\r
- if (resource->IsReserved())\r
- continue;\r
-\r
- if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
- updateReasonByResourceState(device_id, req);\r
- continue;\r
- }\r
-\r
- return vresource;\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-int CAudioDecoderStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)\r
-{\r
- CResource *rsc = vrsc->GetResource();\r
-\r
- if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)\r
- return RMS_ERROR;\r
-\r
- rsc->UpdateAudioCodec(vrsc->GetAudioCodec());\r
- rsc->updateMixingMode(req->GetMixingMode());\r
-\r
- return RMS_OK;\r
-}\r
-\r
-int CAudioDecoderStrategy::GetRetirableConsumers(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)\r
-{\r
- CResource *resource = vresource->GetResource();\r
- CRequester *requester = req->getRequester();\r
- int cid = requester->getHandle();\r
- rms_error_type_e err;\r
-\r
- SERVER_INFO("vresource id(%d), codec(%s)", vresource->GetVResourceID(), vresource->GetAudioCodec().c_str());\r
-\r
- if (CSysInfo::GetInstance()->IsAudioMixingSupported()) {\r
- CMixingStrategy *strategy = CMixingStrategy::getInstance();\r
-\r
- if (!strategy->isAvailableAudioCodec(vresource->GetAudioCodec(), requester->getHandle(), &err)) {\r
- if (strategy->getReclaimableAudioCodecConsumers(vresource->GetAudioCodec(), cid, req, retirables, err_type) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- if (!strategy->isAvailableMixingMode(req->GetMixingMode())) {\r
- if (strategy->getReclaimableMixingModeConsumers(req->GetMixingMode(), cid, retirables, err_type) != RMS_OK)\r
- goto error;\r
- }\r
- }\r
-\r
- if (!resource->IsFreeState()) {\r
- if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), cid, retirables, err_type) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- return RMS_OK;\r
-\r
-error:\r
- if (!retirables->empty())\r
- retirables->clear();\r
-\r
- return RMS_ERROR;\r
-}\r
-\r
-\r
-void CAudioDecoderStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)\r
-{\r
- std::map<int, int> consumer_list;\r
- std::multimap<unsigned long, CVirtualResource *> filtered_vresources;\r
-\r
- ExcludeResources(vresources, &filtered_vresources, req);\r
-\r
- for (auto const &it : filtered_vresources) {\r
- CVirtualResource *vresource = it.second;\r
-\r
- if (GetRetirableConsumers(vresource, req, retirables, err_type) == RMS_OK)\r
- break;\r
- }\r
-\r
- for (auto const &it : consumer_list) {\r
- retirables->insert(std::pair<int, int>(it.first, it.second));\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 <map>
+#include <rms_type.h>
+#include <rms_debug.h>
+#include <CResource.h>
+#include <CVirtualResource.h>
+#include <CRequest.h>
+#include <CRequester.h>
+#include <CPriority.h>
+#include <CAllocateStrategy.h>
+#include <CAudioDecoderStrategy.h>
+#include <CMixingStrategy.h>
+#include <CDependencyController.h>
+#include <CSysInfo.h>
+
+CVirtualResource *CAudioDecoderStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)
+{
+ std::map<int, CVirtualResource*> filtered_vresources;
+ ExcludeResources(vresources, &filtered_vresources, req);
+
+ req->SetResult(RMS_ERROR);
+ req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);
+
+ CRequester *requester = req->getRequester();
+ CMixingStrategy *strategy = CMixingStrategy::getInstance();
+ bool mixing_supported = CSysInfo::GetInstance()->IsAudioMixingSupported();
+
+ for (auto const &it : filtered_vresources) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+ int device_id = resource->GetDeviceID();
+
+ SERVER_INFO("vresource id(%d), codec(%s)", vresource->GetVResourceID(), vresource->GetAudioCodec().c_str());
+
+ rms_error_type_e reason = RMS_ERR_TYPE_NONE;
+
+ if (mixing_supported) {
+ if (!strategy->isAvailableMixingMode(req->GetMixingMode())) {
+ strategy->updateReasonByMixingMode(vresource, req, reason);
+ continue;
+ }
+
+ if (!strategy->isAvailableAudioCodec(vresource->GetAudioCodec(), requester->getHandle(), &reason)) {
+ strategy->updateReasonByAudioCodec(vresource, req, reason);
+ continue;
+ }
+ }
+
+ if (resource->IsReserved())
+ continue;
+
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {
+ updateReasonByResourceState(device_id, req);
+ continue;
+ }
+
+ return vresource;
+ }
+
+ return NULL;
+}
+
+int CAudioDecoderStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)
+{
+ CResource *rsc = vrsc->GetResource();
+
+ if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)
+ return RMS_ERROR;
+
+ rsc->UpdateAudioCodec(vrsc->GetAudioCodec());
+ rsc->updateMixingMode(req->GetMixingMode());
+
+ return RMS_OK;
+}
+
+int CAudioDecoderStrategy::GetRetirableConsumers(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)
+{
+ CResource *resource = vresource->GetResource();
+ CRequester *requester = req->getRequester();
+ int cid = requester->getHandle();
+ rms_error_type_e err;
+
+ SERVER_INFO("vresource id(%d), codec(%s)", vresource->GetVResourceID(), vresource->GetAudioCodec().c_str());
+
+ if (CSysInfo::GetInstance()->IsAudioMixingSupported()) {
+ CMixingStrategy *strategy = CMixingStrategy::getInstance();
+
+ if (!strategy->isAvailableAudioCodec(vresource->GetAudioCodec(), requester->getHandle(), &err)) {
+ if (strategy->getReclaimableAudioCodecConsumers(vresource->GetAudioCodec(), cid, req, retirables, err_type) != RMS_OK)
+ goto error;
+ }
+
+ if (!strategy->isAvailableMixingMode(req->GetMixingMode())) {
+ if (strategy->getReclaimableMixingModeConsumers(req->GetMixingMode(), cid, retirables, err_type) != RMS_OK)
+ goto error;
+ }
+ }
+
+ if (!resource->IsFreeState()) {
+ if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), cid, retirables, err_type) != RMS_OK)
+ goto error;
+ }
+
+ return RMS_OK;
+
+error:
+ if (!retirables->empty())
+ retirables->clear();
+
+ return RMS_ERROR;
+}
+
+
+void CAudioDecoderStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)
+{
+ std::map<int, int> consumer_list;
+ std::multimap<unsigned long, CVirtualResource *> filtered_vresources;
+
+ ExcludeResources(vresources, &filtered_vresources, req);
+
+ for (auto const &it : filtered_vresources) {
+ CVirtualResource *vresource = it.second;
+
+ if (GetRetirableConsumers(vresource, req, retirables, err_type) == RMS_OK)
+ break;
+ }
+
+ for (auto const &it : consumer_list) {
+ retirables->insert(std::pair<int, int>(it.first, it.second));
+ }
+}
-/*\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
-\r
-#include <rms_debug.h>\r
-#include <CResourceDB.h>\r
-#include <CResource.h>\r
-#include <CVirtualResource.h>\r
-#include <CRequest.h>\r
-#include <CRequester.h>\r
-#include <CPriority.h>\r
-#include <CDependencyController.h>\r
-#include <CAllocateStrategy.h>\r
-#include <CExclusiveStrategy.h>\r
-\r
-void CExclusiveStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)\r
-{\r
- CRequester *requester = req->getRequester();\r
-\r
- if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
- return;\r
- }\r
-\r
- if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle())) {\r
- req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
- return;\r
- }\r
-\r
- if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)\r
- return;\r
-\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
-}\r
-\r
-bool CExclusiveStrategy::isAllocatableResource(CVirtualResource *vresource, CRequest *req)\r
-{\r
- CResource *resource = vresource->GetResource();\r
-\r
- if (resource->IsReserved()) {\r
- SERVER_INFO("device id(%d) is reserved state", resource->GetDeviceID());\r
- return false;\r
- }\r
-\r
- if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters())) {\r
- updateReasonByMemCluster(vresource, req);\r
- return false;\r
- }\r
-\r
- if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
- updateReasonByResourceState(resource->GetDeviceID(), req);\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-bool CExclusiveStrategy::isSharableResource(CVirtualResource *vresource, CRequest *req)\r
-{\r
- CResource *resource = vresource->GetResource();\r
-\r
- if (resource->IsReserved()) {\r
- SERVER_INFO("device id(%d) is reserved state", resource->GetDeviceID());\r
- return false;\r
- }\r
-\r
- if (resource->getSharableCount() <= 0) {\r
- SERVER_INFO("device id(%d) is not sharable state", resource->GetDeviceID());\r
- updateReasonBySharableCount(resource->GetDeviceID(), req);\r
- return false;\r
- }\r
-\r
- if (!CDependencyController::getInstance()->isSharableMemClusters(vresource->GetMemClusters(), resource->GetDeviceID())) {\r
- updateReasonByMemCluster(vresource, req);\r
- return false;\r
- }\r
-\r
- if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
- updateReasonByResourceState(resource->GetDeviceID(), req);\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-CVirtualResource *CExclusiveStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)\r
-{\r
- std::map<int, CVirtualResource *> filtered_vresources;\r
- ExcludeResources(vresources, &filtered_vresources, req);\r
-\r
- req->SetResult(RMS_ERROR);\r
- req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);\r
-\r
- for (auto const &it : filtered_vresources) {\r
- CVirtualResource *vresource = it.second;\r
- bool isReservable = (req->GetState() == RMS_STATE_SHARABLE) ? isSharableResource(vresource, req) : isAllocatableResource(vresource, req);\r
-\r
- SERVER_INFO("is Reservable ? %d", isReservable);\r
-\r
- if (!isReservable)\r
- continue;\r
-\r
- return vresource;\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-int CExclusiveStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)\r
-{\r
- CResource *rsc = vrsc->GetResource();\r
-\r
- if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)\r
- return RMS_ERROR;\r
-\r
- rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());\r
-\r
- return RMS_OK;\r
-}\r
-\r
-bool CExclusiveStrategy::ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources)\r
-{\r
- CDependencyController *dc = CDependencyController::getInstance();\r
-\r
- for (auto const &it : vresources) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *resource = vresource->GetResource();\r
-\r
- if (!dc->isAvailableMemClusters(vresource->GetMemClusters()))\r
- continue;\r
-\r
- if (!resource->IsFreeState())\r
- continue;\r
-\r
- return true;\r
- }\r
-\r
- return false;\r
-}\r
-\r
-bool CExclusiveStrategy::ContainSharableResource(std::multimap<unsigned long, CVirtualResource *> vresources)\r
-{\r
- CDependencyController *dc = CDependencyController::getInstance();\r
-\r
- for (auto const &it : vresources) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *resource = vresource->GetResource();\r
-\r
- if (!dc->isSharableMemClusters(vresource->GetMemClusters(), resource->GetDeviceID()))\r
- continue;\r
-\r
- if (!resource->IsSharableState())\r
- continue;\r
-\r
- return true;\r
- }\r
-\r
- return false;\r
-}\r
-\r
-int CExclusiveStrategy::getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)\r
-{\r
- CDependencyController *dc = CDependencyController::getInstance();\r
- CResource *resource = vresource->GetResource();\r
-\r
- if (!dc->isAvailableMemClusters(vresource->GetMemClusters())) {\r
- if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), req->getRequester()->getHandle(), retirables) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- if (!resource->IsFreeState()) {\r
- if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), req->getRequester()->getHandle(), retirables, err_type) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- return RMS_OK;\r
-\r
-error:\r
- if (!retirables->empty())\r
- retirables->clear();\r
-\r
- return RMS_ERROR;\r
-}\r
-\r
-int CExclusiveStrategy::getRetirableConsumersShare(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)\r
-{\r
- CDependencyController *dc = CDependencyController::getInstance();\r
- CResource *resource = vresource->GetResource();\r
-\r
- if (!dc->isSharableMemClusters(vresource->GetMemClusters(), resource->GetDeviceID())) {\r
- if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), req->getRequester()->getHandle(), retirables) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- if (!resource->IsSharableState()) {\r
- if (CPriority::getReclaimableConsumersShare(resource->GetDeviceID(), req->getRequester()->getHandle(), retirables, err_type) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- return RMS_OK;\r
-\r
-error:\r
- if (!retirables->empty())\r
- retirables->clear();\r
-\r
- return RMS_ERROR;\r
-}\r
-\r
-\r
-void CExclusiveStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)\r
-{\r
- std::multimap<int, int> consumer_list;\r
- std::multimap<unsigned long, CVirtualResource *> filtered_vresources;\r
-\r
- ExcludeResources(vresources, &filtered_vresources, req);\r
-\r
- bool isShareMode = (req->GetState() == RMS_STATE_SHARABLE);\r
- bool hasAllocatableResource = (isShareMode) ? ContainSharableResource(filtered_vresources) : ContainAvailableResource(filtered_vresources);\r
-\r
- if (hasAllocatableResource)\r
- return;\r
-\r
- for (auto const &it : filtered_vresources) {\r
- CVirtualResource *vresource = it.second;\r
-\r
- int result = (isShareMode) ? getRetirableConsumersShare(vresource, req, &consumer_list, err_type) : getRetirableConsumersExclusive(vresource, req, &consumer_list, err_type);\r
-\r
- if (result == RMS_OK)\r
- break;\r
- }\r
-\r
- for (auto const &it : consumer_list) {\r
- retirables->insert(std::pair<int, int>(it.first, it.second));\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 <assert.h>
+
+#include <rms_debug.h>
+#include <CResourceDB.h>
+#include <CResource.h>
+#include <CVirtualResource.h>
+#include <CRequest.h>
+#include <CRequester.h>
+#include <CPriority.h>
+#include <CDependencyController.h>
+#include <CAllocateStrategy.h>
+#include <CExclusiveStrategy.h>
+
+void CExclusiveStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)
+{
+ CRequester *requester = req->getRequester();
+
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+ return;
+ }
+
+ if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle())) {
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);
+ return;
+ }
+
+ if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)
+ return;
+
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+}
+
+bool CExclusiveStrategy::isAllocatableResource(CVirtualResource *vresource, CRequest *req)
+{
+ CResource *resource = vresource->GetResource();
+
+ if (resource->IsReserved()) {
+ SERVER_INFO("device id(%d) is reserved state", resource->GetDeviceID());
+ return false;
+ }
+
+ if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters())) {
+ updateReasonByMemCluster(vresource, req);
+ return false;
+ }
+
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {
+ updateReasonByResourceState(resource->GetDeviceID(), req);
+ return false;
+ }
+
+ return true;
+}
+
+bool CExclusiveStrategy::isSharableResource(CVirtualResource *vresource, CRequest *req)
+{
+ CResource *resource = vresource->GetResource();
+
+ if (resource->IsReserved()) {
+ SERVER_INFO("device id(%d) is reserved state", resource->GetDeviceID());
+ return false;
+ }
+
+ if (resource->getSharableCount() <= 0) {
+ SERVER_INFO("device id(%d) is not sharable state", resource->GetDeviceID());
+ updateReasonBySharableCount(resource->GetDeviceID(), req);
+ return false;
+ }
+
+ if (!CDependencyController::getInstance()->isSharableMemClusters(vresource->GetMemClusters(), resource->GetDeviceID())) {
+ updateReasonByMemCluster(vresource, req);
+ return false;
+ }
+
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {
+ updateReasonByResourceState(resource->GetDeviceID(), req);
+ return false;
+ }
+
+ return true;
+}
+
+CVirtualResource *CExclusiveStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)
+{
+ std::map<int, CVirtualResource *> filtered_vresources;
+ ExcludeResources(vresources, &filtered_vresources, req);
+
+ req->SetResult(RMS_ERROR);
+ req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);
+
+ for (auto const &it : filtered_vresources) {
+ CVirtualResource *vresource = it.second;
+ bool isReservable = (req->GetState() == RMS_STATE_SHARABLE) ? isSharableResource(vresource, req) : isAllocatableResource(vresource, req);
+
+ SERVER_INFO("is Reservable ? %d", isReservable);
+
+ if (!isReservable)
+ continue;
+
+ return vresource;
+ }
+
+ return NULL;
+}
+
+int CExclusiveStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)
+{
+ CResource *rsc = vrsc->GetResource();
+
+ if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)
+ return RMS_ERROR;
+
+ rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());
+
+ return RMS_OK;
+}
+
+bool CExclusiveStrategy::ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources)
+{
+ CDependencyController *dc = CDependencyController::getInstance();
+
+ for (auto const &it : vresources) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters()))
+ continue;
+
+ if (!resource->IsFreeState())
+ continue;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool CExclusiveStrategy::ContainSharableResource(std::multimap<unsigned long, CVirtualResource *> vresources)
+{
+ CDependencyController *dc = CDependencyController::getInstance();
+
+ for (auto const &it : vresources) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+
+ if (!dc->isSharableMemClusters(vresource->GetMemClusters(), resource->GetDeviceID()))
+ continue;
+
+ if (!resource->IsSharableState())
+ continue;
+
+ return true;
+ }
+
+ return false;
+}
+
+int CExclusiveStrategy::getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)
+{
+ CDependencyController *dc = CDependencyController::getInstance();
+ CResource *resource = vresource->GetResource();
+
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters())) {
+ if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), req->getRequester()->getHandle(), retirables) != RMS_OK)
+ goto error;
+ }
+
+ if (!resource->IsFreeState()) {
+ if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), req->getRequester()->getHandle(), retirables, err_type) != RMS_OK)
+ goto error;
+ }
+
+ return RMS_OK;
+
+error:
+ if (!retirables->empty())
+ retirables->clear();
+
+ return RMS_ERROR;
+}
+
+int CExclusiveStrategy::getRetirableConsumersShare(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)
+{
+ CDependencyController *dc = CDependencyController::getInstance();
+ CResource *resource = vresource->GetResource();
+
+ if (!dc->isSharableMemClusters(vresource->GetMemClusters(), resource->GetDeviceID())) {
+ if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), req->getRequester()->getHandle(), retirables) != RMS_OK)
+ goto error;
+ }
+
+ if (!resource->IsSharableState()) {
+ if (CPriority::getReclaimableConsumersShare(resource->GetDeviceID(), req->getRequester()->getHandle(), retirables, err_type) != RMS_OK)
+ goto error;
+ }
+
+ return RMS_OK;
+
+error:
+ if (!retirables->empty())
+ retirables->clear();
+
+ return RMS_ERROR;
+}
+
+
+void CExclusiveStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)
+{
+ std::multimap<int, int> consumer_list;
+ std::multimap<unsigned long, CVirtualResource *> filtered_vresources;
+
+ ExcludeResources(vresources, &filtered_vresources, req);
+
+ bool isShareMode = (req->GetState() == RMS_STATE_SHARABLE);
+ bool hasAllocatableResource = (isShareMode) ? ContainSharableResource(filtered_vresources) : ContainAvailableResource(filtered_vresources);
+
+ if (hasAllocatableResource)
+ return;
+
+ for (auto const &it : filtered_vresources) {
+ CVirtualResource *vresource = it.second;
+
+ int result = (isShareMode) ? getRetirableConsumersShare(vresource, req, &consumer_list, err_type) : getRetirableConsumersExclusive(vresource, req, &consumer_list, err_type);
+
+ if (result == RMS_OK)
+ break;
+ }
+
+ for (auto const &it : consumer_list) {
+ retirables->insert(std::pair<int, int>(it.first, it.second));
+ }
+}
-/*\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 <algorithm>\r
-#include <vector>\r
-#include <rms_debug.h>\r
-#include <rms_type.h>\r
-#include <CRequest.h>\r
-#include <CAllocateModeStrategy.h>\r
-#include <CInvalidModeStrategy.h>\r
-\r
-CInvalidModeStrategy::CInvalidModeStrategy()\r
-{\r
-}\r
-\r
-CInvalidModeStrategy::~CInvalidModeStrategy()\r
-{\r
-}\r
-\r
-bool CInvalidModeStrategy::CanAllocateResources(std::vector<CRequest *> requests, rms_allocate_result_s *result)\r
-{\r
- result->result = RMS_ERROR;\r
- result->reason = RMS_ERR_TYPE_INVALID_REQUEST;\r
-\r
- SERVER_ERR("Invalid request set");\r
- std::for_each(requests.begin(), requests.end(), [](CRequest *req) { SERVER_ERR("req state(%d)", req->GetState()); });\r
-\r
- return false;\r
-}\r
-\r
-void CInvalidModeStrategy::WriteAllocResult(rms_allocate_result_s *alloc_result, std::vector<CRequest *> requests, rms_return_device_s *allocated_devices)\r
-{\r
- assert(allocated_devices);\r
-\r
- allocated_devices->result = RMS_ERROR;\r
- allocated_devices->error_type = RMS_ERR_TYPE_INVALID_REQUEST;\r
- allocated_devices->resources_num = 0;\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 <algorithm>
+#include <vector>
+#include <rms_debug.h>
+#include <rms_type.h>
+#include <CRequest.h>
+#include <CAllocateModeStrategy.h>
+#include <CInvalidModeStrategy.h>
+
+CInvalidModeStrategy::CInvalidModeStrategy()
+{
+}
+
+CInvalidModeStrategy::~CInvalidModeStrategy()
+{
+}
+
+bool CInvalidModeStrategy::CanAllocateResources(std::vector<CRequest *> requests, rms_allocate_result_s *result)
+{
+ result->result = RMS_ERROR;
+ result->reason = RMS_ERR_TYPE_INVALID_REQUEST;
+
+ SERVER_ERR("Invalid request set");
+ std::for_each(requests.begin(), requests.end(), [](CRequest *req) { SERVER_ERR("req state(%d)", req->GetState()); });
+
+ return false;
+}
+
+void CInvalidModeStrategy::WriteAllocResult(rms_allocate_result_s *alloc_result, std::vector<CRequest *> requests, rms_return_device_s *allocated_devices)
+{
+ assert(allocated_devices);
+
+ allocated_devices->result = RMS_ERROR;
+ allocated_devices->error_type = RMS_ERR_TYPE_INVALID_REQUEST;
+ allocated_devices->resources_num = 0;
+}
-/*\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
-\r
-#include <rms_type.h>\r
-#include <rms_debug.h>\r
-#include <CVirtualResource.h>\r
-#include <CConsumer.h>\r
-#include <CResourceManager.h>\r
-#include <CRequest.h>\r
-#include <CRequester.h>\r
-#include <CMixingMode.h>\r
-#include <CResourceObserver.h>\r
-#include <CDependencyController.h>\r
-#include <CPriority.h>\r
-#include <CAudioCodec.h>\r
-#include <CAudioCodecCollection.h>\r
-#include <CMixingStrategy.h>\r
-\r
-CMixingStrategy *CMixingStrategy::m_instance = NULL;\r
-\r
-CMixingStrategy *CMixingStrategy::getInstance(void)\r
-{\r
- if (!m_instance)\r
- m_instance = new CMixingStrategy();\r
-\r
- return m_instance;\r
-}\r
-\r
-bool CMixingStrategy::isAvailableAudioCodec(std::string name, int consumer_id, rms_error_type_e *reason)\r
-{\r
- CAudioCodec *audio_codec = CAudioCodecCollection::getInstance()->findAudioCodec(name.c_str());\r
- CDependencyController *dc = CDependencyController::getInstance();\r
-\r
- if (!audio_codec) {\r
- SERVER_ERR("not existing audio codec (%s)", name.c_str());\r
- *reason = RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST;\r
- return false;\r
- }\r
-\r
- if (!audio_codec->isMixingSupported() && dc->isAudioCodecBeingUsed()) {\r
- SERVER_ERR("mixing not supported (%s)", name.c_str());\r
- return false;\r
- }\r
-\r
- if (!dc->isAvailableAudioCodec(name)) {\r
- SERVER_ERR("not available audio codec (%s)", name.c_str());\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-int CMixingStrategy::getReclaimableAudioCodecConsumers(std::string codec_name, int consumer_id, CRequest *req, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)\r
-{\r
- CDependencyController *dc = CDependencyController::getInstance();\r
- CAudioCodec *codec = CAudioCodecCollection::getInstance()->findAudioCodec(codec_name);\r
-\r
- if (!codec)\r
- return RMS_ERROR;\r
-\r
- std::map<unsigned long, std::pair<int, int>> acodec_consumers = dc->getAudioCodecConsumers();\r
-\r
- if (!codec->isMixingSupported() && dc->isAudioCodecBeingUsed()) {\r
- for (auto const &it : acodec_consumers) {\r
- if (!CPriority::isReclaimableConsumer(it.second.second, consumer_id, err_type))\r
- return RMS_ERROR;\r
-\r
- reclaimables->insert(std::pair<int, int>(it.second.first, it.second.second));\r
- }\r
-\r
- return RMS_OK;\r
- }\r
-\r
- if (!dc->isAvailableAudioCodec(codec_name)) {\r
- for (auto const &it : acodec_consumers) {\r
- CResource *rsc = CResourceDB::getInstance()->FindResource(it.second.first);\r
- if (req->IsMainDeviceRequest() && !rsc->IsMainDevice())\r
- continue;\r
- if (req->IsSubDeviceRequest() && rsc->IsMainDevice())\r
- continue;\r
- if (!CPriority::isReclaimableConsumer(it.second.second, consumer_id, err_type))\r
- continue;\r
-\r
- reclaimables->insert(std::pair<int, int>(it.second.first, it.second.second));\r
- return RMS_OK;\r
- }\r
- }\r
-\r
- return RMS_ERROR;\r
-\r
-}\r
-\r
-bool CMixingStrategy::isAvailableMixingMode(rms_mixing_mode_e mode)\r
-{\r
- CMixingMode *cur_mode = CDependencyController::getInstance()->getCurMixingMode();\r
-\r
- if (!cur_mode)\r
- return true;\r
-\r
- SERVER_INFO("cur_mode(%d)/requested(%d)", cur_mode->getMode(), mode);\r
-\r
- return (mode == cur_mode->getMode());\r
-}\r
-\r
-int CMixingStrategy::getReclaimableMixingModeConsumers(rms_mixing_mode_e mode, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)\r
-{\r
- CMixingMode *cur_mode = CDependencyController::getInstance()->getCurMixingMode();\r
-\r
- if (!cur_mode) {\r
- SERVER_ERR("there is no mixing mode to reclaim");\r
- return RMS_ERROR;\r
- }\r
-\r
- SERVER_INFO("cur mixing mode (%d), requested codec (%d)", cur_mode->getMode(), mode);\r
-\r
- std::map<int, int> consumers = cur_mode->GetConsumers();\r
-\r
- if (consumers.size() == 0) {\r
- SERVER_ERR("no consumer to reclaim in mixing mode(%d)", cur_mode->getMode());\r
- return RMS_ERROR;\r
- }\r
-\r
- for (auto const &it_consumer : consumers) {\r
- if (!CPriority::isReclaimableConsumer(it_consumer.second, consumer_id, err_type))\r
- return RMS_ERROR;\r
-\r
- reclaimables->insert(std::pair<int, int>(it_consumer.first, it_consumer.second));\r
- }\r
-\r
- return RMS_OK;\r
-}\r
-\r
-bool CMixingStrategy::canReclaimMixingMode(rms_mixing_mode_e mode, CMixingMode *cur_mode, int consumer_id)\r
-{\r
- std::map<int, int> consumers = cur_mode->GetConsumers();\r
-\r
- if (consumers.size() == 0) {\r
- SERVER_ERR("no consumer to reclaim in mixing mode(%d)", cur_mode->getMode());\r
- return false;\r
- }\r
-\r
- for (auto const &it_consumer : consumers) {\r
- if (!CPriority::isReclaimableConsumer(it_consumer.second, consumer_id, NULL))\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-bool CMixingStrategy::canReclaimMixingMode(rms_mixing_mode_e mode, int consumer_id)\r
-{\r
- CMixingMode *mixing_mode = CDependencyController::getInstance()->getCurMixingMode();\r
-\r
- return (mixing_mode != NULL) ? canReclaimMixingMode(mode, mixing_mode, consumer_id) : false;\r
-}\r
-\r
-void CMixingStrategy::updateReasonByMixingMode(CVirtualResource *vresource, CRequest *req, rms_error_type_e cur_reason)\r
-{\r
- CRequester *requester = req->getRequester();\r
-\r
- if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
- return;\r
- }\r
-\r
- if (!needReclaimCheck(cur_reason)) {\r
- req->SetReason(cur_reason);\r
- return;\r
- }\r
-\r
- if (canReclaimMixingMode(req->GetMixingMode(), requester->getHandle())) {\r
- req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
- return;\r
- }\r
-\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
-\r
-}\r
-\r
-void CMixingStrategy::updateReasonByAudioCodec(CVirtualResource *vresource, CRequest *req, rms_error_type_e cur_reason)\r
-{\r
- CRequester *requester = req->getRequester();\r
-\r
- if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
- return;\r
- }\r
-\r
- if (!needReclaimCheck(cur_reason)) {\r
- req->SetReason(cur_reason);\r
- return;\r
- }\r
-\r
- if (canReclaimAudioCodec(vresource->GetAudioCodec(), requester->getHandle())) {\r
- req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
- return;\r
- }\r
-\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
-}\r
-\r
-bool CMixingStrategy::needReclaimCheck(rms_error_type_e reason)\r
-{\r
- bool result = false;\r
-\r
- switch (reason) {\r
- case RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER:\r
- case RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST:\r
- SERVER_ERR("erro case : %d", reason);\r
- result = false;\r
- break;\r
- default:\r
- result = true;\r
- break;\r
- }\r
-\r
- return result;\r
-}\r
-\r
-bool CMixingStrategy::canReclaimAudioCodec(std::string codec_name, int consumer_id)\r
-{\r
- CDependencyController *dc = CDependencyController::getInstance();\r
- CAudioCodec *codec = CAudioCodecCollection::getInstance()->findAudioCodec(codec_name);\r
-\r
- if (!codec)\r
- return false;\r
-\r
- std::map<unsigned long, std::pair<int, int>> acodec_consumers = dc->getAudioCodecConsumers();\r
- rms_error_type_e err_type;\r
-\r
- if (!codec->isMixingSupported() && dc->isAudioCodecBeingUsed()) {\r
- for (auto const &it : acodec_consumers)\r
- {\r
- if (!CPriority::isReclaimableConsumer(it.second.second, consumer_id, &err_type))\r
- return false;\r
- }\r
-\r
- return true;\r
- }\r
-\r
- if (!dc->isAvailableAudioCodec(codec_name)) {\r
- for (auto const &it : acodec_consumers) {\r
- if (!CPriority::isReclaimableConsumer(it.second.second, consumer_id, &err_type))\r
- continue;\r
-\r
- return true;\r
- }\r
- }\r
-\r
- return false;\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 <stdlib.h>
+
+#include <rms_type.h>
+#include <rms_debug.h>
+#include <CVirtualResource.h>
+#include <CConsumer.h>
+#include <CResourceManager.h>
+#include <CRequest.h>
+#include <CRequester.h>
+#include <CMixingMode.h>
+#include <CResourceObserver.h>
+#include <CDependencyController.h>
+#include <CPriority.h>
+#include <CAudioCodec.h>
+#include <CAudioCodecCollection.h>
+#include <CMixingStrategy.h>
+
+CMixingStrategy *CMixingStrategy::m_instance = NULL;
+
+CMixingStrategy *CMixingStrategy::getInstance(void)
+{
+ if (!m_instance)
+ m_instance = new CMixingStrategy();
+
+ return m_instance;
+}
+
+bool CMixingStrategy::isAvailableAudioCodec(std::string name, int consumer_id, rms_error_type_e *reason)
+{
+ CAudioCodec *audio_codec = CAudioCodecCollection::getInstance()->findAudioCodec(name.c_str());
+ CDependencyController *dc = CDependencyController::getInstance();
+
+ if (!audio_codec) {
+ SERVER_ERR("not existing audio codec (%s)", name.c_str());
+ *reason = RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST;
+ return false;
+ }
+
+ if (!audio_codec->isMixingSupported() && dc->isAudioCodecBeingUsed()) {
+ SERVER_ERR("mixing not supported (%s)", name.c_str());
+ return false;
+ }
+
+ if (!dc->isAvailableAudioCodec(name)) {
+ SERVER_ERR("not available audio codec (%s)", name.c_str());
+ return false;
+ }
+
+ return true;
+}
+
+int CMixingStrategy::getReclaimableAudioCodecConsumers(std::string codec_name, int consumer_id, CRequest *req, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)
+{
+ CDependencyController *dc = CDependencyController::getInstance();
+ CAudioCodec *codec = CAudioCodecCollection::getInstance()->findAudioCodec(codec_name);
+
+ if (!codec)
+ return RMS_ERROR;
+
+ std::map<unsigned long, std::pair<int, int>> acodec_consumers = dc->getAudioCodecConsumers();
+
+ if (!codec->isMixingSupported() && dc->isAudioCodecBeingUsed()) {
+ for (auto const &it : acodec_consumers) {
+ if (!CPriority::isReclaimableConsumer(it.second.second, consumer_id, err_type))
+ return RMS_ERROR;
+
+ reclaimables->insert(std::pair<int, int>(it.second.first, it.second.second));
+ }
+
+ return RMS_OK;
+ }
+
+ if (!dc->isAvailableAudioCodec(codec_name)) {
+ for (auto const &it : acodec_consumers) {
+ CResource *rsc = CResourceDB::getInstance()->FindResource(it.second.first);
+ if (req->IsMainDeviceRequest() && !rsc->IsMainDevice())
+ continue;
+ if (req->IsSubDeviceRequest() && rsc->IsMainDevice())
+ continue;
+ if (!CPriority::isReclaimableConsumer(it.second.second, consumer_id, err_type))
+ continue;
+
+ reclaimables->insert(std::pair<int, int>(it.second.first, it.second.second));
+ return RMS_OK;
+ }
+ }
+
+ return RMS_ERROR;
+
+}
+
+bool CMixingStrategy::isAvailableMixingMode(rms_mixing_mode_e mode)
+{
+ CMixingMode *cur_mode = CDependencyController::getInstance()->getCurMixingMode();
+
+ if (!cur_mode)
+ return true;
+
+ SERVER_INFO("cur_mode(%d)/requested(%d)", cur_mode->getMode(), mode);
+
+ return (mode == cur_mode->getMode());
+}
+
+int CMixingStrategy::getReclaimableMixingModeConsumers(rms_mixing_mode_e mode, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)
+{
+ CMixingMode *cur_mode = CDependencyController::getInstance()->getCurMixingMode();
+
+ if (!cur_mode) {
+ SERVER_ERR("there is no mixing mode to reclaim");
+ return RMS_ERROR;
+ }
+
+ SERVER_INFO("cur mixing mode (%d), requested codec (%d)", cur_mode->getMode(), mode);
+
+ std::map<int, int> consumers = cur_mode->GetConsumers();
+
+ if (consumers.size() == 0) {
+ SERVER_ERR("no consumer to reclaim in mixing mode(%d)", cur_mode->getMode());
+ return RMS_ERROR;
+ }
+
+ for (auto const &it_consumer : consumers) {
+ if (!CPriority::isReclaimableConsumer(it_consumer.second, consumer_id, err_type))
+ return RMS_ERROR;
+
+ reclaimables->insert(std::pair<int, int>(it_consumer.first, it_consumer.second));
+ }
+
+ return RMS_OK;
+}
+
+bool CMixingStrategy::canReclaimMixingMode(rms_mixing_mode_e mode, CMixingMode *cur_mode, int consumer_id)
+{
+ std::map<int, int> consumers = cur_mode->GetConsumers();
+
+ if (consumers.size() == 0) {
+ SERVER_ERR("no consumer to reclaim in mixing mode(%d)", cur_mode->getMode());
+ return false;
+ }
+
+ for (auto const &it_consumer : consumers) {
+ if (!CPriority::isReclaimableConsumer(it_consumer.second, consumer_id, NULL))
+ return false;
+ }
+
+ return true;
+}
+
+bool CMixingStrategy::canReclaimMixingMode(rms_mixing_mode_e mode, int consumer_id)
+{
+ CMixingMode *mixing_mode = CDependencyController::getInstance()->getCurMixingMode();
+
+ return (mixing_mode != NULL) ? canReclaimMixingMode(mode, mixing_mode, consumer_id) : false;
+}
+
+void CMixingStrategy::updateReasonByMixingMode(CVirtualResource *vresource, CRequest *req, rms_error_type_e cur_reason)
+{
+ CRequester *requester = req->getRequester();
+
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+ return;
+ }
+
+ if (!needReclaimCheck(cur_reason)) {
+ req->SetReason(cur_reason);
+ return;
+ }
+
+ if (canReclaimMixingMode(req->GetMixingMode(), requester->getHandle())) {
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);
+ return;
+ }
+
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+
+}
+
+void CMixingStrategy::updateReasonByAudioCodec(CVirtualResource *vresource, CRequest *req, rms_error_type_e cur_reason)
+{
+ CRequester *requester = req->getRequester();
+
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+ return;
+ }
+
+ if (!needReclaimCheck(cur_reason)) {
+ req->SetReason(cur_reason);
+ return;
+ }
+
+ if (canReclaimAudioCodec(vresource->GetAudioCodec(), requester->getHandle())) {
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);
+ return;
+ }
+
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+}
+
+bool CMixingStrategy::needReclaimCheck(rms_error_type_e reason)
+{
+ bool result = false;
+
+ switch (reason) {
+ case RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER:
+ case RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST:
+ SERVER_ERR("erro case : %d", reason);
+ result = false;
+ break;
+ default:
+ result = true;
+ break;
+ }
+
+ return result;
+}
+
+bool CMixingStrategy::canReclaimAudioCodec(std::string codec_name, int consumer_id)
+{
+ CDependencyController *dc = CDependencyController::getInstance();
+ CAudioCodec *codec = CAudioCodecCollection::getInstance()->findAudioCodec(codec_name);
+
+ if (!codec)
+ return false;
+
+ std::map<unsigned long, std::pair<int, int>> acodec_consumers = dc->getAudioCodecConsumers();
+ rms_error_type_e err_type;
+
+ if (!codec->isMixingSupported() && dc->isAudioCodecBeingUsed()) {
+ for (auto const &it : acodec_consumers)
+ {
+ if (!CPriority::isReclaimableConsumer(it.second.second, consumer_id, &err_type))
+ return false;
+ }
+
+ return true;
+ }
+
+ if (!dc->isAvailableAudioCodec(codec_name)) {
+ for (auto const &it : acodec_consumers) {
+ if (!CPriority::isReclaimableConsumer(it.second.second, consumer_id, &err_type))
+ continue;
+
+ 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 <assert.h>\r
-\r
-#include <rms_debug.h>\r
-#include <CResourceDB.h>\r
-#include <CBandwidth.h>\r
-#include <CResource.h>\r
-#include <CVirtualResource.h>\r
-#include <CRequest.h>\r
-#include <CRequester.h>\r
-#include <CPriority.h>\r
-#include <CDependencyController.h>\r
-#include <CAllocateStrategy.h>\r
-#include <CNDecodingVideoDecoderStrategy.h>\r
-\r
-void CNDecodingVideoDecoderStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)\r
-{\r
- CRequester *requester = req->getRequester();\r
-\r
- if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
- return;\r
- }\r
-\r
- if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle())) {\r
- req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
- return;\r
- }\r
-\r
- if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)\r
- return;\r
-\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
-}\r
-\r
-void CNDecodingVideoDecoderStrategy::updateReasonByBW(CVirtualResource *vresource, CRequest *req)\r
-{\r
- if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
- return;\r
- }\r
-\r
- rms_error_type_e reason = canReclaimRequiredBW(req, vresource->GetBW()) ?\r
- RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER : RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;\r
- req->SetReason(reason);\r
-}\r
-\r
-void CNDecodingVideoDecoderStrategy::updateReasonByTripleDecoding(CRequest *req)\r
-{\r
- if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
- return;\r
- }\r
-\r
- rms_error_type_e reason = canReclaimActiveVideoDecoders(req) ?\r
- RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER : RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;\r
- req->SetReason(reason);\r
-}\r
-\r
-bool CNDecodingVideoDecoderStrategy::isAllocatableResource(CVirtualResource *vresource, CRequest *req)\r
-{\r
- int category_class = vresource->GetCategoryClass();\r
- CResource *resource = vresource->GetResource();\r
-\r
- if (resource->IsReserved()) {\r
- SERVER_INFO("device id(%d) is reserved state", resource->GetDeviceID());\r
- return false;\r
- }\r
-\r
- if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters(), category_class, vresource->GetCategoryType())) {\r
- updateReasonByMemCluster(vresource, req);\r
- return false;\r
- }\r
-\r
- CBandwidth *bandwidth = CBandwidth::GetInstance();\r
- if ((bandwidth->GetNConsumersNDec(vresource->GetCategoryType()) == 0) && (vresource->GetBW() > bandwidth->GetAvail())) {\r
- SERVER_INFO("insufficient BW required(%d)/avail(%d)", vresource->GetBW(), bandwidth->GetAvail());\r
- updateReasonByBW(vresource, req);\r
- return false;\r
- }\r
-\r
- if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
- updateReasonByResourceState(resource->GetDeviceID(), req);\r
- return false;\r
- }\r
-\r
- if (!CResourceDB::getInstance()->HasAvailableDecoderNDecoding()) {\r
- updateReasonByTripleDecoding(req);\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-CVirtualResource *CNDecodingVideoDecoderStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)\r
-{\r
- std::map<int, CVirtualResource *> filtered_vresources;\r
- ExcludeResources(vresources, &filtered_vresources, req);\r
-\r
- req->SetResult(RMS_ERROR);\r
- req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);\r
-\r
- for (auto const &it : filtered_vresources) {\r
- CVirtualResource *vresource = it.second;\r
- if (!isAllocatableResource(vresource, req))\r
- continue;\r
-\r
- return vresource;\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-int CNDecodingVideoDecoderStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)\r
-{\r
- CResource *rsc = vrsc->GetResource();\r
-\r
- if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)\r
- return RMS_ERROR;\r
-\r
- rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());\r
-\r
- return RMS_OK;\r
-}\r
-\r
-bool CNDecodingVideoDecoderStrategy::ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources)\r
-{\r
-\r
- CDependencyController *dc = CDependencyController::getInstance();\r
- CBandwidth *bandwidth = CBandwidth::GetInstance();\r
-\r
- for (auto const &it : vresources) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *resource = vresource->GetResource();\r
- int category_class = vresource->GetCategoryClass();\r
-\r
- if (!dc->isAvailableMemClusters(vresource->GetMemClusters(), category_class, vresource->GetCategoryType()))\r
- continue;\r
-\r
- if ((bandwidth->GetNConsumersNDec(vresource->GetCategoryType()) == 0) && (bandwidth->GetAvail() < vresource->GetBW()))\r
- continue;\r
-\r
- if (!resource->IsFreeState())\r
- continue;\r
-\r
- if (!CResourceDB::getInstance()->HasAvailableDecoderNDecoding())\r
- continue;\r
-\r
- return true;\r
- }\r
-\r
- return false;\r
-}\r
-\r
-int CNDecodingVideoDecoderStrategy::getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)\r
-{\r
- CDependencyController *dc = CDependencyController::getInstance();\r
- CResourceDB *resource_db = CResourceDB::getInstance();\r
- CResource *resource = vresource->GetResource();\r
- CBandwidth *bandwidth = CBandwidth::GetInstance();\r
- int requester_id = req->getRequester()->getHandle();\r
- int category_class = vresource->GetCategoryClass();\r
-\r
- if (!dc->isAvailableMemClusters(vresource->GetMemClusters(), category_class, vresource->GetCategoryType())) {\r
- if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), requester_id, retirables) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- if ((bandwidth->GetNConsumersNDec(vresource->GetCategoryType()) == 0) && ((bandwidth->GetAvail() + GetReclaimedBW(retirables)) < vresource->GetBW())) {\r
- if (GetConsumerUsingBW(req, vresource->GetBW(), retirables) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- if (!resource->IsFreeState()) {\r
- if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), requester_id, retirables, err_type) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- if (!resource_db->HasAvailableDecoderNDecoding(*retirables)) {\r
- if (GetReclaimableVideoDecoderConsumers(requester_id, retirables, req, err_type) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- return RMS_OK;\r
-error:\r
- if (!retirables->empty())\r
- retirables->clear();\r
-\r
- return RMS_ERROR;\r
-}\r
-\r
-void CNDecodingVideoDecoderStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)\r
-{\r
- std::multimap<int, int> consumer_list;\r
- std::multimap<unsigned long, CVirtualResource *> filtered_vresources;\r
- bool included = false;\r
-\r
- ExcludeResources(vresources, &filtered_vresources, req);\r
-\r
- if (ContainAvailableResource(filtered_vresources))\r
- return;\r
-\r
- for (auto const &it : filtered_vresources) {\r
- CVirtualResource *vresource = it.second;\r
- included = false;\r
- CResource *rsc = vresource->GetResource();\r
- SERVER_INFO("vrsc(%d)/rsc(%d)", vresource->GetVResourceID(), rsc->GetDeviceID());\r
- if (getRetirableConsumersExclusive(vresource, req, &consumer_list, err_type) == RMS_OK) {\r
- for (auto const &it_c : consumer_list) {\r
- auto it_r = retirables->find(it_c.first);\r
- if (it_r != retirables->end()) {\r
- included = true;\r
- SERVER_INFO("(%d:%d) is already in the list", it_c.first, it_c.second);\r
- break;\r
- }\r
- }\r
- if (included)\r
- continue;\r
-\r
- break;\r
- }\r
- }\r
-\r
- retirables->insert(consumer_list.begin(), consumer_list.end());\r
-}\r
-\r
-bool CNDecodingVideoDecoderStrategy::canReclaimRequiredBW(CRequest *req, unsigned int bw)\r
-{\r
- CRequester *requester = req->getRequester();\r
- CResourceDB *resource_db = CResourceDB::getInstance();\r
- CBandwidth *bandwidth = CBandwidth::GetInstance();\r
- unsigned int check_available = bandwidth->GetAvail();\r
- std::map<int, int> bw_consumers = bandwidth->GetConsumers();\r
-\r
- for (std::map<int, int>::iterator it = bw_consumers.begin(); it != bw_consumers.end(); it++) {\r
- int device_id = (*it).first;\r
- int consumer_id = (*it).second;\r
-\r
- CResource *pRsc = resource_db->FindResource(device_id);\r
-\r
- if (!pRsc) {\r
- SERVER_ERR("cannot find resource using device id");\r
- continue;\r
- }\r
-\r
- if (requester->getHandle() == consumer_id) {\r
- SERVER_INFO("CID[%d] is using BW (%d)", requester->getHandle(), pRsc->GetBW());\r
- continue;\r
- }\r
-\r
- if (CPriority::compare(consumer_id, requester->getHandle()) != HIGH_PRIORITY)\r
- continue;\r
-\r
- check_available += pRsc->GetBW();\r
-\r
- if (bw <= check_available)\r
- break;\r
-\r
- SERVER_INFO("DevID[%d]/ need more resource to be released!!! required BW(%d)-resource BW(%d)-check(%d)", pRsc->GetDeviceID(), bw, pRsc->GetBW(), check_available); \r
-\r
- }\r
-\r
- SERVER_INFO("required BW(%d) - available (%d)", bw, check_available);\r
-\r
- return (bw <= check_available);\r
-}\r
-\r
-void CNDecodingVideoDecoderStrategy::SelectDevicesByMainSub(CRequest *req, std::map<int, int> *src, std::map<int, int> *result)\r
-{\r
- CResourceDB *db = CResourceDB::getInstance();\r
-\r
- for (auto const &it : *src) {\r
- CResource *rsc = db->FindResource(it.first);\r
- if (!rsc)\r
- continue;\r
- if (req->IsMainDeviceRequest() && !rsc->IsMainDevice())\r
- continue;\r
- if (req->IsSubDeviceRequest() && rsc->IsMainDevice())\r
- continue;\r
-\r
- result->insert(std::pair<int, int>(it.first, it.second));\r
- }\r
-}\r
-\r
-int CNDecodingVideoDecoderStrategy::GetConsumerUsingBW(CRequest *req, unsigned int bw, std::multimap<int, int>* return_ids)\r
-{\r
- std::map<int, int> candidates;\r
- std::map<int, int> cur_consumers = CBandwidth::GetInstance()->GetConsumers(); //device id, consumer id\r
-\r
- SelectDevicesByMainSub(req, &cur_consumers, &candidates);\r
-\r
- std::multimap<int, int> reclaimed_by_ms;\r
- unsigned int avail_bw = GetConsumerUsingBWByAllocationTime(req->getRequester()->getHandle(), bw, candidates, &reclaimed_by_ms);\r
-\r
- if (avail_bw >= bw) {\r
- return_ids->insert(reclaimed_by_ms.begin(), reclaimed_by_ms.end());\r
- return RMS_OK;\r
- }\r
-\r
- std::multimap<int, int> reclaimed_by_t;\r
- GetConsumerUsingBWByAllocationTime(req->getRequester()->getHandle(), bw, cur_consumers, &reclaimed_by_t);\r
- return_ids->insert(reclaimed_by_t.begin(), reclaimed_by_t.end());\r
-\r
- return RMS_OK;\r
-}\r
-\r
-int CNDecodingVideoDecoderStrategy::GetConsumerUsingBWByAllocationTime(int requester_id, unsigned int required_bw, std::map<int, int> bw_consumers, std::multimap<int, int>* reclaimed_consumers)\r
-{\r
- assert(reclaimed_consumers);\r
-\r
- CResourceDB *resource_db = CResourceDB::getInstance();\r
- CBandwidth *bandwidth = CBandwidth::GetInstance();\r
-\r
- SERVER_INFO("candidates using BW : %zu", bw_consumers.size());\r
- unsigned int reclaimed_bw = bandwidth->GetAvail();\r
-\r
- std::map<unsigned long, int> consumers_by_t;\r
- for (auto const &itc : bw_consumers) {\r
- CResource *rsc = resource_db->FindResource(itc.first);\r
- if (!rsc)\r
- continue;\r
-\r
- consumers_by_t.insert(std::pair<unsigned long, int>(rsc->GetAllocatedTime(), itc.first));\r
- }\r
-\r
- for (auto const &it : consumers_by_t) {\r
- int device_id = it.second;\r
- CResource *pRsc = resource_db->FindResource(device_id);\r
- if (!pRsc)\r
- continue;\r
-\r
- int consumer_id = pRsc->GetFirstConsumer();\r
- SERVER_INFO("consumer (%d) is using bw for device (%d)", consumer_id, device_id);\r
-\r
- if (requester_id == consumer_id) {\r
- SERVER_INFO("CID[%d] is using BW (%d)", requester_id, pRsc->GetBW());\r
- continue;\r
- }\r
-\r
- if (CPriority::compare(consumer_id, requester_id) != HIGH_PRIORITY)\r
- continue;\r
-\r
- auto ret = reclaimed_consumers->find(device_id);\r
- if (ret != reclaimed_consumers->end()) {\r
- SERVER_INFO("(%d:%d) already inserted", device_id, consumer_id);\r
- continue;\r
- }\r
-\r
- reclaimed_consumers->insert(std::pair<int, int>(device_id, consumer_id));\r
-\r
- if (pRsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) {\r
- std::map<int, int> siblings;\r
- bandwidth->GetConsumersNDec(pRsc->GetCurCategory(), &siblings);\r
- if (siblings.size() > 0) {\r
- SERVER_INFO("insert n-dec siblings(%zu)", siblings.size());\r
- reclaimed_consumers->insert(siblings.begin(), siblings.end());\r
- }\r
- }\r
-\r
- reclaimed_bw += pRsc->GetBW();\r
-\r
- if (required_bw <= reclaimed_bw)\r
- break;\r
- SERVER_INFO("DevID[%d]/ need more BW! required:(%d)-resource(%d)-reclaimed(%d)", pRsc->GetDeviceID(), required_bw, pRsc->GetBW(), reclaimed_bw);\r
- }\r
-\r
- return reclaimed_bw;\r
-}\r
-\r
-bool CNDecodingVideoDecoderStrategy::canReclaimActiveVideoDecoders(CRequest *req)\r
-{\r
- CRequester *requester = req->getRequester();\r
- CResourceDB *resource_db = CResourceDB::getInstance();\r
- std::map<int, int> active_vdecs = resource_db->GetActiveVideoDecoders();\r
-\r
- for (auto const &it : active_vdecs) {\r
- int dev_id = it.first;\r
- int cid = it.second;\r
-\r
- CResource *rsc = resource_db->FindResource(dev_id);\r
-\r
- if (!rsc) {\r
- SERVER_ERR("can't find resource (%d)", dev_id);\r
- continue;\r
- }\r
-\r
- if (requester->getHandle() == cid) {\r
- SERVER_INFO("CID[%d] is using device (%d)", cid, dev_id);\r
- continue;\r
- }\r
-\r
- if (CPriority::compare(cid, requester->getHandle()) == HIGH_PRIORITY)\r
- return true;\r
- }\r
-\r
- return false;\r
-\r
-}\r
-\r
-int CNDecodingVideoDecoderStrategy::GetReclaimableVideoDecoderConsumers(int consumer_id, std::multimap<int, int>* reclaimables, CRequest *req, rms_error_type_e *err_type)\r
-{\r
- std::map<unsigned long, CResource*> rscs;\r
- CResource *rsc = NULL;\r
- CResourceDB *resource_db = CResourceDB::getInstance();\r
- std::map<int, int> active_vdecs = resource_db->GetActiveVideoDecoders();\r
- bool has_main_vdec = false;\r
- bool has_sub_vdec = false;\r
-\r
- for (auto const &it_vdec : active_vdecs) {\r
- rsc = resource_db->FindResource(it_vdec.first);\r
- rscs.insert(std::pair<unsigned long, CResource*>(rsc->GetAllocatedTime(), rsc));\r
-\r
- if (rsc->IsMainDevice())\r
- has_main_vdec = true;\r
- else\r
- has_sub_vdec = true;\r
- }\r
-\r
- for (auto const &it : rscs)\r
- {\r
- rsc = it.second;\r
-\r
- if (req->IsMainDeviceRequest() && has_main_vdec && !rsc->IsMainDevice())\r
- continue;\r
- if (req->IsSubDeviceRequest() && has_sub_vdec && rsc->IsMainDevice())\r
- continue;\r
-\r
- if (CPriority::getReclaimableConsumers(rsc->GetDeviceID(), consumer_id, reclaimables, err_type) == RMS_OK)\r
- return RMS_OK;\r
- }\r
-\r
- return RMS_ERROR;\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 <rms_debug.h>
+#include <CResourceDB.h>
+#include <CBandwidth.h>
+#include <CResource.h>
+#include <CVirtualResource.h>
+#include <CRequest.h>
+#include <CRequester.h>
+#include <CPriority.h>
+#include <CDependencyController.h>
+#include <CAllocateStrategy.h>
+#include <CNDecodingVideoDecoderStrategy.h>
+
+void CNDecodingVideoDecoderStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)
+{
+ CRequester *requester = req->getRequester();
+
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+ return;
+ }
+
+ if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle())) {
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);
+ return;
+ }
+
+ if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)
+ return;
+
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+}
+
+void CNDecodingVideoDecoderStrategy::updateReasonByBW(CVirtualResource *vresource, CRequest *req)
+{
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+ return;
+ }
+
+ rms_error_type_e reason = canReclaimRequiredBW(req, vresource->GetBW()) ?
+ RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER : RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;
+ req->SetReason(reason);
+}
+
+void CNDecodingVideoDecoderStrategy::updateReasonByTripleDecoding(CRequest *req)
+{
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+ return;
+ }
+
+ rms_error_type_e reason = canReclaimActiveVideoDecoders(req) ?
+ RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER : RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;
+ req->SetReason(reason);
+}
+
+bool CNDecodingVideoDecoderStrategy::isAllocatableResource(CVirtualResource *vresource, CRequest *req)
+{
+ int category_class = vresource->GetCategoryClass();
+ CResource *resource = vresource->GetResource();
+
+ if (resource->IsReserved()) {
+ SERVER_INFO("device id(%d) is reserved state", resource->GetDeviceID());
+ return false;
+ }
+
+ if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters(), category_class, vresource->GetCategoryType())) {
+ updateReasonByMemCluster(vresource, req);
+ return false;
+ }
+
+ CBandwidth *bandwidth = CBandwidth::GetInstance();
+ if ((bandwidth->GetNConsumersNDec(vresource->GetCategoryType()) == 0) && (vresource->GetBW() > bandwidth->GetAvail())) {
+ SERVER_INFO("insufficient BW required(%d)/avail(%d)", vresource->GetBW(), bandwidth->GetAvail());
+ updateReasonByBW(vresource, req);
+ return false;
+ }
+
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {
+ updateReasonByResourceState(resource->GetDeviceID(), req);
+ return false;
+ }
+
+ if (!CResourceDB::getInstance()->HasAvailableDecoderNDecoding()) {
+ updateReasonByTripleDecoding(req);
+ return false;
+ }
+
+ return true;
+}
+
+CVirtualResource *CNDecodingVideoDecoderStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)
+{
+ std::map<int, CVirtualResource *> filtered_vresources;
+ ExcludeResources(vresources, &filtered_vresources, req);
+
+ req->SetResult(RMS_ERROR);
+ req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);
+
+ for (auto const &it : filtered_vresources) {
+ CVirtualResource *vresource = it.second;
+ if (!isAllocatableResource(vresource, req))
+ continue;
+
+ return vresource;
+ }
+
+ return NULL;
+}
+
+int CNDecodingVideoDecoderStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)
+{
+ CResource *rsc = vrsc->GetResource();
+
+ if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)
+ return RMS_ERROR;
+
+ rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());
+
+ return RMS_OK;
+}
+
+bool CNDecodingVideoDecoderStrategy::ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources)
+{
+
+ CDependencyController *dc = CDependencyController::getInstance();
+ CBandwidth *bandwidth = CBandwidth::GetInstance();
+
+ for (auto const &it : vresources) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+ int category_class = vresource->GetCategoryClass();
+
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters(), category_class, vresource->GetCategoryType()))
+ continue;
+
+ if ((bandwidth->GetNConsumersNDec(vresource->GetCategoryType()) == 0) && (bandwidth->GetAvail() < vresource->GetBW()))
+ continue;
+
+ if (!resource->IsFreeState())
+ continue;
+
+ if (!CResourceDB::getInstance()->HasAvailableDecoderNDecoding())
+ continue;
+
+ return true;
+ }
+
+ return false;
+}
+
+int CNDecodingVideoDecoderStrategy::getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)
+{
+ CDependencyController *dc = CDependencyController::getInstance();
+ CResourceDB *resource_db = CResourceDB::getInstance();
+ CResource *resource = vresource->GetResource();
+ CBandwidth *bandwidth = CBandwidth::GetInstance();
+ int requester_id = req->getRequester()->getHandle();
+ int category_class = vresource->GetCategoryClass();
+
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters(), category_class, vresource->GetCategoryType())) {
+ if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), requester_id, retirables) != RMS_OK)
+ goto error;
+ }
+
+ if ((bandwidth->GetNConsumersNDec(vresource->GetCategoryType()) == 0) && ((bandwidth->GetAvail() + GetReclaimedBW(retirables)) < vresource->GetBW())) {
+ if (GetConsumerUsingBW(req, vresource->GetBW(), retirables) != RMS_OK)
+ goto error;
+ }
+
+ if (!resource->IsFreeState()) {
+ if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), requester_id, retirables, err_type) != RMS_OK)
+ goto error;
+ }
+
+ if (!resource_db->HasAvailableDecoderNDecoding(*retirables)) {
+ if (GetReclaimableVideoDecoderConsumers(requester_id, retirables, req, err_type) != RMS_OK)
+ goto error;
+ }
+
+ return RMS_OK;
+error:
+ if (!retirables->empty())
+ retirables->clear();
+
+ return RMS_ERROR;
+}
+
+void CNDecodingVideoDecoderStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)
+{
+ std::multimap<int, int> consumer_list;
+ std::multimap<unsigned long, CVirtualResource *> filtered_vresources;
+ bool included = false;
+
+ ExcludeResources(vresources, &filtered_vresources, req);
+
+ if (ContainAvailableResource(filtered_vresources))
+ return;
+
+ for (auto const &it : filtered_vresources) {
+ CVirtualResource *vresource = it.second;
+ included = false;
+ CResource *rsc = vresource->GetResource();
+ SERVER_INFO("vrsc(%d)/rsc(%d)", vresource->GetVResourceID(), rsc->GetDeviceID());
+ if (getRetirableConsumersExclusive(vresource, req, &consumer_list, err_type) == RMS_OK) {
+ for (auto const &it_c : consumer_list) {
+ auto it_r = retirables->find(it_c.first);
+ if (it_r != retirables->end()) {
+ included = true;
+ SERVER_INFO("(%d:%d) is already in the list", it_c.first, it_c.second);
+ break;
+ }
+ }
+ if (included)
+ continue;
+
+ break;
+ }
+ }
+
+ retirables->insert(consumer_list.begin(), consumer_list.end());
+}
+
+bool CNDecodingVideoDecoderStrategy::canReclaimRequiredBW(CRequest *req, unsigned int bw)
+{
+ CRequester *requester = req->getRequester();
+ CResourceDB *resource_db = CResourceDB::getInstance();
+ CBandwidth *bandwidth = CBandwidth::GetInstance();
+ unsigned int check_available = bandwidth->GetAvail();
+ std::map<int, int> bw_consumers = bandwidth->GetConsumers();
+
+ for (std::map<int, int>::iterator it = bw_consumers.begin(); it != bw_consumers.end(); it++) {
+ int device_id = (*it).first;
+ int consumer_id = (*it).second;
+
+ CResource *pRsc = resource_db->FindResource(device_id);
+
+ if (!pRsc) {
+ SERVER_ERR("cannot find resource using device id");
+ continue;
+ }
+
+ if (requester->getHandle() == consumer_id) {
+ SERVER_INFO("CID[%d] is using BW (%d)", requester->getHandle(), pRsc->GetBW());
+ continue;
+ }
+
+ if (CPriority::compare(consumer_id, requester->getHandle()) != HIGH_PRIORITY)
+ continue;
+
+ check_available += pRsc->GetBW();
+
+ if (bw <= check_available)
+ break;
+
+ SERVER_INFO("DevID[%d] / need more resource to be released!!! required BW(%d) - resource BW(%d) - check(%d)", pRsc->GetDeviceID(), bw, pRsc->GetBW(), check_available);
+
+ }
+
+ SERVER_INFO("required BW(%d) - available (%d)", bw, check_available);
+
+ return (bw <= check_available);
+}
+
+void CNDecodingVideoDecoderStrategy::SelectDevicesByMainSub(CRequest *req, std::map<int, int> *src, std::map<int, int> *result)
+{
+ CResourceDB *db = CResourceDB::getInstance();
+
+ for (auto const &it : *src) {
+ CResource *rsc = db->FindResource(it.first);
+ if (!rsc)
+ continue;
+ if (req->IsMainDeviceRequest() && !rsc->IsMainDevice())
+ continue;
+ if (req->IsSubDeviceRequest() && rsc->IsMainDevice())
+ continue;
+
+ result->insert(std::pair<int, int>(it.first, it.second));
+ }
+}
+
+int CNDecodingVideoDecoderStrategy::GetConsumerUsingBW(CRequest *req, unsigned int bw, std::multimap<int, int>* return_ids)
+{
+ std::map<int, int> candidates;
+ std::map<int, int> cur_consumers = CBandwidth::GetInstance()->GetConsumers(); //device id, consumer id
+
+ SelectDevicesByMainSub(req, &cur_consumers, &candidates);
+
+ std::multimap<int, int> reclaimed_by_ms;
+ unsigned int avail_bw = GetConsumerUsingBWByAllocationTime(req->getRequester()->getHandle(), bw, candidates, &reclaimed_by_ms);
+
+ if (avail_bw >= bw) {
+ return_ids->insert(reclaimed_by_ms.begin(), reclaimed_by_ms.end());
+ return RMS_OK;
+ }
+
+ std::multimap<int, int> reclaimed_by_t;
+ GetConsumerUsingBWByAllocationTime(req->getRequester()->getHandle(), bw, cur_consumers, &reclaimed_by_t);
+ return_ids->insert(reclaimed_by_t.begin(), reclaimed_by_t.end());
+
+ return RMS_OK;
+}
+
+int CNDecodingVideoDecoderStrategy::GetConsumerUsingBWByAllocationTime(int requester_id, unsigned int required_bw, std::map<int, int> bw_consumers, std::multimap<int, int>* reclaimed_consumers)
+{
+ assert(reclaimed_consumers);
+
+ CResourceDB *resource_db = CResourceDB::getInstance();
+ CBandwidth *bandwidth = CBandwidth::GetInstance();
+
+ SERVER_INFO("candidates using BW : %zu", bw_consumers.size());
+ unsigned int reclaimed_bw = bandwidth->GetAvail();
+
+ std::map<unsigned long, int> consumers_by_t;
+ for (auto const &itc : bw_consumers) {
+ CResource *rsc = resource_db->FindResource(itc.first);
+ if (!rsc)
+ continue;
+
+ consumers_by_t.insert(std::pair<unsigned long, int>(rsc->GetAllocatedTime(), itc.first));
+ }
+
+ for (auto const &it : consumers_by_t) {
+ int device_id = it.second;
+ CResource *pRsc = resource_db->FindResource(device_id);
+ if (!pRsc)
+ continue;
+
+ int consumer_id = pRsc->GetFirstConsumer();
+ SERVER_INFO("consumer (%d) is using bw for device (%d)", consumer_id, device_id);
+
+ if (requester_id == consumer_id) {
+ SERVER_INFO("CID[%d] is using BW (%d)", requester_id, pRsc->GetBW());
+ continue;
+ }
+
+ if (CPriority::compare(consumer_id, requester_id) != HIGH_PRIORITY)
+ continue;
+
+ auto ret = reclaimed_consumers->find(device_id);
+ if (ret != reclaimed_consumers->end()) {
+ SERVER_INFO("(%d:%d) already inserted", device_id, consumer_id);
+ continue;
+ }
+
+ reclaimed_consumers->insert(std::pair<int, int>(device_id, consumer_id));
+
+ if (pRsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) {
+ std::map<int, int> siblings;
+ bandwidth->GetConsumersNDec(pRsc->GetCurCategory(), &siblings);
+ if (siblings.size() > 0) {
+ SERVER_INFO("insert n-dec siblings(%zu)", siblings.size());
+ reclaimed_consumers->insert(siblings.begin(), siblings.end());
+ }
+ }
+
+ reclaimed_bw += pRsc->GetBW();
+
+ if (required_bw <= reclaimed_bw)
+ break;
+ SERVER_INFO("DevID[%d]/ need more BW! required:(%d)-resource(%d)-reclaimed(%d)", pRsc->GetDeviceID(), required_bw, pRsc->GetBW(), reclaimed_bw);
+ }
+
+ return reclaimed_bw;
+}
+
+bool CNDecodingVideoDecoderStrategy::canReclaimActiveVideoDecoders(CRequest *req)
+{
+ CRequester *requester = req->getRequester();
+ CResourceDB *resource_db = CResourceDB::getInstance();
+ std::map<int, int> active_vdecs = resource_db->GetActiveVideoDecoders();
+
+ for (auto const &it : active_vdecs) {
+ int dev_id = it.first;
+ int cid = it.second;
+
+ CResource *rsc = resource_db->FindResource(dev_id);
+
+ if (!rsc) {
+ SERVER_ERR("can't find resource (%d)", dev_id);
+ continue;
+ }
+
+ if (requester->getHandle() == cid) {
+ SERVER_INFO("CID[%d] is using device (%d)", cid, dev_id);
+ continue;
+ }
+
+ if (CPriority::compare(cid, requester->getHandle()) == HIGH_PRIORITY)
+ return true;
+ }
+
+ return false;
+
+}
+
+int CNDecodingVideoDecoderStrategy::GetReclaimableVideoDecoderConsumers(int consumer_id, std::multimap<int, int>* reclaimables, CRequest *req, rms_error_type_e *err_type)
+{
+ std::map<unsigned long, CResource*> rscs;
+ CResource *rsc = NULL;
+ CResourceDB *resource_db = CResourceDB::getInstance();
+ std::map<int, int> active_vdecs = resource_db->GetActiveVideoDecoders();
+ bool has_main_vdec = false;
+ bool has_sub_vdec = false;
+
+ for (auto const &it_vdec : active_vdecs) {
+ rsc = resource_db->FindResource(it_vdec.first);
+ rscs.insert(std::pair<unsigned long, CResource*>(rsc->GetAllocatedTime(), rsc));
+
+ if (rsc->IsMainDevice())
+ has_main_vdec = true;
+ else
+ has_sub_vdec = true;
+ }
+
+ for (auto const &it : rscs)
+ {
+ rsc = it.second;
+
+ if (req->IsMainDeviceRequest() && has_main_vdec && !rsc->IsMainDevice())
+ continue;
+ if (req->IsSubDeviceRequest() && has_sub_vdec && rsc->IsMainDevice())
+ continue;
+
+ if (CPriority::getReclaimableConsumers(rsc->GetDeviceID(), consumer_id, reclaimables, err_type) == RMS_OK)
+ return RMS_OK;
+ }
+
+ return RMS_ERROR;
+}
-/*\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 <algorithm>\r
-\r
-#include <rms_debug.h>\r
-#include <CRequest.h>\r
-#include <CResource.h>\r
-#include <CResourceDB.h>\r
-#include <CResourceCategory.h>\r
-#include <CAllocateModeStrategy.h>\r
-#include <CNormalModeStrategy.h>\r
-\r
-void ReserveCandidate(CRequest *req)\r
-{\r
- CResourceCategory *resource_category = CResourceDB::getInstance()->FindResourceCategory(req->GetCategory());\r
-\r
- req->SetResult(RMS_ERROR);\r
-\r
- if (!resource_category) {\r
- if (req->GetCategory() == RMS_CATEGORY_NOT_PERMITTED)\r
- req->SetReason(RMS_ERR_TYPE_NOT_PERMITTED);\r
- else\r
- req->SetReason(RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST);\r
-\r
- SERVER_ERR("not existing category(%d)! can't allocate a candidate", req->GetCategory());\r
- return;\r
- }\r
-\r
- CResource *resource = resource_category->ReserveCandidate(req, true);\r
-\r
- if (!resource)\r
- return;\r
-\r
- req->SetResult(RMS_OK);\r
- req->SetCandidateDevice(resource->GetDeviceID());\r
-}\r
-\r
-void ReleaseReservedResources(CRequest *req)\r
-{\r
- if (req->GetResult() != RMS_OK)\r
- return;\r
-\r
- CResource *resource = CResourceDB::getInstance()->FindResource(req->GetCandidateDevice());\r
-\r
- resource->CancelReservation((rms_requests_resource_state_e) req->GetState());\r
-}\r
-\r
-rms_return_code_e ToAllocReturnCode(rms_error_type_e error_type)\r
-{\r
- rms_return_code_e result = RMS_OK;\r
-\r
- switch (error_type) {\r
- case RMS_ERR_TYPE_NONE:\r
- result = RMS_OK;\r
- break;\r
- case RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER:\r
- result = RMS_ERROR_TAKE_RESOURCE_FROM_OTHER_CONSUMER;\r
- break;\r
- default:\r
- result = RMS_ERROR;\r
- break;\r
- }\r
-\r
- return result;\r
-}\r
-\r
-\r
-CNormalModeStrategy::CNormalModeStrategy()\r
-{\r
-}\r
-\r
-CNormalModeStrategy::~CNormalModeStrategy()\r
-{\r
-}\r
-\r
-rms_error_type_e CNormalModeStrategy::GetCandidateFindResult(std::vector<CRequest *> requests)\r
-{\r
- rms_error_type_e result = RMS_ERR_TYPE_NONE;\r
-\r
- for (auto& it : requests) {\r
- CRequest *request = it;\r
-\r
- if (request->GetResult() == RMS_OK)\r
- continue;\r
-\r
- if (request->GetReason() != RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)\r
- return request->GetReason();\r
-\r
- result = RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER;\r
- }\r
-\r
- return result;\r
-}\r
-\r
-bool CNormalModeStrategy::CanAllocateResources(std::vector<CRequest*> requests, rms_allocate_result_s *result)\r
-{\r
- std::for_each(requests.begin(), requests.end(), ReserveCandidate);\r
-\r
- result->reason = GetCandidateFindResult(requests);\r
- result->result = ToAllocReturnCode(result->reason);\r
-\r
- std::for_each(requests.begin(), requests.end(), ReleaseReservedResources);\r
-\r
- return (result->result == RMS_OK);\r
-}\r
-\r
-void CNormalModeStrategy::WriteAllocResult(rms_allocate_result_s *alloc_result, std::vector<CRequest *> requests, rms_return_device_s *allocated_devices)\r
-{\r
- assert(allocated_devices);\r
-\r
- allocated_devices->result = alloc_result->result;\r
- allocated_devices->error_type = alloc_result->reason;\r
-\r
- if (alloc_result->result != RMS_OK) {\r
- allocated_devices->resources_num = 0;\r
- return;\r
- }\r
-\r
- allocated_devices->resources_num = requests.size();\r
- allocated_devices->device_ids = (int*) calloc(requests.size(), sizeof(int));\r
- assert(allocated_devices->device_ids);\r
- allocated_devices->devices = (rms_return_device_info_s*) calloc(requests.size(), sizeof(rms_return_device_info_s));\r
- assert(allocated_devices->devices);\r
-\r
- int i = 0;\r
-\r
- for (auto const &it : requests) {\r
- allocated_devices->device_ids[i] = it->GetAllocatedVirtualDevice();\r
- allocated_devices->devices[i].device_id = it->GetAllocatedVirtualDevice();\r
- CResource *resource = CResourceDB::getInstance()->FindResource(it->GetAllocatedDevice());\r
- assert(resource);\r
-\r
- const char *path = resource->GetDevicePath();\r
- allocated_devices->devices[i].device_path = strndup(path, strlen(path));\r
- resource->SetAllocatedTime();\r
- i++;\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 <assert.h>
+#include <algorithm>
+
+#include <rms_debug.h>
+#include <CRequest.h>
+#include <CResource.h>
+#include <CResourceDB.h>
+#include <CResourceCategory.h>
+#include <CAllocateModeStrategy.h>
+#include <CNormalModeStrategy.h>
+
+void ReserveCandidate(CRequest *req)
+{
+ CResourceCategory *resource_category = CResourceDB::getInstance()->FindResourceCategory(req->GetCategory());
+
+ req->SetResult(RMS_ERROR);
+
+ if (!resource_category) {
+ if (req->GetCategory() == RMS_CATEGORY_NOT_PERMITTED)
+ req->SetReason(RMS_ERR_TYPE_NOT_PERMITTED);
+ else
+ req->SetReason(RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST);
+
+ SERVER_ERR("not existing category(%d)! can't allocate a candidate", req->GetCategory());
+ return;
+ }
+
+ CResource *resource = resource_category->ReserveCandidate(req, true);
+
+ if (!resource)
+ return;
+
+ req->SetResult(RMS_OK);
+ req->SetCandidateDevice(resource->GetDeviceID());
+}
+
+void ReleaseReservedResources(CRequest *req)
+{
+ if (req->GetResult() != RMS_OK)
+ return;
+
+ CResource *resource = CResourceDB::getInstance()->FindResource(req->GetCandidateDevice());
+
+ resource->CancelReservation((rms_requests_resource_state_e) req->GetState());
+}
+
+rms_return_code_e ToAllocReturnCode(rms_error_type_e error_type)
+{
+ rms_return_code_e result = RMS_OK;
+
+ switch (error_type) {
+ case RMS_ERR_TYPE_NONE:
+ result = RMS_OK;
+ break;
+ case RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER:
+ result = RMS_ERROR_TAKE_RESOURCE_FROM_OTHER_CONSUMER;
+ break;
+ default:
+ result = RMS_ERROR;
+ break;
+ }
+
+ return result;
+}
+
+
+CNormalModeStrategy::CNormalModeStrategy()
+{
+}
+
+CNormalModeStrategy::~CNormalModeStrategy()
+{
+}
+
+rms_error_type_e CNormalModeStrategy::GetCandidateFindResult(std::vector<CRequest *> requests)
+{
+ rms_error_type_e result = RMS_ERR_TYPE_NONE;
+
+ for (auto& it : requests) {
+ CRequest *request = it;
+
+ if (request->GetResult() == RMS_OK)
+ continue;
+
+ if (request->GetReason() != RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)
+ return request->GetReason();
+
+ result = RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER;
+ }
+
+ return result;
+}
+
+bool CNormalModeStrategy::CanAllocateResources(std::vector<CRequest*> requests, rms_allocate_result_s *result)
+{
+ std::for_each(requests.begin(), requests.end(), ReserveCandidate);
+
+ result->reason = GetCandidateFindResult(requests);
+ result->result = ToAllocReturnCode(result->reason);
+
+ std::for_each(requests.begin(), requests.end(), ReleaseReservedResources);
+
+ return (result->result == RMS_OK);
+}
+
+void CNormalModeStrategy::WriteAllocResult(rms_allocate_result_s *alloc_result, std::vector<CRequest *> requests, rms_return_device_s *allocated_devices)
+{
+ assert(allocated_devices);
+
+ allocated_devices->result = alloc_result->result;
+ allocated_devices->error_type = alloc_result->reason;
+
+ if (alloc_result->result != RMS_OK) {
+ allocated_devices->resources_num = 0;
+ return;
+ }
+
+ allocated_devices->resources_num = requests.size();
+ allocated_devices->device_ids = (int*) calloc(requests.size(), sizeof(int));
+ assert(allocated_devices->device_ids);
+ allocated_devices->devices = (rms_return_device_info_s*) calloc(requests.size(), sizeof(rms_return_device_info_s));
+ assert(allocated_devices->devices);
+
+ int i = 0;
+
+ for (auto const &it : requests) {
+ allocated_devices->device_ids[i] = it->GetAllocatedVirtualDevice();
+ allocated_devices->devices[i].device_id = it->GetAllocatedVirtualDevice();
+ CResource *resource = CResourceDB::getInstance()->FindResource(it->GetAllocatedDevice());
+ assert(resource);
+
+ const char *path = resource->GetDevicePath();
+ allocated_devices->devices[i].device_path = strndup(path, strlen(path));
+ resource->SetAllocatedTime();
+ i++;
+ }
+}
-/*\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
-\r
-#include <rms_debug.h>\r
-#include <CResource.h>\r
-#include <CVirtualResource.h>\r
-#include <CResourceDB.h>\r
-#include <CRequest.h>\r
-#include <CPriority.h>\r
-#include <CRequester.h>\r
-#include <CNormalStrategy.h>\r
-\r
-CNormalStrategy::CNormalStrategy()\r
-{\r
-}\r
-\r
-CNormalStrategy::~CNormalStrategy()\r
-{\r
-}\r
-\r
-CVirtualResource *CNormalStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)\r
-{\r
- std::map<int, CVirtualResource *> filtered_vresources;\r
- ExcludeResources(vresources, &filtered_vresources, req);\r
-\r
- req->SetResult(RMS_ERROR);\r
- req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);\r
-\r
- for (auto const &it : filtered_vresources) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *resource = vresource->GetResource();\r
- int device_id = resource->GetDeviceID();\r
-\r
- if (resource->IsReserved())\r
- continue;\r
-\r
- if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
- updateReasonByResourceState(device_id, req);\r
- continue;\r
- }\r
-\r
- return vresource;\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-int CNormalStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)\r
-{\r
- CResource *rsc = vrsc->GetResource();\r
-\r
- if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)\r
- return RMS_ERROR;\r
-\r
- return RMS_OK;\r
-}\r
-\r
-bool CNormalStrategy::ContainFreeResource(std::multimap<unsigned long, CVirtualResource *> vresources)\r
-{\r
- for (auto const &it : vresources) {\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 CNormalStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)\r
-{\r
- std::multimap<int, int> consumer_list;\r
- std::multimap<unsigned long, CVirtualResource *> filtered_vresources;\r
-\r
- ExcludeResources(vresources, &filtered_vresources, req);\r
-\r
- if (ContainFreeResource(filtered_vresources))\r
- return;\r
-\r
- for (auto const &it : filtered_vresources) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *resource = vresource->GetResource();\r
-\r
- if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), req->getRequester()->getHandle(), &consumer_list, err_type) == RMS_OK)\r
- break;\r
- }\r
-\r
- for (auto const &it : consumer_list) {\r
- retirables->insert(std::pair<int, int>(it.first, it.second));\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 <assert.h>
+
+#include <rms_debug.h>
+#include <CResource.h>
+#include <CVirtualResource.h>
+#include <CResourceDB.h>
+#include <CRequest.h>
+#include <CPriority.h>
+#include <CRequester.h>
+#include <CNormalStrategy.h>
+
+CNormalStrategy::CNormalStrategy()
+{
+}
+
+CNormalStrategy::~CNormalStrategy()
+{
+}
+
+CVirtualResource *CNormalStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)
+{
+ std::map<int, CVirtualResource *> filtered_vresources;
+ ExcludeResources(vresources, &filtered_vresources, req);
+
+ req->SetResult(RMS_ERROR);
+ req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);
+
+ for (auto const &it : filtered_vresources) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+ int device_id = resource->GetDeviceID();
+
+ if (resource->IsReserved())
+ continue;
+
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {
+ updateReasonByResourceState(device_id, req);
+ continue;
+ }
+
+ return vresource;
+ }
+
+ return NULL;
+}
+
+int CNormalStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)
+{
+ CResource *rsc = vrsc->GetResource();
+
+ if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)
+ return RMS_ERROR;
+
+ return RMS_OK;
+}
+
+bool CNormalStrategy::ContainFreeResource(std::multimap<unsigned long, CVirtualResource *> vresources)
+{
+ for (auto const &it : vresources) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+
+ if (resource->IsFreeState())
+ return true;
+ }
+
+ return false;
+}
+
+void CNormalStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)
+{
+ std::multimap<int, int> consumer_list;
+ std::multimap<unsigned long, CVirtualResource *> filtered_vresources;
+
+ ExcludeResources(vresources, &filtered_vresources, req);
+
+ if (ContainFreeResource(filtered_vresources))
+ return;
+
+ for (auto const &it : filtered_vresources) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+
+ if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), req->getRequester()->getHandle(), &consumer_list, err_type) == RMS_OK)
+ break;
+ }
+
+ for (auto const &it : consumer_list) {
+ retirables->insert(std::pair<int, int>(it.first, it.second));
+ }
+}
-/*\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 <algorithm>\r
-\r
-#include <rms_type.h>\r
-#include <rms_debug.h>\r
-\r
-#include <CRequest.h>\r
-#include <CResource.h>\r
-#include <CResourceDB.h>\r
-#include <CResourceCategory.h>\r
-#include <CAllocateModeStrategy.h>\r
-#include <CPreferenceModeStrategy.h>\r
-\r
-CPreferenceModeStrategy::CPreferenceModeStrategy()\r
-{\r
-}\r
-\r
-CPreferenceModeStrategy::~CPreferenceModeStrategy()\r
-{\r
-}\r
-\r
-bool CPreferenceModeStrategy::CanAllocateResources(std::vector<CRequest*> requests, rms_allocate_result_s *result)\r
-{\r
- result->result = RMS_ERROR;\r
- result->reason = RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE;\r
-\r
- for (auto const &it : requests) {\r
- CRequest *req = it;\r
- CResourceCategory *resource_category = CResourceDB::getInstance()->FindResourceCategory(req->GetCategory());\r
-\r
- if (!resource_category) {\r
- SERVER_ERR("not existing category(%d)! can't allocate a candidate", req->GetCategory());\r
- continue;\r
- }\r
-\r
- CResource *resource = resource_category->ReserveCandidate(req, false);\r
-\r
- if (!resource)\r
- continue;\r
-\r
- req->SetResult(RMS_OK);\r
- req->SetCandidateDevice(resource->GetDeviceID());\r
- result->result = RMS_OK;\r
- break;\r
- }\r
-\r
- std::for_each(requests.begin(), requests.end(), [](CRequest *req) { if (req->GetResult()!= RMS_OK) return;\r
- CResource *resource = CResourceDB::getInstance()->FindResource(req->GetCandidateDevice());\r
- resource->CancelReservation((rms_requests_resource_state_e) req->GetState()); });\r
-\r
- return (result->result == RMS_OK);\r
-}\r
-\r
-void CPreferenceModeStrategy::WriteAllocResult(rms_allocate_result_s *alloc_result, std::vector<CRequest *> requests, rms_return_device_s *allocated_devices)\r
-{\r
- assert(allocated_devices);\r
-\r
- allocated_devices->result = alloc_result->result;\r
- allocated_devices->error_type = alloc_result->reason;\r
-\r
- if (alloc_result->result != RMS_OK) {\r
- allocated_devices->resources_num = 0;\r
- return;\r
- }\r
-\r
- allocated_devices->resources_num = requests.size();\r
- allocated_devices->device_ids = (int*) calloc(requests.size(), sizeof(int));\r
- assert(allocated_devices->device_ids);\r
- allocated_devices->devices = (rms_return_device_info_s*) calloc(requests.size(), sizeof(rms_return_device_info_s));\r
- assert(allocated_devices->devices);\r
-\r
- int i = 0;\r
-\r
- for (auto const &it : requests) {\r
- bool is_allocated = (it->GetResult() == RMS_OK);\r
- int allocated_device_id = (is_allocated) ? it->GetAllocatedVirtualDevice() : RMS_DEVICE_NONE;\r
-\r
- allocated_devices->device_ids[i] = allocated_device_id;\r
- allocated_devices->devices[i].device_id = allocated_device_id;\r
-\r
- if (!is_allocated) {\r
- i++;\r
- continue;\r
- }\r
-\r
- CResource *resource = CResourceDB::getInstance()->FindResource(it->GetAllocatedDevice());\r
- assert(resource);\r
-\r
- const char *path = resource->GetDevicePath();\r
- allocated_devices->devices[i].device_path = strndup(path, strlen(path));\r
- resource->SetAllocatedTime();\r
- i++;\r
- }\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 <assert.h>
+#include <algorithm>
+
+#include <rms_type.h>
+#include <rms_debug.h>
+
+#include <CRequest.h>
+#include <CResource.h>
+#include <CResourceDB.h>
+#include <CResourceCategory.h>
+#include <CAllocateModeStrategy.h>
+#include <CPreferenceModeStrategy.h>
+
+CPreferenceModeStrategy::CPreferenceModeStrategy()
+{
+}
+
+CPreferenceModeStrategy::~CPreferenceModeStrategy()
+{
+}
+
+bool CPreferenceModeStrategy::CanAllocateResources(std::vector<CRequest*> requests, rms_allocate_result_s *result)
+{
+ result->result = RMS_ERROR;
+ result->reason = RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE;
+
+ for (auto const &it : requests) {
+ CRequest *req = it;
+ CResourceCategory *resource_category = CResourceDB::getInstance()->FindResourceCategory(req->GetCategory());
+
+ if (!resource_category) {
+ SERVER_ERR("not existing category(%d)! can't allocate a candidate", req->GetCategory());
+ continue;
+ }
+
+ CResource *resource = resource_category->ReserveCandidate(req, false);
+
+ if (!resource)
+ continue;
+
+ req->SetResult(RMS_OK);
+ req->SetCandidateDevice(resource->GetDeviceID());
+ result->result = RMS_OK;
+ break;
+ }
+
+ std::for_each(requests.begin(), requests.end(), [](CRequest *req) { if (req->GetResult()!= RMS_OK) return;
+ CResource *resource = CResourceDB::getInstance()->FindResource(req->GetCandidateDevice());
+ resource->CancelReservation((rms_requests_resource_state_e) req->GetState()); });
+
+ return (result->result == RMS_OK);
+}
+
+void CPreferenceModeStrategy::WriteAllocResult(rms_allocate_result_s *alloc_result, std::vector<CRequest *> requests, rms_return_device_s *allocated_devices)
+{
+ assert(allocated_devices);
+
+ allocated_devices->result = alloc_result->result;
+ allocated_devices->error_type = alloc_result->reason;
+
+ if (alloc_result->result != RMS_OK) {
+ allocated_devices->resources_num = 0;
+ return;
+ }
+
+ allocated_devices->resources_num = requests.size();
+ allocated_devices->device_ids = (int*) calloc(requests.size(), sizeof(int));
+ assert(allocated_devices->device_ids);
+ allocated_devices->devices = (rms_return_device_info_s*) calloc(requests.size(), sizeof(rms_return_device_info_s));
+ assert(allocated_devices->devices);
+
+ int i = 0;
+
+ for (auto const &it : requests) {
+ bool is_allocated = (it->GetResult() == RMS_OK);
+ int allocated_device_id = (is_allocated) ? it->GetAllocatedVirtualDevice() : RMS_DEVICE_NONE;
+
+ allocated_devices->device_ids[i] = allocated_device_id;
+ allocated_devices->devices[i].device_id = allocated_device_id;
+
+ if (!is_allocated) {
+ i++;
+ continue;
+ }
+
+ CResource *resource = CResourceDB::getInstance()->FindResource(it->GetAllocatedDevice());
+ assert(resource);
+
+ const char *path = resource->GetDevicePath();
+ allocated_devices->devices[i].device_path = strndup(path, strlen(path));
+ resource->SetAllocatedTime();
+ i++;
+ }
+}
+
-/*\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
-\r
-#include <rms_debug.h>\r
-#include <CResource.h>\r
-#include <CVirtualResource.h>\r
-#include <CResourceDB.h>\r
-#include <CRequest.h>\r
-#include <CPriority.h>\r
-#include <CRequester.h>\r
-#include <CDependencyController.h>\r
-#include <CScalerStrategy.h>\r
-\r
-CScalerStrategy::CScalerStrategy()\r
-{\r
-}\r
-\r
-CScalerStrategy::~CScalerStrategy()\r
-{\r
-}\r
-\r
-void CScalerStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)\r
-{\r
- CRequester *requester = req->getRequester();\r
-\r
- if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle())) {\r
- req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
- return;\r
- }\r
-\r
- if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)\r
- return;\r
-\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
-}\r
-\r
-CVirtualResource *CScalerStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)\r
-{\r
- std::map<int, CVirtualResource *> filtered_vresources;\r
- ExcludeResources(vresources, &filtered_vresources, req);\r
-\r
- req->SetResult(RMS_ERROR);\r
- req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);\r
-\r
- for (auto const &it : filtered_vresources) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *resource = vresource->GetResource();\r
- int device_id = resource->GetDeviceID();\r
-\r
- if (resource->IsReserved())\r
- continue;\r
-\r
- if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters())) {\r
- updateReasonByMemCluster(vresource, req);\r
- continue;\r
- }\r
-\r
- if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
- updateReasonByResourceState(device_id, req);\r
- continue;\r
- }\r
-\r
- return vresource;\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-int CScalerStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)\r
-{\r
- CResource *rsc = vrsc->GetResource();\r
-\r
- if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)\r
- return RMS_ERROR;\r
-\r
- rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());\r
- return RMS_OK;\r
-}\r
-\r
-bool CScalerStrategy::ContainFreeResource(std::multimap<unsigned long, CVirtualResource *> vresources)\r
-{\r
- for (auto const &it : vresources)\r
- {\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 CScalerStrategy::SelectConsumersByAllocationTime(std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)\r
-{\r
- CResourceDB *db = CResourceDB::getInstance();\r
- std::map<unsigned long, int> candidates_by_alloc_t; // allocation time, virtual resource id\r
-\r
- for (auto const &it : *candidates) {\r
- std::multimap<int, int> candidate = it.second;\r
- for (auto const &itc : candidate) {\r
- CResource *rsc = db->FindResource(itc.first);\r
- candidates_by_alloc_t.insert(std::pair<unsigned long, int>(rsc->GetAllocatedTime(), it.first));\r
- SERVER_INFO("vrsc(%d)/dev(%d:%ld)/cid(%d)", it.first, itc.first, rsc->GetAllocatedTime(), itc.second);\r
- }\r
- }\r
-\r
- auto itf = candidates_by_alloc_t.begin();\r
- if (itf == candidates_by_alloc_t.end()) {\r
- SERVER_ERR("no candidate");\r
- return;\r
- }\r
-\r
- auto const &ite = candidates->find(itf->second);\r
- std::multimap<int, int> *elected = &ite->second;\r
-\r
- result->insert(elected->begin(), elected->end());\r
-}\r
-\r
-void CScalerStrategy::SelectConsumersByZoneId(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)\r
-{\r
- if (zone_id <= 0) {\r
- SERVER_ERR("invalid zone id(%d)", zone_id);\r
- return;\r
- }\r
-\r
- CResourceDB *db = CResourceDB::getInstance();\r
-\r
- for (auto const &it : *candidates) {\r
- std::multimap<int, int> candidate = it.second;\r
- for (auto const &itc : candidate) {\r
- CResource *rsc = db->FindResource(itc.first);\r
- if (rsc->GetZoneId() == zone_id) {\r
- SERVER_INFO("[%d] select (%d) > (%d:%d)", it.first, zone_id, itc.first, itc.second);\r
- result->insert(candidate.begin(), candidate.end());\r
- break;\r
- }\r
- }\r
- }\r
-}\r
-\r
-bool CScalerStrategy::ContainInterlacedNotSupportedApp(std::map<int, std::multimap<int, int>> *candidates)\r
-{\r
- CResourceDB *db = CResourceDB::getInstance();\r
-\r
- for (auto const &it : *candidates) {\r
- std::multimap<int, int> candidate = it.second;\r
- for (auto const &itc : candidate) {\r
- CResource *rsc = db->FindResource(itc.first);\r
- if (rsc->GetCurCategory() != RMS_CATEGORY_SCALER_INTERLACED)\r
- return true;\r
- }\r
- }\r
- return false;\r
-}\r
-\r
-int CScalerStrategy::FindScalerInSameZone(int zone_id)\r
-{\r
- std::map<int, CResource*> scalers;\r
- CResourceDB::getInstance()->GetScalerList(&scalers);\r
-\r
- for (auto const &it : scalers) {\r
- CResource *rsc = it.second;\r
- if (rsc->GetZoneId() == zone_id) {\r
- SERVER_INFO("scaler in same zone(%d:%d:%d) found", zone_id, rsc->GetDeviceID(), rsc->GetVirtualDeviceId());\r
- return rsc->GetDeviceID();\r
- }\r
- }\r
- SERVER_INFO("scaler in same zone not found");\r
- return -1;\r
-}\r
-\r
-int CScalerStrategy::FindScalerUsedByAppInterlacedNotSupported(std::map<int, std::multimap<int, int>> *candidates)\r
-{\r
- CResourceDB *db = CResourceDB::getInstance();\r
- for (auto const &it : *candidates) {\r
- std::multimap<int, int> candidate = it.second;\r
- for (auto const &itc : candidate) {\r
- CResource *rsc = db->FindResource(itc.first);\r
- if (rsc->GetCurCategory() == RMS_CATEGORY_SCALER_INTERLACED)\r
- continue;\r
- SERVER_INFO("scaler(%d:%d:%d) used by the app interlaced not supported found", rsc->GetCurCategory(), rsc->GetDeviceID(), rsc->GetVirtualDeviceId());\r
- return rsc->GetDeviceID();\r
- }\r
- }\r
- SERVER_INFO("scaler used by the app interlaced not supported not found");\r
- return -1;\r
-}\r
-\r
-void CScalerStrategy::SelectConsumersBySwap(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)\r
-{\r
- if (!ContainInterlacedNotSupportedApp(candidates)) {\r
- SERVER_INFO("all scalers are being used by apps supporting interlaced");\r
- return;\r
- }\r
-\r
- int scaler_id_sz = FindScalerInSameZone(zone_id);\r
- if (scaler_id_sz < 0)\r
- return;\r
-\r
- int scaler_id_ins = FindScalerUsedByAppInterlacedNotSupported(candidates);\r
- if (scaler_id_ins < 0)\r
- return;\r
-\r
- CResourceDB *db = CResourceDB::getInstance();\r
- CResource *rsc_sz = db->FindResource(scaler_id_sz);\r
- CResource *rsc_ins = db->FindResource(scaler_id_ins);\r
-\r
- if (db->SwapScaler(rsc_sz->GetVirtualDeviceId(), rsc_ins->GetVirtualDeviceId()) < 0)\r
- return;\r
-\r
- db->UpdateVirtualScalerIds();\r
-\r
- std::set<int> consumers = rsc_ins->GetConsumers();\r
- for (auto const &it : consumers) {\r
- SERVER_INFO("insert (%d:%d)", scaler_id_ins, it);\r
- result->insert(std::pair<int, int>(scaler_id_ins, it));\r
- }\r
-}\r
-\r
-void CScalerStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource*> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)\r
-{\r
- std::multimap<int, int> consumer_list;\r
- std::multimap<unsigned long, CVirtualResource *> filtered_vresources;\r
- std::map<int, std::multimap<int, int>> candidates; // <vrsc id, <device id, consumer id>>\r
-\r
- ExcludeResources(vresources, &filtered_vresources, req);\r
-\r
- CDependencyController *dc = CDependencyController::getInstance();\r
-\r
- for (auto const &it : filtered_vresources) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *resource = vresource->GetResource();\r
- SERVER_INFO("vrsc(%d)/rsc(%d)", vresource->GetVResourceID(), resource->GetDeviceID());\r
-\r
- if (!dc->isAvailableMemClusters(vresource->GetMemClusters())) {\r
- if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), req->getRequester()->getHandle(), &consumer_list) != RMS_OK) {\r
- SERVER_ERR("failed to find reclaimable consumer vrsc(%d)/rsc(%d)", vresource->GetVResourceID(), resource->GetDeviceID());\r
- };\r
- }\r
- if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), req->getRequester()->getHandle(), &consumer_list, err_type) == RMS_OK) {\r
- candidates.insert(std::pair<int, std::multimap<int, int>>(vresource->GetVResourceID(), consumer_list));\r
- consumer_list.clear();\r
- }\r
- }\r
- SERVER_INFO("zone id : %d, candidates(%zu)", req->GetMultiviewZoneId(), candidates.size());\r
- if (req->GetMultiviewZoneId() > 0)\r
- SelectConsumersByZoneId(req->GetMultiviewZoneId(), &candidates, &consumer_list);\r
-\r
- if (consumer_list.empty() && (req->GetCategory() == RMS_CATEGORY_SCALER_INTERLACED))\r
- SelectConsumersBySwap(req->GetMultiviewZoneId(), &candidates, &consumer_list);\r
-\r
- if (consumer_list.empty())\r
- SelectConsumersByAllocationTime(&candidates, &consumer_list);\r
-\r
- for (auto const &it : consumer_list)\r
- retirables->insert(std::pair<int, int>(it.first, it.second));\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 <rms_debug.h>
+#include <CResource.h>
+#include <CVirtualResource.h>
+#include <CResourceDB.h>
+#include <CRequest.h>
+#include <CPriority.h>
+#include <CRequester.h>
+#include <CDependencyController.h>
+#include <CScalerStrategy.h>
+
+CScalerStrategy::CScalerStrategy()
+{
+}
+
+CScalerStrategy::~CScalerStrategy()
+{
+}
+
+void CScalerStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)
+{
+ CRequester *requester = req->getRequester();
+
+ if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle())) {
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);
+ return;
+ }
+
+ if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)
+ return;
+
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+}
+
+CVirtualResource *CScalerStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)
+{
+ std::map<int, CVirtualResource *> filtered_vresources;
+ ExcludeResources(vresources, &filtered_vresources, req);
+
+ req->SetResult(RMS_ERROR);
+ req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);
+
+ for (auto const &it : filtered_vresources) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+ int device_id = resource->GetDeviceID();
+
+ if (resource->IsReserved())
+ continue;
+
+ if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters())) {
+ updateReasonByMemCluster(vresource, req);
+ continue;
+ }
+
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {
+ updateReasonByResourceState(device_id, req);
+ continue;
+ }
+
+ return vresource;
+ }
+
+ return NULL;
+}
+
+int CScalerStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)
+{
+ CResource *rsc = vrsc->GetResource();
+
+ if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)
+ return RMS_ERROR;
+
+ rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());
+ return RMS_OK;
+}
+
+bool CScalerStrategy::ContainFreeResource(std::multimap<unsigned long, CVirtualResource *> vresources)
+{
+ for (auto const &it : vresources)
+ {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+
+ if (resource->IsFreeState())
+ return true;
+ }
+
+ return false;
+}
+
+void CScalerStrategy::SelectConsumersByAllocationTime(std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)
+{
+ CResourceDB *db = CResourceDB::getInstance();
+ std::map<unsigned long, int> candidates_by_alloc_t; // allocation time, virtual resource id
+
+ for (auto const &it : *candidates) {
+ std::multimap<int, int> candidate = it.second;
+ for (auto const &itc : candidate) {
+ CResource *rsc = db->FindResource(itc.first);
+ candidates_by_alloc_t.insert(std::pair<unsigned long, int>(rsc->GetAllocatedTime(), it.first));
+ SERVER_INFO("vrsc(%d)/dev(%d:%ld)/cid(%d)", it.first, itc.first, rsc->GetAllocatedTime(), itc.second);
+ }
+ }
+
+ auto itf = candidates_by_alloc_t.begin();
+ if (itf == candidates_by_alloc_t.end()) {
+ SERVER_ERR("no candidate");
+ return;
+ }
+
+ auto const &ite = candidates->find(itf->second);
+ std::multimap<int, int> *elected = &ite->second;
+
+ result->insert(elected->begin(), elected->end());
+}
+
+void CScalerStrategy::SelectConsumersByZoneId(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)
+{
+ if (zone_id <= 0) {
+ SERVER_ERR("invalid zone id(%d)", zone_id);
+ return;
+ }
+
+ CResourceDB *db = CResourceDB::getInstance();
+
+ for (auto const &it : *candidates) {
+ std::multimap<int, int> candidate = it.second;
+ for (auto const &itc : candidate) {
+ CResource *rsc = db->FindResource(itc.first);
+ if (rsc->GetZoneId() == zone_id) {
+ SERVER_INFO("[%d] select (%d) > (%d:%d)", it.first, zone_id, itc.first, itc.second);
+ result->insert(candidate.begin(), candidate.end());
+ break;
+ }
+ }
+ }
+}
+
+bool CScalerStrategy::ContainInterlacedNotSupportedApp(std::map<int, std::multimap<int, int>> *candidates)
+{
+ CResourceDB *db = CResourceDB::getInstance();
+
+ for (auto const &it : *candidates) {
+ std::multimap<int, int> candidate = it.second;
+ for (auto const &itc : candidate) {
+ CResource *rsc = db->FindResource(itc.first);
+ if (rsc->GetCurCategory() != RMS_CATEGORY_SCALER_INTERLACED)
+ return true;
+ }
+ }
+ return false;
+}
+
+int CScalerStrategy::FindScalerInSameZone(int zone_id)
+{
+ std::map<int, CResource*> scalers;
+ CResourceDB::getInstance()->GetScalerList(&scalers);
+
+ for (auto const &it : scalers) {
+ CResource *rsc = it.second;
+ if (rsc->GetZoneId() == zone_id) {
+ SERVER_INFO("scaler in same zone(%d:%d:%d) found", zone_id, rsc->GetDeviceID(), rsc->GetVirtualDeviceId());
+ return rsc->GetDeviceID();
+ }
+ }
+ SERVER_INFO("scaler in same zone not found");
+ return -1;
+}
+
+int CScalerStrategy::FindScalerUsedByAppInterlacedNotSupported(std::map<int, std::multimap<int, int>> *candidates)
+{
+ CResourceDB *db = CResourceDB::getInstance();
+ for (auto const &it : *candidates) {
+ std::multimap<int, int> candidate = it.second;
+ for (auto const &itc : candidate) {
+ CResource *rsc = db->FindResource(itc.first);
+ if (rsc->GetCurCategory() == RMS_CATEGORY_SCALER_INTERLACED)
+ continue;
+ SERVER_INFO("scaler(%d:%d:%d) used by the app interlaced not supported found", rsc->GetCurCategory(), rsc->GetDeviceID(), rsc->GetVirtualDeviceId());
+ return rsc->GetDeviceID();
+ }
+ }
+ SERVER_INFO("scaler used by the app interlaced not supported not found");
+ return -1;
+}
+
+void CScalerStrategy::SelectConsumersBySwap(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)
+{
+ if (!ContainInterlacedNotSupportedApp(candidates)) {
+ SERVER_INFO("all scalers are being used by apps supporting interlaced");
+ return;
+ }
+
+ int scaler_id_sz = FindScalerInSameZone(zone_id);
+ if (scaler_id_sz < 0)
+ return;
+
+ int scaler_id_ins = FindScalerUsedByAppInterlacedNotSupported(candidates);
+ if (scaler_id_ins < 0)
+ return;
+
+ CResourceDB *db = CResourceDB::getInstance();
+ CResource *rsc_sz = db->FindResource(scaler_id_sz);
+ CResource *rsc_ins = db->FindResource(scaler_id_ins);
+
+ if (db->SwapScaler(rsc_sz->GetVirtualDeviceId(), rsc_ins->GetVirtualDeviceId()) < 0)
+ return;
+
+ db->UpdateVirtualScalerIds();
+
+ std::set<int> consumers = rsc_ins->GetConsumers();
+ for (auto const &it : consumers) {
+ SERVER_INFO("insert (%d:%d)", scaler_id_ins, it);
+ result->insert(std::pair<int, int>(scaler_id_ins, it));
+ }
+}
+
+void CScalerStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource*> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)
+{
+ std::multimap<int, int> consumer_list;
+ std::multimap<unsigned long, CVirtualResource *> filtered_vresources;
+ std::map<int, std::multimap<int, int>> candidates; // <vrsc id, <device id, consumer id>>
+
+ ExcludeResources(vresources, &filtered_vresources, req);
+
+ CDependencyController *dc = CDependencyController::getInstance();
+
+ for (auto const &it : filtered_vresources) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+ SERVER_INFO("vrsc(%d)/rsc(%d)", vresource->GetVResourceID(), resource->GetDeviceID());
+
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters())) {
+ if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), req->getRequester()->getHandle(), &consumer_list) != RMS_OK) {
+ SERVER_ERR("failed to find reclaimable consumer vrsc(%d)/rsc(%d)", vresource->GetVResourceID(), resource->GetDeviceID());
+ };
+ }
+ if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), req->getRequester()->getHandle(), &consumer_list, err_type) == RMS_OK) {
+ candidates.insert(std::pair<int, std::multimap<int, int>>(vresource->GetVResourceID(), consumer_list));
+ consumer_list.clear();
+ }
+ }
+ SERVER_INFO("zone id : %d, candidates(%zu)", req->GetMultiviewZoneId(), candidates.size());
+ if (req->GetMultiviewZoneId() > 0)
+ SelectConsumersByZoneId(req->GetMultiviewZoneId(), &candidates, &consumer_list);
+
+ if (consumer_list.empty() && (req->GetCategory() == RMS_CATEGORY_SCALER_INTERLACED))
+ SelectConsumersBySwap(req->GetMultiviewZoneId(), &candidates, &consumer_list);
+
+ if (consumer_list.empty())
+ SelectConsumersByAllocationTime(&candidates, &consumer_list);
+
+ for (auto const &it : consumer_list)
+ retirables->insert(std::pair<int, int>(it.first, it.second));
+}
-/*\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
-\r
-#include <ri-module-api.h>\r
-#include <rms_debug.h>\r
-#include <CResourceDB.h>\r
-#include <CBandwidth.h>\r
-#include <CResource.h>\r
-#include <CVirtualResource.h>\r
-#include <CRequest.h>\r
-#include <CRequester.h>\r
-#include <CPriority.h>\r
-#include <CDependencyController.h>\r
-#include <CAllocateStrategy.h>\r
-#include <CVideoDecoderStrategy.h>\r
-\r
-CVideoDecoderStrategy::CVideoDecoderStrategy()\r
-{\r
- m_reclaim_policy_by_zone_id = ri_get_zone_id_based_reclaim_policy();\r
-}\r
-\r
-void CVideoDecoderStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)\r
-{\r
- CRequester *requester = req->getRequester();\r
-\r
- if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
- return;\r
- }\r
-\r
- if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle())) {\r
- req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
- return;\r
- }\r
-\r
- if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)\r
- return;\r
-\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
-}\r
-\r
-void CVideoDecoderStrategy::updateReasonByBW(CVirtualResource *vresource, CRequest *req)\r
-{\r
- if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
- return;\r
- }\r
-\r
- rms_error_type_e reason = canReclaimRequiredBW(req, vresource->GetBW()) ?\r
- RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER:RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;\r
- req->SetReason(reason);\r
-}\r
-\r
-void CVideoDecoderStrategy::updateReasonByTripleDecoding(CRequest *req)\r
-{\r
- if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
- return;\r
- }\r
-\r
- rms_error_type_e reason = canReclaimActiveVideoDecoders(req) ?\r
- RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER : RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;\r
- req->SetReason(reason);\r
-}\r
-\r
-bool CVideoDecoderStrategy::isAllocatableResource(CVirtualResource *vresource, CRequest *req)\r
-{\r
- CResource *resource = vresource->GetResource();\r
- //int cat_id = vresource->GetCategoryType();\r
- //int vid = vresource->GetVResourceID();\r
- int device_id = resource->GetDeviceID();\r
-\r
- //SERVER_INFO("> cat(%d)/vid(%d) device id(%d)", cat_id, vid, device_id);\r
-\r
- if (resource->IsReserved()) {\r
- SERVER_INFO("device id(%d) is reserved state", device_id);\r
- return false;\r
- }\r
-\r
- if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters())) {\r
- updateReasonByMemCluster(vresource, req);\r
- return false;\r
- }\r
-\r
- CBandwidth *bandwidth = CBandwidth::GetInstance();\r
-\r
- if (vresource->GetBW() > bandwidth->GetAvail()) {\r
- SERVER_INFO("insufficient BW required(%d)/avail(%d)", vresource->GetBW(), bandwidth->GetAvail());\r
- updateReasonByBW(vresource, req);\r
- return false;\r
- }\r
-\r
- if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
- updateReasonByResourceState(device_id, req);\r
- return false;\r
- }\r
-\r
- if (!CResourceDB::getInstance()->HasAvailableDecoder()) {\r
- updateReasonByTripleDecoding(req);\r
- return false;\r
- }\r
-\r
- //SERVER_INFO("> cat(%d)/vid(%d) device id(%d) allocatable", cat_id, vid, device_id);\r
-\r
- return true;\r
-}\r
-\r
-CVirtualResource *CVideoDecoderStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)\r
-{\r
- std::map<int, CVirtualResource*> filtered_vresources;\r
- ExcludeResources(vresources, &filtered_vresources, req);\r
-\r
- req->SetResult(RMS_ERROR);\r
- req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);\r
-\r
- for (auto const &it : filtered_vresources) {\r
- CVirtualResource *vresource = it.second;\r
-\r
- if (!isAllocatableResource(vresource, req))\r
- continue;\r
-\r
- return vresource;\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-int CVideoDecoderStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)\r
-{\r
- CResource *rsc = vrsc->GetResource();\r
-\r
- if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)\r
- return RMS_ERROR;\r
-\r
- rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());\r
- return RMS_OK;\r
-}\r
-\r
-bool CVideoDecoderStrategy::ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources)\r
-{\r
- CDependencyController *dc = CDependencyController::getInstance();\r
- CBandwidth *bandwidth = CBandwidth::GetInstance();\r
-\r
- for (auto const &it : vresources) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *resource = vresource->GetResource();\r
-\r
- if (!dc->isAvailableMemClusters(vresource->GetMemClusters()))\r
- continue;\r
-\r
- if (bandwidth->GetAvail() < vresource->GetBW())\r
- continue;\r
-\r
- if (!resource->IsFreeState())\r
- continue;\r
-\r
- if (!CResourceDB::getInstance()->HasAvailableDecoder())\r
- continue;\r
-\r
- return true;\r
- }\r
-\r
- return false;\r
-}\r
-\r
-int CVideoDecoderStrategy::getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)\r
-{\r
- CDependencyController *dc = CDependencyController::getInstance();\r
- CResourceDB *resource_db = CResourceDB::getInstance();\r
- CResource *resource = vresource->GetResource();\r
- CBandwidth *bandwidth = CBandwidth::GetInstance();\r
- int requester_id = req->getRequester()->getHandle();\r
-\r
- SERVER_INFO(":: Get retirable consumers (%d:%d)", vresource->GetVResourceID(), resource->GetDeviceID());\r
-\r
- if (!dc->isAvailableMemClusters(vresource->GetMemClusters())) {\r
- SERVER_INFO("vrsc(%d)/rsc(%d)", vresource->GetVResourceID(), resource->GetDeviceID());\r
- if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), requester_id, retirables) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- if ((bandwidth->GetAvail() + GetReclaimedBW(retirables)) < vresource->GetBW()) {\r
- if (getConsumerUsingBW(req, vresource->GetBW(), retirables) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- if (!resource->IsFreeState()) {\r
- if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), requester_id, retirables, err_type) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- if (!resource_db->HasAvailableDecoder(*retirables)) {\r
- if (GetReclaimableVideoDecoderConsumers(requester_id, retirables, req, err_type) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- SERVER_WARN("RMS_OK");\r
- return RMS_OK;\r
-\r
-error:\r
- if (!retirables->empty())\r
- retirables->clear();\r
-\r
- return RMS_ERROR;\r
-}\r
-\r
-void CVideoDecoderStrategy::SelectInSameCategoryAndZone(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)\r
-{\r
- CResourceDB *db = CResourceDB::getInstance();\r
-\r
- for (auto const &it : *candidates) {\r
- std::multimap<int, int> candidate = it.second;\r
- for (auto const &itc : candidate) {\r
- CResource *rsc = db->FindResource(itc.first);\r
- if ((rsc->GetVirtualResourceID() == it.first) && (rsc->GetZoneId() == zone_id)) {\r
- SERVER_INFO("[%d] select (%d) > (%d:%d)", it.first, zone_id, itc.first, itc.second);\r
- result->insert(candidate.begin(), candidate.end());\r
- return;\r
- }\r
- }\r
- }\r
-}\r
-\r
-int CVideoDecoderStrategy::GetConflictScore(int n_conflicts)\r
-{\r
- return (10000 - n_conflicts);\r
-}\r
-\r
-void CVideoDecoderStrategy::SelectInSameZone(int zone_id, std::map<int, std::multimap<int, int>> candidates, std::multimap<int, int> *result)\r
-{\r
- CResourceDB *db = CResourceDB::getInstance();\r
- std::map<int, int> candidates_by_score;\r
-\r
- for (auto const &it : candidates) {\r
- std::multimap<int, int> candidate = it.second;\r
- for (auto const &itc : candidate) {\r
- CResource *rsc = db->FindResource(itc.first);\r
- if (rsc->GetZoneId() != zone_id)\r
- continue;\r
-\r
- int score = GetConflictScore(candidate.size());\r
- SERVER_INFO("insert (%d:%d) : score(%d) by (%d)", it.first, zone_id, score, itc.first);\r
- candidates_by_score.insert(std::pair<int, int>(score, it.first));\r
- }\r
- }\r
-\r
- if (candidates_by_score.empty())\r
- return;\r
-\r
- auto const top = candidates_by_score.rbegin();\r
- auto const it = candidates.find(top->second);\r
- if (it == candidates.end())\r
- return;\r
-\r
- std::multimap<int, int> selected = it->second;\r
- SERVER_INFO("select (%d:%d)", top->second, zone_id);\r
- result->insert(selected.begin(), selected.end());\r
-}\r
-\r
-void CVideoDecoderStrategy::SelectConsumersByZoneId(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)\r
-{\r
- if (zone_id <= 0) {\r
- SERVER_ERR("invalid zone id(%d)", zone_id);\r
- return;\r
- }\r
-\r
- SelectInSameCategoryAndZone(zone_id, candidates, result);\r
-\r
- if (!result->empty())\r
- return;\r
-\r
- SelectInSameZone(zone_id, *candidates, result);\r
-}\r
-\r
-void CVideoDecoderStrategy::SelectConsumersByAllocationTime(std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)\r
-{\r
- CResourceDB *db = CResourceDB::getInstance();\r
- std::map<unsigned long, int> candidates_by_alloc_t; // allocation time, virtual resource id\r
-\r
- std::map<int, int> conflicts; //virtual resource id, n conflicts\r
- int n_conflicts = 0;\r
- for (auto const &itn : *candidates) {\r
- std::multimap<int, int> candidate = itn.second;\r
- n_conflicts = candidate.size();\r
- if (n_conflicts > 0) {\r
- SERVER_INFO("vrsc(%d)/conflicts(%d)", itn.first, n_conflicts);\r
- conflicts.insert(std::pair<int, int>(itn.first, n_conflicts));\r
- }\r
- }\r
-\r
- bool inserted = false;\r
-\r
- for (auto const &it : *candidates) {\r
- std::multimap<int, int> candidate = it.second;\r
- n_conflicts = candidate.size();\r
- for (auto const &itc : candidate) {\r
- CResource *rsc = db->FindResource(itc.first);\r
- unsigned long alloc_t = rsc->GetAllocatedTime();\r
- SERVER_INFO("insert vrsc(%d)/dev(%d:%ld)/cid(%d)", it.first, itc.first, rsc->GetAllocatedTime(), itc.second);\r
- inserted = candidates_by_alloc_t.insert(std::pair<unsigned long, int>(alloc_t, it.first)).second;\r
- if (!inserted) {\r
- SERVER_INFO("t:%ld already in it", alloc_t);\r
- auto const &cur = candidates_by_alloc_t.find(alloc_t);\r
- if (cur == candidates_by_alloc_t.end())\r
- continue;\r
-\r
- auto const &n = conflicts.find(cur->second);\r
- if (n == conflicts.end())\r
- continue;\r
-\r
- int cur_conflicts = n->second;\r
- SERVER_INFO("cur_conflicts(%d)/n_conflicts(%d)", cur_conflicts, n_conflicts);\r
- if (cur_conflicts > n_conflicts) {\r
- candidates_by_alloc_t.erase(rsc->GetAllocatedTime());\r
- SERVER_INFO("insert vrsc(%d)/dev(%d:%ld)/cid(%d)", it.first, itc.first, rsc->GetAllocatedTime(), itc.second);\r
- candidates_by_alloc_t.insert(std::pair<unsigned long, int>(rsc->GetAllocatedTime(), it.first));\r
- }\r
- }\r
-\r
- }\r
- }\r
-\r
- auto itf = candidates_by_alloc_t.begin();\r
- if (itf == candidates_by_alloc_t.end()) {\r
- SERVER_ERR("no candidate");\r
- return;\r
- }\r
-\r
- auto const &ite = candidates->find(itf->second);\r
- std::multimap<int, int> *elected = &ite->second;\r
-\r
- result->insert(elected->begin(), elected->end());\r
-}\r
-\r
-void CVideoDecoderStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)\r
-{\r
- std::multimap<int, int> consumer_list;\r
- std::multimap<unsigned long, CVirtualResource *> filtered_vresources;\r
- std::map<int, std::multimap<int, int>> candidates;\r
-\r
- ExcludeResources(vresources, &filtered_vresources, req);\r
-\r
- if (ContainAvailableResource(filtered_vresources))\r
- return;\r
-\r
- for (auto const &it : filtered_vresources) {\r
- CVirtualResource *vresource = it.second;\r
-\r
- if (getRetirableConsumersExclusive(vresource, req, &consumer_list, err_type) == RMS_OK) {\r
- candidates.insert(std::pair<int, std::multimap<int, int>>(vresource->GetVResourceID(), consumer_list));\r
- consumer_list.clear();\r
- }\r
- }\r
-\r
- if (m_reclaim_policy_by_zone_id && req->GetMultiviewZoneId() > 0)\r
- SelectConsumersByZoneId(req->GetMultiviewZoneId(), &candidates, &consumer_list);\r
-\r
- if (consumer_list.empty())\r
- SelectConsumersByAllocationTime(&candidates, &consumer_list);\r
-\r
- for (auto const &it : consumer_list)\r
- retirables->insert(std::pair<int, int>(it.first, it.second));\r
-}\r
-\r
-bool CVideoDecoderStrategy::canReclaimRequiredBW(CRequest *req, unsigned int bw)\r
-{\r
- CRequester *requester = req->getRequester();\r
- CResourceDB *resource_db = CResourceDB::getInstance();\r
- CBandwidth *bandwidth = CBandwidth::GetInstance();\r
- unsigned int reclaimed_bw = bandwidth->GetAvail();\r
- std::map<int, int> bw_consumers = bandwidth->GetConsumers();\r
-\r
- for (std::map<int, int>::iterator it = bw_consumers.begin(); it != bw_consumers.end(); it++) {\r
- int device_id = (*it).first;\r
- int consumer_id = (*it).second;\r
-\r
- CResource *pRsc = resource_db->FindResource(device_id);\r
-\r
- if (!pRsc) {\r
- SERVER_ERR("cannot find resource using device id");\r
- continue;\r
- }\r
-\r
- if (requester->getHandle() == consumer_id) {\r
- SERVER_INFO("CID[%d] is using BW (%d)", requester->getHandle(), pRsc->GetBW());\r
- continue;\r
- }\r
-\r
- if (CPriority::compare(consumer_id, requester->getHandle()) != HIGH_PRIORITY)\r
- continue;\r
-\r
- reclaimed_bw += pRsc->GetBW();\r
-\r
- if (bw <= reclaimed_bw)\r
- break;\r
-\r
- SERVER_INFO("DevID[%d] / need more resource to be released!!! required BW(%d)-resource BW(%d)-check(%d)", pRsc->GetDeviceID(), bw, pRsc->GetBW(), reclaimed_bw);\r
- }\r
-\r
- SERVER_INFO("required BW(%d) - available (%d)", bw, reclaimed_bw);\r
-\r
- return (bw <= reclaimed_bw);\r
-\r
-}\r
-\r
-void CVideoDecoderStrategy::SelectDevicesByMainSub(CRequest *req, std::map<int, int> *src, std::map<int, int> *result)\r
-{\r
- CResourceDB *db = CResourceDB::getInstance();\r
-\r
- for (auto const &it : *src) {\r
- CResource *rsc = db->FindResource(it.first);\r
- if (!rsc)\r
- continue;\r
- if (req->IsMainDeviceRequest() && !rsc->IsMainDevice())\r
- continue;\r
- if (req->IsSubDeviceRequest() && rsc->IsMainDevice())\r
- continue;\r
-\r
- result->insert(std::pair<int, int>(it.first, it.second));\r
- }\r
-}\r
-\r
-int CVideoDecoderStrategy::getConsumerUsingBW(CRequest *req, unsigned int bw, std::multimap<int, int> *return_ids)\r
-{\r
- std::map<int, int> candidates;\r
- std::map<int, int> cur_consumers = CBandwidth::GetInstance()->GetConsumers(); //device id, consumer id\r
-\r
- SelectDevicesByMainSub(req, &cur_consumers, &candidates);\r
-\r
- std::multimap<int, int> reclaimed_by_ms;\r
- unsigned int avail_bw = GetConsumerUsingBWByAllocationTime(req->getRequester()->getHandle(), bw, candidates, &reclaimed_by_ms);\r
-\r
- if (avail_bw >= bw) {\r
- return_ids->insert(reclaimed_by_ms.begin(), reclaimed_by_ms.end());\r
- return RMS_OK;\r
- }\r
-\r
- std::multimap<int, int> reclaimed_by_t;\r
- GetConsumerUsingBWByAllocationTime(req->getRequester()->getHandle(), bw, cur_consumers, &reclaimed_by_t);\r
- return_ids->insert(reclaimed_by_t.begin(), reclaimed_by_t.end());\r
-\r
- return RMS_OK;\r
-}\r
-\r
-int CVideoDecoderStrategy::GetConsumerUsingBWByAllocationTime(int requester_id, unsigned int required_bw, std::map<int, int> bw_consumers, std::multimap<int, int> *reclaimed_consumers)\r
-{\r
- assert(reclaimed_consumers);\r
-\r
- CResourceDB *resource_db = CResourceDB::getInstance();\r
- CBandwidth *bandwidth = CBandwidth::GetInstance();\r
-\r
- SERVER_INFO("candidates using BW : %zu", bw_consumers.size());\r
- unsigned int reclaimed_bw = bandwidth->GetAvail();\r
-\r
- std::map<unsigned long, int> consumers_by_t;\r
- for (auto const &itc : bw_consumers) {\r
- CResource *rsc = resource_db->FindResource(itc.first);\r
- if (!rsc)\r
- continue;\r
-\r
- consumers_by_t.insert(std::pair<unsigned long, int>(rsc->GetAllocatedTime(), itc.first));\r
- }\r
-\r
- for (auto const &it : consumers_by_t) {\r
- int device_id = it.second;\r
- CResource *pRsc = resource_db->FindResource(device_id);\r
- if (!pRsc)\r
- continue;\r
-\r
- int consumer_id = pRsc->GetFirstConsumer();\r
- SERVER_INFO("consumer (%d) is using bw for device (%d)", consumer_id, device_id);\r
-\r
- if (requester_id == consumer_id) {\r
- SERVER_INFO("CID[%d] is using BW (%d)", requester_id, pRsc->GetBW());\r
- continue;\r
- }\r
-\r
- if (CPriority::compare(consumer_id, requester_id) != HIGH_PRIORITY)\r
- continue;\r
-\r
- auto ret = reclaimed_consumers->find(device_id);\r
- if (ret != reclaimed_consumers->end()) {\r
- SERVER_INFO("(%d:%d) already inserted", device_id, consumer_id);\r
- continue;\r
- }\r
-\r
- reclaimed_consumers->insert(std::pair<int, int>(device_id, consumer_id));\r
-\r
- if (pRsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) {\r
- std::map<int, int> siblings;\r
- bandwidth->GetConsumersNDec(pRsc->GetCurCategory(), &siblings);\r
- if (siblings.size() > 0) {\r
- SERVER_INFO("insert n-dec siblings(%zu)", siblings.size());\r
- reclaimed_consumers->insert(siblings.begin(), siblings.end());\r
- }\r
- }\r
-\r
- reclaimed_bw += pRsc->GetBW();\r
-\r
- if (required_bw <= reclaimed_bw)\r
- break;\r
- SERVER_INFO("DevID[%d]/ need more BW! required:(%d)-resource(%d)-reclaimed(%d)", pRsc->GetDeviceID(), required_bw, pRsc->GetBW(), reclaimed_bw);\r
- }\r
-\r
- return reclaimed_bw;\r
-}\r
-\r
-bool CVideoDecoderStrategy::canReclaimActiveVideoDecoders(CRequest *req)\r
-{\r
- CRequester *requester = req->getRequester();\r
- CResourceDB *resource_db = CResourceDB::getInstance();\r
- std::map<int, int> active_vdecs = resource_db->GetActiveVideoDecoders();\r
-\r
- for (auto const &it : active_vdecs) {\r
- int dev_id = it.first;\r
- int cid = it.second;\r
-\r
- CResource *rsc = resource_db->FindResource(dev_id);\r
-\r
- if (!rsc) {\r
- SERVER_ERR("can't find resource (%d)", dev_id);\r
- continue;\r
- }\r
-\r
- if (requester->getHandle() == cid) {\r
- SERVER_INFO("CID[%d] is using device (%d)", cid, dev_id);\r
- continue;\r
- }\r
-\r
- if (CPriority::compare(cid, requester->getHandle()) == HIGH_PRIORITY)\r
- return true;\r
- }\r
-\r
- return false;\r
-\r
-}\r
-\r
-int CVideoDecoderStrategy::GetReclaimableVideoDecoderConsumers(int consumer_id, std::multimap<int, int>* reclaimables, CRequest *req, rms_error_type_e *err_type)\r
-{\r
- std::map<unsigned long, CResource*> rscs;\r
- CResource *rsc = NULL;\r
- CResourceDB *db = CResourceDB::getInstance();\r
- std::map<int, int> active_vdecs = db->GetActiveVideoDecoders();\r
- bool has_main_vdec = false;\r
- bool has_sub_vdec = false;\r
-\r
- for (auto const &it_vdec : active_vdecs) {\r
- rsc = db->FindResource(it_vdec.first);\r
- rscs.insert(std::pair<unsigned long, CResource*>(rsc->GetAllocatedTime(), rsc));\r
-\r
- if (rsc->IsMainDevice())\r
- has_main_vdec = true;\r
- else\r
- has_sub_vdec = true;\r
- }\r
-\r
- for (auto const &it : rscs) {\r
- rsc = it.second;\r
-\r
- if (req->IsMainDeviceRequest() && has_main_vdec && !rsc->IsMainDevice())\r
- continue;\r
- if (req->IsSubDeviceRequest() && has_sub_vdec && rsc->IsMainDevice())\r
- continue;\r
-\r
- if (CPriority::getReclaimableConsumers(rsc->GetDeviceID(), consumer_id, reclaimables, err_type) == RMS_OK) {\r
- if (rsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) {\r
- std::map<int, int> active_ndecs = db->GetActiveNVideoDecoders();\r
- reclaimables->insert(active_ndecs.begin(), active_ndecs.end());\r
- }\r
- return RMS_OK;\r
- }\r
- }\r
-\r
- return RMS_ERROR;\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 <ri-module-api.h>
+#include <rms_debug.h>
+#include <CResourceDB.h>
+#include <CBandwidth.h>
+#include <CResource.h>
+#include <CVirtualResource.h>
+#include <CRequest.h>
+#include <CRequester.h>
+#include <CPriority.h>
+#include <CDependencyController.h>
+#include <CAllocateStrategy.h>
+#include <CVideoDecoderStrategy.h>
+
+CVideoDecoderStrategy::CVideoDecoderStrategy()
+{
+ m_reclaim_policy_by_zone_id = ri_get_zone_id_based_reclaim_policy();
+}
+
+void CVideoDecoderStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)
+{
+ CRequester *requester = req->getRequester();
+
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+ return;
+ }
+
+ if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle())) {
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);
+ return;
+ }
+
+ if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)
+ return;
+
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+}
+
+void CVideoDecoderStrategy::updateReasonByBW(CVirtualResource *vresource, CRequest *req)
+{
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+ return;
+ }
+
+ rms_error_type_e reason = canReclaimRequiredBW(req, vresource->GetBW()) ?
+ RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER:RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;
+ req->SetReason(reason);
+}
+
+void CVideoDecoderStrategy::updateReasonByTripleDecoding(CRequest *req)
+{
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+ return;
+ }
+
+ rms_error_type_e reason = canReclaimActiveVideoDecoders(req) ?
+ RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER : RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;
+ req->SetReason(reason);
+}
+
+bool CVideoDecoderStrategy::isAllocatableResource(CVirtualResource *vresource, CRequest *req)
+{
+ CResource *resource = vresource->GetResource();
+ //int cat_id = vresource->GetCategoryType();
+ //int vid = vresource->GetVResourceID();
+ int device_id = resource->GetDeviceID();
+
+ //SERVER_INFO("> cat(%d)/vid(%d) device id(%d)", cat_id, vid, device_id);
+
+ if (resource->IsReserved()) {
+ SERVER_INFO("device id(%d) is reserved state", device_id);
+ return false;
+ }
+
+ if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters())) {
+ updateReasonByMemCluster(vresource, req);
+ return false;
+ }
+
+ CBandwidth *bandwidth = CBandwidth::GetInstance();
+
+ if (vresource->GetBW() > bandwidth->GetAvail()) {
+ SERVER_INFO("insufficient BW required(%d)/avail(%d)", vresource->GetBW(), bandwidth->GetAvail());
+ updateReasonByBW(vresource, req);
+ return false;
+ }
+
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {
+ updateReasonByResourceState(device_id, req);
+ return false;
+ }
+
+ if (!CResourceDB::getInstance()->HasAvailableDecoder()) {
+ updateReasonByTripleDecoding(req);
+ return false;
+ }
+
+ //SERVER_INFO("> cat(%d)/vid(%d) device id(%d) allocatable", cat_id, vid, device_id);
+
+ return true;
+}
+
+CVirtualResource *CVideoDecoderStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)
+{
+ std::map<int, CVirtualResource*> filtered_vresources;
+ ExcludeResources(vresources, &filtered_vresources, req);
+
+ req->SetResult(RMS_ERROR);
+ req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);
+
+ for (auto const &it : filtered_vresources) {
+ CVirtualResource *vresource = it.second;
+
+ if (!isAllocatableResource(vresource, req))
+ continue;
+
+ return vresource;
+ }
+
+ return NULL;
+}
+
+int CVideoDecoderStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)
+{
+ CResource *rsc = vrsc->GetResource();
+
+ if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)
+ return RMS_ERROR;
+
+ rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());
+ return RMS_OK;
+}
+
+bool CVideoDecoderStrategy::ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources)
+{
+ CDependencyController *dc = CDependencyController::getInstance();
+ CBandwidth *bandwidth = CBandwidth::GetInstance();
+
+ for (auto const &it : vresources) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters()))
+ continue;
+
+ if (bandwidth->GetAvail() < vresource->GetBW())
+ continue;
+
+ if (!resource->IsFreeState())
+ continue;
+
+ if (!CResourceDB::getInstance()->HasAvailableDecoder())
+ continue;
+
+ return true;
+ }
+
+ return false;
+}
+
+int CVideoDecoderStrategy::getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)
+{
+ CDependencyController *dc = CDependencyController::getInstance();
+ CResourceDB *resource_db = CResourceDB::getInstance();
+ CResource *resource = vresource->GetResource();
+ CBandwidth *bandwidth = CBandwidth::GetInstance();
+ int requester_id = req->getRequester()->getHandle();
+
+ SERVER_INFO(":: Get retirable consumers (%d:%d)", vresource->GetVResourceID(), resource->GetDeviceID());
+
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters())) {
+ SERVER_INFO("vrsc(%d)/rsc(%d)", vresource->GetVResourceID(), resource->GetDeviceID());
+ if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), requester_id, retirables) != RMS_OK)
+ goto error;
+ }
+
+ if ((bandwidth->GetAvail() + GetReclaimedBW(retirables)) < vresource->GetBW()) {
+ if (getConsumerUsingBW(req, vresource->GetBW(), retirables) != RMS_OK)
+ goto error;
+ }
+
+ if (!resource->IsFreeState()) {
+ if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), requester_id, retirables, err_type) != RMS_OK)
+ goto error;
+ }
+
+ if (!resource_db->HasAvailableDecoder(*retirables)) {
+ if (GetReclaimableVideoDecoderConsumers(requester_id, retirables, req, err_type) != RMS_OK)
+ goto error;
+ }
+
+ SERVER_WARN("RMS_OK");
+ return RMS_OK;
+
+error:
+ if (!retirables->empty())
+ retirables->clear();
+
+ return RMS_ERROR;
+}
+
+void CVideoDecoderStrategy::SelectInSameCategoryAndZone(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)
+{
+ CResourceDB *db = CResourceDB::getInstance();
+
+ for (auto const &it : *candidates) {
+ std::multimap<int, int> candidate = it.second;
+ for (auto const &itc : candidate) {
+ CResource *rsc = db->FindResource(itc.first);
+ if ((rsc->GetVirtualResourceID() == it.first) && (rsc->GetZoneId() == zone_id)) {
+ SERVER_INFO("[%d] select (%d) > (%d:%d)", it.first, zone_id, itc.first, itc.second);
+ result->insert(candidate.begin(), candidate.end());
+ return;
+ }
+ }
+ }
+}
+
+int CVideoDecoderStrategy::GetConflictScore(int n_conflicts)
+{
+ return (10000 - n_conflicts);
+}
+
+void CVideoDecoderStrategy::SelectInSameZone(int zone_id, std::map<int, std::multimap<int, int>> candidates, std::multimap<int, int> *result)
+{
+ CResourceDB *db = CResourceDB::getInstance();
+ std::map<int, int> candidates_by_score;
+
+ for (auto const &it : candidates) {
+ std::multimap<int, int> candidate = it.second;
+ for (auto const &itc : candidate) {
+ CResource *rsc = db->FindResource(itc.first);
+ if (rsc->GetZoneId() != zone_id)
+ continue;
+
+ int score = GetConflictScore(candidate.size());
+ SERVER_INFO("insert (%d:%d) : score(%d) by (%d)", it.first, zone_id, score, itc.first);
+ candidates_by_score.insert(std::pair<int, int>(score, it.first));
+ }
+ }
+
+ if (candidates_by_score.empty())
+ return;
+
+ auto const top = candidates_by_score.rbegin();
+ auto const it = candidates.find(top->second);
+ if (it == candidates.end())
+ return;
+
+ std::multimap<int, int> selected = it->second;
+ SERVER_INFO("select (%d:%d)", top->second, zone_id);
+ result->insert(selected.begin(), selected.end());
+}
+
+void CVideoDecoderStrategy::SelectConsumersByZoneId(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)
+{
+ if (zone_id <= 0) {
+ SERVER_ERR("invalid zone id(%d)", zone_id);
+ return;
+ }
+
+ SelectInSameCategoryAndZone(zone_id, candidates, result);
+
+ if (!result->empty())
+ return;
+
+ SelectInSameZone(zone_id, *candidates, result);
+}
+
+void CVideoDecoderStrategy::SelectConsumersByAllocationTime(std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)
+{
+ CResourceDB *db = CResourceDB::getInstance();
+ std::map<unsigned long, int> candidates_by_alloc_t; // allocation time, virtual resource id
+
+ std::map<int, int> conflicts; //virtual resource id, n conflicts
+ int n_conflicts = 0;
+ for (auto const &itn : *candidates) {
+ std::multimap<int, int> candidate = itn.second;
+ n_conflicts = candidate.size();
+ if (n_conflicts > 0) {
+ SERVER_INFO("vrsc(%d)/conflicts(%d)", itn.first, n_conflicts);
+ conflicts.insert(std::pair<int, int>(itn.first, n_conflicts));
+ }
+ }
+
+ bool inserted = false;
+
+ for (auto const &it : *candidates) {
+ std::multimap<int, int> candidate = it.second;
+ n_conflicts = candidate.size();
+ for (auto const &itc : candidate) {
+ CResource *rsc = db->FindResource(itc.first);
+ unsigned long alloc_t = rsc->GetAllocatedTime();
+ SERVER_INFO("insert vrsc(%d)/dev(%d:%ld)/cid(%d)", it.first, itc.first, rsc->GetAllocatedTime(), itc.second);
+ inserted = candidates_by_alloc_t.insert(std::pair<unsigned long, int>(alloc_t, it.first)).second;
+ if (!inserted) {
+ SERVER_INFO("t:%ld already in it", alloc_t);
+ auto const &cur = candidates_by_alloc_t.find(alloc_t);
+ if (cur == candidates_by_alloc_t.end())
+ continue;
+
+ auto const &n = conflicts.find(cur->second);
+ if (n == conflicts.end())
+ continue;
+
+ int cur_conflicts = n->second;
+ SERVER_INFO("cur_conflicts(%d)/n_conflicts(%d)", cur_conflicts, n_conflicts);
+ if (cur_conflicts > n_conflicts) {
+ candidates_by_alloc_t.erase(rsc->GetAllocatedTime());
+ SERVER_INFO("insert vrsc(%d)/dev(%d:%ld)/cid(%d)", it.first, itc.first, rsc->GetAllocatedTime(), itc.second);
+ candidates_by_alloc_t.insert(std::pair<unsigned long, int>(rsc->GetAllocatedTime(), it.first));
+ }
+ }
+
+ }
+ }
+
+ auto itf = candidates_by_alloc_t.begin();
+ if (itf == candidates_by_alloc_t.end()) {
+ SERVER_ERR("no candidate");
+ return;
+ }
+
+ auto const &ite = candidates->find(itf->second);
+ std::multimap<int, int> *elected = &ite->second;
+
+ result->insert(elected->begin(), elected->end());
+}
+
+void CVideoDecoderStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)
+{
+ std::multimap<int, int> consumer_list;
+ std::multimap<unsigned long, CVirtualResource *> filtered_vresources;
+ std::map<int, std::multimap<int, int>> candidates;
+
+ ExcludeResources(vresources, &filtered_vresources, req);
+
+ if (ContainAvailableResource(filtered_vresources))
+ return;
+
+ for (auto const &it : filtered_vresources) {
+ CVirtualResource *vresource = it.second;
+
+ if (getRetirableConsumersExclusive(vresource, req, &consumer_list, err_type) == RMS_OK) {
+ candidates.insert(std::pair<int, std::multimap<int, int>>(vresource->GetVResourceID(), consumer_list));
+ consumer_list.clear();
+ }
+ }
+
+ if (m_reclaim_policy_by_zone_id && req->GetMultiviewZoneId() > 0)
+ SelectConsumersByZoneId(req->GetMultiviewZoneId(), &candidates, &consumer_list);
+
+ if (consumer_list.empty())
+ SelectConsumersByAllocationTime(&candidates, &consumer_list);
+
+ for (auto const &it : consumer_list)
+ retirables->insert(std::pair<int, int>(it.first, it.second));
+}
+
+bool CVideoDecoderStrategy::canReclaimRequiredBW(CRequest *req, unsigned int bw)
+{
+ CRequester *requester = req->getRequester();
+ CResourceDB *resource_db = CResourceDB::getInstance();
+ CBandwidth *bandwidth = CBandwidth::GetInstance();
+ unsigned int reclaimed_bw = bandwidth->GetAvail();
+ std::map<int, int> bw_consumers = bandwidth->GetConsumers();
+
+ for (std::map<int, int>::iterator it = bw_consumers.begin(); it != bw_consumers.end(); it++) {
+ int device_id = (*it).first;
+ int consumer_id = (*it).second;
+
+ CResource *pRsc = resource_db->FindResource(device_id);
+
+ if (!pRsc) {
+ SERVER_ERR("cannot find resource using device id");
+ continue;
+ }
+
+ if (requester->getHandle() == consumer_id) {
+ SERVER_INFO("CID[%d] is using BW (%d)", requester->getHandle(), pRsc->GetBW());
+ continue;
+ }
+
+ if (CPriority::compare(consumer_id, requester->getHandle()) != HIGH_PRIORITY)
+ continue;
+
+ reclaimed_bw += pRsc->GetBW();
+
+ if (bw <= reclaimed_bw)
+ break;
+
+ SERVER_INFO("DevID[%d] / need more resource to be released!!! required BW(%d)-resource BW(%d)-check(%d)", pRsc->GetDeviceID(), bw, pRsc->GetBW(), reclaimed_bw);
+ }
+
+ SERVER_INFO("required BW(%d) - available (%d)", bw, reclaimed_bw);
+
+ return (bw <= reclaimed_bw);
+
+}
+
+void CVideoDecoderStrategy::SelectDevicesByMainSub(CRequest *req, std::map<int, int> *src, std::map<int, int> *result)
+{
+ CResourceDB *db = CResourceDB::getInstance();
+
+ for (auto const &it : *src) {
+ CResource *rsc = db->FindResource(it.first);
+ if (!rsc)
+ continue;
+ if (req->IsMainDeviceRequest() && !rsc->IsMainDevice())
+ continue;
+ if (req->IsSubDeviceRequest() && rsc->IsMainDevice())
+ continue;
+
+ result->insert(std::pair<int, int>(it.first, it.second));
+ }
+}
+
+int CVideoDecoderStrategy::getConsumerUsingBW(CRequest *req, unsigned int bw, std::multimap<int, int> *return_ids)
+{
+ std::map<int, int> candidates;
+ std::map<int, int> cur_consumers = CBandwidth::GetInstance()->GetConsumers(); //device id, consumer id
+
+ SelectDevicesByMainSub(req, &cur_consumers, &candidates);
+
+ std::multimap<int, int> reclaimed_by_ms;
+ unsigned int avail_bw = GetConsumerUsingBWByAllocationTime(req->getRequester()->getHandle(), bw, candidates, &reclaimed_by_ms);
+
+ if (avail_bw >= bw) {
+ return_ids->insert(reclaimed_by_ms.begin(), reclaimed_by_ms.end());
+ return RMS_OK;
+ }
+
+ std::multimap<int, int> reclaimed_by_t;
+ GetConsumerUsingBWByAllocationTime(req->getRequester()->getHandle(), bw, cur_consumers, &reclaimed_by_t);
+ return_ids->insert(reclaimed_by_t.begin(), reclaimed_by_t.end());
+
+ return RMS_OK;
+}
+
+int CVideoDecoderStrategy::GetConsumerUsingBWByAllocationTime(int requester_id, unsigned int required_bw, std::map<int, int> bw_consumers, std::multimap<int, int> *reclaimed_consumers)
+{
+ assert(reclaimed_consumers);
+
+ CResourceDB *resource_db = CResourceDB::getInstance();
+ CBandwidth *bandwidth = CBandwidth::GetInstance();
+
+ SERVER_INFO("candidates using BW : %zu", bw_consumers.size());
+ unsigned int reclaimed_bw = bandwidth->GetAvail();
+
+ std::map<unsigned long, int> consumers_by_t;
+ for (auto const &itc : bw_consumers) {
+ CResource *rsc = resource_db->FindResource(itc.first);
+ if (!rsc)
+ continue;
+
+ consumers_by_t.insert(std::pair<unsigned long, int>(rsc->GetAllocatedTime(), itc.first));
+ }
+
+ for (auto const &it : consumers_by_t) {
+ int device_id = it.second;
+ CResource *pRsc = resource_db->FindResource(device_id);
+ if (!pRsc)
+ continue;
+
+ int consumer_id = pRsc->GetFirstConsumer();
+ SERVER_INFO("consumer (%d) is using bw for device (%d)", consumer_id, device_id);
+
+ if (requester_id == consumer_id) {
+ SERVER_INFO("CID[%d] is using BW (%d)", requester_id, pRsc->GetBW());
+ continue;
+ }
+
+ if (CPriority::compare(consumer_id, requester_id) != HIGH_PRIORITY)
+ continue;
+
+ auto ret = reclaimed_consumers->find(device_id);
+ if (ret != reclaimed_consumers->end()) {
+ SERVER_INFO("(%d:%d) already inserted", device_id, consumer_id);
+ continue;
+ }
+
+ reclaimed_consumers->insert(std::pair<int, int>(device_id, consumer_id));
+
+ if (pRsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) {
+ std::map<int, int> siblings;
+ bandwidth->GetConsumersNDec(pRsc->GetCurCategory(), &siblings);
+ if (siblings.size() > 0) {
+ SERVER_INFO("insert n-dec siblings(%zu)", siblings.size());
+ reclaimed_consumers->insert(siblings.begin(), siblings.end());
+ }
+ }
+
+ reclaimed_bw += pRsc->GetBW();
+
+ if (required_bw <= reclaimed_bw)
+ break;
+ SERVER_INFO("DevID[%d]/ need more BW! required:(%d)-resource(%d)-reclaimed(%d)", pRsc->GetDeviceID(), required_bw, pRsc->GetBW(), reclaimed_bw);
+ }
+
+ return reclaimed_bw;
+}
+
+bool CVideoDecoderStrategy::canReclaimActiveVideoDecoders(CRequest *req)
+{
+ CRequester *requester = req->getRequester();
+ CResourceDB *resource_db = CResourceDB::getInstance();
+ std::map<int, int> active_vdecs = resource_db->GetActiveVideoDecoders();
+
+ for (auto const &it : active_vdecs) {
+ int dev_id = it.first;
+ int cid = it.second;
+
+ CResource *rsc = resource_db->FindResource(dev_id);
+
+ if (!rsc) {
+ SERVER_ERR("can't find resource (%d)", dev_id);
+ continue;
+ }
+
+ if (requester->getHandle() == cid) {
+ SERVER_INFO("CID[%d] is using device (%d)", cid, dev_id);
+ continue;
+ }
+
+ if (CPriority::compare(cid, requester->getHandle()) == HIGH_PRIORITY)
+ return true;
+ }
+
+ return false;
+
+}
+
+int CVideoDecoderStrategy::GetReclaimableVideoDecoderConsumers(int consumer_id, std::multimap<int, int>* reclaimables, CRequest *req, rms_error_type_e *err_type)
+{
+ std::map<unsigned long, CResource*> rscs;
+ CResource *rsc = NULL;
+ CResourceDB *db = CResourceDB::getInstance();
+ std::map<int, int> active_vdecs = db->GetActiveVideoDecoders();
+ bool has_main_vdec = false;
+ bool has_sub_vdec = false;
+
+ for (auto const &it_vdec : active_vdecs) {
+ rsc = db->FindResource(it_vdec.first);
+ rscs.insert(std::pair<unsigned long, CResource*>(rsc->GetAllocatedTime(), rsc));
+
+ if (rsc->IsMainDevice())
+ has_main_vdec = true;
+ else
+ has_sub_vdec = true;
+ }
+
+ for (auto const &it : rscs) {
+ rsc = it.second;
+
+ if (req->IsMainDeviceRequest() && has_main_vdec && !rsc->IsMainDevice())
+ continue;
+ if (req->IsSubDeviceRequest() && has_sub_vdec && rsc->IsMainDevice())
+ continue;
+
+ if (CPriority::getReclaimableConsumers(rsc->GetDeviceID(), consumer_id, reclaimables, err_type) == RMS_OK) {
+ if (rsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) {
+ std::map<int, int> active_ndecs = db->GetActiveNVideoDecoders();
+ reclaimables->insert(active_ndecs.begin(), active_ndecs.end());
+ }
+ return RMS_OK;
+ }
+ }
+
+ return RMS_ERROR;
+}
-/*\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
-\r
-#include <rms_debug.h>\r
-#include <CResourceDB.h>\r
-#include <CResource.h>\r
-#include <CVirtualResource.h>\r
-#include <CRequest.h>\r
-#include <CRequester.h>\r
-#include <CPriority.h>\r
-#include <CDependencyController.h>\r
-#include <CAllocateStrategy.h>\r
-#include <CVideoEncoderExclusiveStrategy.h>\r
-\r
-void CVideoEncoderExclusiveStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)\r
-{\r
- CRequester *requester = req->getRequester();\r
-\r
- if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
- return;\r
- }\r
-\r
- if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle(), requester->getAppId())) {\r
- SERVER_ERR("canReclaimMemClusters is failed");\r
- req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
- return;\r
- }\r
-\r
- if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER) {\r
- SERVER_ERR("RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER");\r
- return;\r
- }\r
-\r
- req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
-}\r
-\r
-bool CVideoEncoderExclusiveStrategy::isAllocatableResource(CVirtualResource *vresource, CRequest *req)\r
-{\r
- CResource *resource = vresource->GetResource();\r
- CRequester *requester = req->getRequester();\r
-\r
- if (resource->IsReserved()) {\r
- SERVER_ERR("device id(%d) is reserved state", resource->GetDeviceID());\r
- return false;\r
- }\r
-\r
- if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters(), requester->getAppId())) {\r
- SERVER_ERR("isAvailableMemClusters is failed");\r
- updateReasonByMemCluster(vresource, req);\r
- return false;\r
- }\r
-\r
- if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
- SERVER_ERR("IsAllocatableState is failed");\r
- updateReasonByResourceState(resource->GetDeviceID(), req);\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-CVirtualResource *CVideoEncoderExclusiveStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)\r
-{\r
- std::map<int, CVirtualResource *> filtered_vresources;\r
- ExcludeResources(vresources, &filtered_vresources, req);\r
-\r
- req->SetResult(RMS_ERROR);\r
- req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);\r
-\r
- for (auto const &it : filtered_vresources) {\r
- CVirtualResource *vresource = it.second;\r
- if (!isAllocatableResource(vresource, req))\r
- continue;\r
-\r
- return vresource;\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-int CVideoEncoderExclusiveStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)\r
-{\r
- CResource *rsc = vrsc->GetResource();\r
-\r
- if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)\r
- return RMS_ERROR;\r
-\r
- rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());\r
-\r
- return RMS_OK;\r
-}\r
-\r
-bool CVideoEncoderExclusiveStrategy::ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req)\r
-{\r
- CDependencyController *dc = CDependencyController::getInstance();\r
- CRequester *requester = req->getRequester();\r
-\r
- for (auto const &it : vresources) {\r
- CVirtualResource *vresource = it.second;\r
- CResource *resource = vresource->GetResource();\r
-\r
- if (!dc->isAvailableMemClusters(vresource->GetMemClusters(), requester->getAppId()))\r
- continue;\r
-\r
- if (!resource->IsFreeState())\r
- continue;\r
-\r
- return true;\r
- }\r
-\r
- return false;\r
-}\r
-\r
-int CVideoEncoderExclusiveStrategy::getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)\r
-{\r
- CDependencyController *dc = CDependencyController::getInstance();\r
- CResource *resource = vresource->GetResource();\r
- CRequester *requester = req->getRequester();\r
-\r
- if (!requester) {\r
- SERVER_ERR("can't find requester");\r
- goto error;\r
- }\r
-\r
- if (!dc->isAvailableMemClusters(vresource->GetMemClusters(), requester->getAppId())) {\r
- if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), req->getRequester()->getHandle(), retirables, requester->getAppId()) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- if (!resource->IsFreeState()) {\r
- if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), req->getRequester()->getHandle(), retirables, err_type) != RMS_OK)\r
- goto error;\r
- }\r
-\r
- return RMS_OK;\r
-\r
-error:\r
- if (!retirables->empty())\r
- retirables->clear();\r
-\r
- return RMS_ERROR;\r
-}\r
-\r
-void CVideoEncoderExclusiveStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)\r
-{\r
- std::multimap<int, int> consumer_list;\r
- std::multimap<unsigned long, CVirtualResource *> filtered_vresources;\r
-\r
- ExcludeResources(vresources, &filtered_vresources, req);\r
-\r
- bool hasAllocatableResource = ContainAvailableResource(filtered_vresources, req);\r
- if (hasAllocatableResource)\r
- return;\r
-\r
- for (auto const &it : filtered_vresources) {\r
- CVirtualResource *vresource = it.second;\r
- if (getRetirableConsumersExclusive(vresource, req, &consumer_list, err_type) == RMS_OK)\r
- break;\r
- }\r
-\r
- for (auto const &it : consumer_list) {\r
- retirables->insert(std::pair<int, int>(it.first, it.second));\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 <assert.h>
+
+#include <rms_debug.h>
+#include <CResourceDB.h>
+#include <CResource.h>
+#include <CVirtualResource.h>
+#include <CRequest.h>
+#include <CRequester.h>
+#include <CPriority.h>
+#include <CDependencyController.h>
+#include <CAllocateStrategy.h>
+#include <CVideoEncoderExclusiveStrategy.h>
+
+void CVideoEncoderExclusiveStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)
+{
+ CRequester *requester = req->getRequester();
+
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+ return;
+ }
+
+ if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle(), requester->getAppId())) {
+ SERVER_ERR("canReclaimMemClusters is failed");
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);
+ return;
+ }
+
+ if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER) {
+ SERVER_ERR("RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER");
+ return;
+ }
+
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);
+}
+
+bool CVideoEncoderExclusiveStrategy::isAllocatableResource(CVirtualResource *vresource, CRequest *req)
+{
+ CResource *resource = vresource->GetResource();
+ CRequester *requester = req->getRequester();
+
+ if (resource->IsReserved()) {
+ SERVER_ERR("device id(%d) is reserved state", resource->GetDeviceID());
+ return false;
+ }
+
+ if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters(), requester->getAppId())) {
+ SERVER_ERR("isAvailableMemClusters is failed");
+ updateReasonByMemCluster(vresource, req);
+ return false;
+ }
+
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {
+ SERVER_ERR("IsAllocatableState is failed");
+ updateReasonByResourceState(resource->GetDeviceID(), req);
+ return false;
+ }
+
+ return true;
+}
+
+CVirtualResource *CVideoEncoderExclusiveStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)
+{
+ std::map<int, CVirtualResource *> filtered_vresources;
+ ExcludeResources(vresources, &filtered_vresources, req);
+
+ req->SetResult(RMS_ERROR);
+ req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);
+
+ for (auto const &it : filtered_vresources) {
+ CVirtualResource *vresource = it.second;
+ if (!isAllocatableResource(vresource, req))
+ continue;
+
+ return vresource;
+ }
+
+ return NULL;
+}
+
+int CVideoEncoderExclusiveStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)
+{
+ CResource *rsc = vrsc->GetResource();
+
+ if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)
+ return RMS_ERROR;
+
+ rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());
+
+ return RMS_OK;
+}
+
+bool CVideoEncoderExclusiveStrategy::ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req)
+{
+ CDependencyController *dc = CDependencyController::getInstance();
+ CRequester *requester = req->getRequester();
+
+ for (auto const &it : vresources) {
+ CVirtualResource *vresource = it.second;
+ CResource *resource = vresource->GetResource();
+
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters(), requester->getAppId()))
+ continue;
+
+ if (!resource->IsFreeState())
+ continue;
+
+ return true;
+ }
+
+ return false;
+}
+
+int CVideoEncoderExclusiveStrategy::getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)
+{
+ CDependencyController *dc = CDependencyController::getInstance();
+ CResource *resource = vresource->GetResource();
+ CRequester *requester = req->getRequester();
+
+ if (!requester) {
+ SERVER_ERR("can't find requester");
+ goto error;
+ }
+
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters(), requester->getAppId())) {
+ if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), req->getRequester()->getHandle(), retirables, requester->getAppId()) != RMS_OK)
+ goto error;
+ }
+
+ if (!resource->IsFreeState()) {
+ if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), req->getRequester()->getHandle(), retirables, err_type) != RMS_OK)
+ goto error;
+ }
+
+ return RMS_OK;
+
+error:
+ if (!retirables->empty())
+ retirables->clear();
+
+ return RMS_ERROR;
+}
+
+void CVideoEncoderExclusiveStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)
+{
+ std::multimap<int, int> consumer_list;
+ std::multimap<unsigned long, CVirtualResource *> filtered_vresources;
+
+ ExcludeResources(vresources, &filtered_vresources, req);
+
+ bool hasAllocatableResource = ContainAvailableResource(filtered_vresources, req);
+ if (hasAllocatableResource)
+ return;
+
+ for (auto const &it : filtered_vresources) {
+ CVirtualResource *vresource = it.second;
+ if (getRetirableConsumersExclusive(vresource, req, &consumer_list, err_type) == RMS_OK)
+ break;
+ }
+
+ for (auto const &it : consumer_list) {
+ retirables->insert(std::pair<int, int>(it.first, it.second));
+ }
+}