Remove CRLF line terminators 74/322274/2
authorYoungHun Kim <yh8004.kim@samsung.com>
Mon, 7 Apr 2025 06:39:41 +0000 (15:39 +0900)
committerYoungHun Kim <yh8004.kim@samsung.com>
Mon, 7 Apr 2025 22:21:56 +0000 (07:21 +0900)
Change-Id: Id0619321cb659d0f6f658402ae719c057b238a52

23 files changed:
packaging/rscmgr-service.spec
src/CCallback.cpp
src/CMessageHandler.cpp
src/manager/dependence/CAudioCodec.cpp
src/manager/dependence/CAudioCodecCollection.cpp
src/manager/dependence/CBandwidth.cpp
src/manager/dependence/CDependencyController.cpp
src/manager/dependence/CMemCluster.cpp
src/manager/dependence/CMixingMode.cpp
src/manager/strategy/CAllocateModeStrategyProvider.cpp
src/manager/strategy/CAllocateStrategy.cpp
src/manager/strategy/CAllocateStrategyProvider.cpp
src/manager/strategy/CAudioDecoderStrategy.cpp
src/manager/strategy/CExclusiveStrategy.cpp
src/manager/strategy/CInvalidModeStrategy.cpp
src/manager/strategy/CMixingStrategy.cpp
src/manager/strategy/CNDecodingVideoDecoderStrategy.cpp
src/manager/strategy/CNormalModeStrategy.cpp
src/manager/strategy/CNormalStrategy.cpp
src/manager/strategy/CPreferenceModeStrategy.cpp
src/manager/strategy/CScalerStrategy.cpp
src/manager/strategy/CVideoDecoderStrategy.cpp
src/manager/strategy/CVideoEncoderExclusiveStrategy.cpp

index 90e4baba8d21ee24435d0dce9b61c954ed045d96..5913e216570f34a2ed1ae713fc30ba5e4b9bfd84 100644 (file)
@@ -1,7 +1,7 @@
 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
index 1207408af412f6b02d03597a2205317012cb6d30..33977df72ed21fac74a452c82d002efd5f51e497 100644 (file)
@@ -61,7 +61,7 @@ int CCallback::SendCallbackMessage(int cid, int pid, void *callback_data, int si
 
        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;
index cf831146cfe608bc768565eefa9ef7384d83fd33..4c5c6277f2535b0be020cdabe193f429cc04ed24 100644 (file)
@@ -1005,7 +1005,6 @@ int CMessageHandler::ReclaimResources(int reason, int requester_cid, int request
                                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;
index 15dd2b8d2e4f140b22ae4abd7df5570a4f4b451a..60787ca8fb1ada06b732070585baed72a94ed355 100644 (file)
-/*\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;
+}
index 5d7364045744c693961feff077263d958a6db0f3..8468cff5dd6c2a34ca96033e2657e0ab24706e6d 100644 (file)
@@ -1,62 +1,62 @@
-/*\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();
+}
index c9535df01368c6133fa6189424cd9c7930b667c1..075122885bbf84708771b42f639873a0d6db7231 100644 (file)
-/*\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;
+}
index b6fe90f8083b81b48225081c1e01a51d3716462d..ee64a003e568b4d89b126509a16e38f9f62430a6 100644 (file)
-/*\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;
+}
index 7da1ce8333a4117d5c588ff4d1650fd2e46ae49c..77312f349342b94db83d340e1706330febb889fb 100644 (file)
-/*\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;
+}
index 131bd5e69fc381d389007f22fa9902270f42c884..64d32a3afa998d5c94621dfb788574b11c4ff38c 100644 (file)
@@ -1,48 +1,48 @@
-/*\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();
+}
+
index 9a715a37a66bbbada6ef67694dbd5af655ab2b29..84099ca08f5643d34b74bfc48aed2a29c8e71bde 100644 (file)
@@ -1,93 +1,93 @@
-/*\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;
+}
index 621605b4f739b56e15f0cd0663c0e8c695ff5701..9c9971707722faddd6014b526d75d80c08393b4e 100644 (file)
-/*\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);
+       }
+}
index 840a8a2a70b976b4b62e4e2fffa68f0d9fdcc074..37213058c5dc358dee51c47c3cf77995d3ef0a43 100644 (file)
-/*\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;
+}
index 984ad8eedc397d085a71585d689b57df31587b4f..5f6b536d85b18063a5a79a2b583e429bd3879357 100644 (file)
-/*\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));
+       }
+}
index 04f9f971923302872f701fe6c430cf15aff46908..f6e235fbcf7168bd22a6d9fd25f3a0e4d4fb7522 100644 (file)
-/*\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));
+       }
+}
index f314e48521f4bb1bada4125663c0c248eaabe70f..1ec0b830e90c68f413afcf27fe14ec580b9b450d 100644 (file)
@@ -1,52 +1,52 @@
-/*\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;
+}
index db58961e49af4b4359e7ee96e1e97905b0e7c2cd..bd9493cfda9ddabb3c79d2739168559ff2796f37 100644 (file)
-/*\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;
+
+}
index 6291dc6c86060071fc99ccb3afc47a926fa3809d..dd002547af26199c06f184eaa2c4f03884cb48be 100644 (file)
-/*\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;
+}
index be8f4f8f6ae6cd154f0cd6b5678876d5d62de06b..e24e37a9f36d25a680210b2264176383527f3bf4 100644 (file)
-/*\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++;
+       }
+}
index 49846b19824051bb76e918732e33fa88ef8cf60c..2dd1679f6a49f08a847c68646079aaa03fd0a067 100644 (file)
-/*\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));
+       }
+}
index 05c60a10005839eeb630301614a2a3e17d478948..d9da9c7004ff8b6799c8e65b9010dbf31f34612c 100644 (file)
-/*\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++;
+       }
+}
+
index 5cca7814a33da9cbcba1a71b7d4d089382bb0d72..9962f4a13ef360216483fffa3dbf721848499d24 100644 (file)
-/*\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));
+}
index c02f504073427a28b65ef4c396d1cb2409d5e6e9..10e6169bd931b46fa4cca58c42171ff957d86f16 100644 (file)
-/*\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;
+}
index 3e0669127a6a7999f1fd76e2b77222af6897fdbb..b39ac824c17b6567551485ff4602c034fe8b8938 100644 (file)
-/*\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));
+       }
+}