From 7236e99d6f1374e489fd3718fa307f325ba48ebd Mon Sep 17 00:00:00 2001 From: YoungHun Kim Date: Mon, 7 Apr 2025 15:39:41 +0900 Subject: [PATCH] Remove CRLF line terminators Change-Id: Id0619321cb659d0f6f658402ae719c057b238a52 --- packaging/rscmgr-service.spec | 2 +- src/CCallback.cpp | 2 +- src/CMessageHandler.cpp | 1 - src/manager/dependence/CAudioCodec.cpp | 216 +-- .../dependence/CAudioCodecCollection.cpp | 124 +- src/manager/dependence/CBandwidth.cpp | 328 ++--- .../dependence/CDependencyController.cpp | 1014 +++++++------- src/manager/dependence/CMemCluster.cpp | 282 ++-- src/manager/dependence/CMixingMode.cpp | 96 +- .../CAllocateModeStrategyProvider.cpp | 186 +-- src/manager/strategy/CAllocateStrategy.cpp | 302 ++--- .../strategy/CAllocateStrategyProvider.cpp | 306 ++--- .../strategy/CAudioDecoderStrategy.cpp | 292 ++-- src/manager/strategy/CExclusiveStrategy.cpp | 498 +++---- src/manager/strategy/CInvalidModeStrategy.cpp | 104 +- src/manager/strategy/CMixingStrategy.cpp | 534 ++++---- .../CNDecodingVideoDecoderStrategy.cpp | 896 ++++++------- src/manager/strategy/CNormalModeStrategy.cpp | 306 ++--- src/manager/strategy/CNormalStrategy.cpp | 214 +-- .../strategy/CPreferenceModeStrategy.cpp | 222 ++-- src/manager/strategy/CScalerStrategy.cpp | 546 ++++---- .../strategy/CVideoDecoderStrategy.cpp | 1180 ++++++++--------- .../CVideoEncoderExclusiveStrategy.cpp | 360 ++--- 23 files changed, 4005 insertions(+), 4006 deletions(-) diff --git a/packaging/rscmgr-service.spec b/packaging/rscmgr-service.spec index 90e4bab..5913e21 100644 --- a/packaging/rscmgr-service.spec +++ b/packaging/rscmgr-service.spec @@ -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 diff --git a/src/CCallback.cpp b/src/CCallback.cpp index 1207408..33977df 100644 --- a/src/CCallback.cpp +++ b/src/CCallback.cpp @@ -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; diff --git a/src/CMessageHandler.cpp b/src/CMessageHandler.cpp index cf83114..4c5c627 100644 --- a/src/CMessageHandler.cpp +++ b/src/CMessageHandler.cpp @@ -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; diff --git a/src/manager/dependence/CAudioCodec.cpp b/src/manager/dependence/CAudioCodec.cpp index 15dd2b8..60787ca 100644 --- a/src/manager/dependence/CAudioCodec.cpp +++ b/src/manager/dependence/CAudioCodec.cpp @@ -1,108 +1,108 @@ -/* - * 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 -#include - -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(device_id, consumer_id)); - - if (it == m_consumers.end()) { - m_consumers.insert(std::pair(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 CAudioCodec::getResourcesOfConsumer(int consumer_id) -{ - std::set resources; - - for (auto const &it : m_resources) { - if (it.second == consumer_id) - resources.insert(it.first); - } - - return resources; -} +/* + * 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 +#include + +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(device_id, consumer_id)); + + if (it == m_consumers.end()) { + m_consumers.insert(std::pair(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 CAudioCodec::getResourcesOfConsumer(int consumer_id) +{ + std::set resources; + + for (auto const &it : m_resources) { + if (it.second == consumer_id) + resources.insert(it.first); + } + + return resources; +} diff --git a/src/manager/dependence/CAudioCodecCollection.cpp b/src/manager/dependence/CAudioCodecCollection.cpp index 5d73640..8468cff 100644 --- a/src/manager/dependence/CAudioCodecCollection.cpp +++ b/src/manager/dependence/CAudioCodecCollection.cpp @@ -1,62 +1,62 @@ -/* - * 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 - -#include -#include - -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(name), audio_codec)); - } - - if (count > 0) - audio_codec->increaseMaxRef(); -} +/* + * 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 + +#include +#include + +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(name), audio_codec)); + } + + if (count > 0) + audio_codec->increaseMaxRef(); +} diff --git a/src/manager/dependence/CBandwidth.cpp b/src/manager/dependence/CBandwidth.cpp index c9535df..0751228 100644 --- a/src/manager/dependence/CBandwidth.cpp +++ b/src/manager/dependence/CBandwidth.cpp @@ -1,164 +1,164 @@ -/* - * 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 -#include -#include -#include -#include -#include - -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 consumers; - consumers.insert(std::pair(device_id, consumer_id)); - m_ndec_consumers.insert(std::pair>(category_id, consumers)); - } - else - { - std::map *consumers = &it->second; - consumers->insert(std::pair(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 *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(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 c_mc; - - CResourceDB *db = CResourceDB::getInstance(); - CResource *u_rsc = db->FindResource(device_id); - CVirtualResource *u_vrsc = db->FindVirtualResource(u_rsc->GetVirtualResourceID()); - - std::set u_mc = u_vrsc->GetMemClusters(); - - std::map 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 c_mc, std::set 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; -} +/* + * 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 +#include +#include +#include +#include +#include + +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 consumers; + consumers.insert(std::pair(device_id, consumer_id)); + m_ndec_consumers.insert(std::pair>(category_id, consumers)); + } + else + { + std::map *consumers = &it->second; + consumers->insert(std::pair(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 *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(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 c_mc; + + CResourceDB *db = CResourceDB::getInstance(); + CResource *u_rsc = db->FindResource(device_id); + CVirtualResource *u_vrsc = db->FindVirtualResource(u_rsc->GetVirtualResourceID()); + + std::set u_mc = u_vrsc->GetMemClusters(); + + std::map 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 c_mc, std::set 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; +} diff --git a/src/manager/dependence/CDependencyController.cpp b/src/manager/dependence/CDependencyController.cpp index b6fe90f..ee64a00 100644 --- a/src/manager/dependence/CDependencyController.cpp +++ b/src/manager/dependence/CDependencyController.cpp @@ -1,507 +1,507 @@ -/* - * 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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(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(id, mc)); -} - -bool CDependencyController::isAvailableMemClusters(std::set 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 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 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 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 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 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 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 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 mc_ids, int consumer_id, std::multimap* 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 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 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(it_dev_id, it_consumer)); - } - } - } - - return RMS_OK; -} - -int CDependencyController::getReclaimableMemClusterConsumers(std::set mc_ids, int consumer_id, std::multimap* 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 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 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(it_dev_id, it_consumer)); - } - } - } - - return RMS_OK; -} - -void CDependencyController::SwapConsumers(int device_id_a, std::set consumers_a, int device_id_b, std::set 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 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 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 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 (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> CDependencyController::getAudioCodecConsumers(void) -{ - std::map> consumers; - - for (auto const &it : m_acodec_consumers) { - CResource *rsc = CResourceDB::getInstance()->FindResource(it.first); - consumers.insert(std::pair>(rsc->GetAllocatedTime(), std::make_pair(it.first, it.second))); - } - - return consumers; -} +/* + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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(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(id, mc)); +} + +bool CDependencyController::isAvailableMemClusters(std::set 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 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 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 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 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 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 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 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 mc_ids, int consumer_id, std::multimap* 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 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 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(it_dev_id, it_consumer)); + } + } + } + + return RMS_OK; +} + +int CDependencyController::getReclaimableMemClusterConsumers(std::set mc_ids, int consumer_id, std::multimap* 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 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 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(it_dev_id, it_consumer)); + } + } + } + + return RMS_OK; +} + +void CDependencyController::SwapConsumers(int device_id_a, std::set consumers_a, int device_id_b, std::set 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 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 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 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 (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> CDependencyController::getAudioCodecConsumers(void) +{ + std::map> consumers; + + for (auto const &it : m_acodec_consumers) { + CResource *rsc = CResourceDB::getInstance()->FindResource(it.first); + consumers.insert(std::pair>(rsc->GetAllocatedTime(), std::make_pair(it.first, it.second))); + } + + return consumers; +} diff --git a/src/manager/dependence/CMemCluster.cpp b/src/manager/dependence/CMemCluster.cpp index 7da1ce8..77312f3 100644 --- a/src/manager/dependence/CMemCluster.cpp +++ b/src/manager/dependence/CMemCluster.cpp @@ -1,141 +1,141 @@ -/* - * 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 -#include -#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 device_ids; - device_ids.insert(device_id); - m_consumers.insert(std::pair>(consumer_id, device_ids)); - m_category_class = category_class; - m_category_id = category_id; - } else { - std::set &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 &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 CMemCluster::GetConsumers(void) -{ - std::set consumers; - - for (const auto& it : m_consumers) - consumers.insert(it.first); - - return consumers; -} - -void CMemCluster::ClearConsumers(void) -{ - for (auto &it : m_consumers) { - std::set &id_it = it.second; - id_it.clear(); - } - m_consumers.clear(); -} - -std::set CMemCluster::GetAssignedDeviceId(int consumer_id) -{ - std::set 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; -} +/* + * 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 +#include +#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 device_ids; + device_ids.insert(device_id); + m_consumers.insert(std::pair>(consumer_id, device_ids)); + m_category_class = category_class; + m_category_id = category_id; + } else { + std::set &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 &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 CMemCluster::GetConsumers(void) +{ + std::set consumers; + + for (const auto& it : m_consumers) + consumers.insert(it.first); + + return consumers; +} + +void CMemCluster::ClearConsumers(void) +{ + for (auto &it : m_consumers) { + std::set &id_it = it.second; + id_it.clear(); + } + m_consumers.clear(); +} + +std::set CMemCluster::GetAssignedDeviceId(int consumer_id) +{ + std::set 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; +} diff --git a/src/manager/dependence/CMixingMode.cpp b/src/manager/dependence/CMixingMode.cpp index 131bd5e..64d32a3 100644 --- a/src/manager/dependence/CMixingMode.cpp +++ b/src/manager/dependence/CMixingMode.cpp @@ -1,48 +1,48 @@ -/* - * 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 -#include - -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(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(); -} - +/* + * 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 +#include + +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(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(); +} + diff --git a/src/manager/strategy/CAllocateModeStrategyProvider.cpp b/src/manager/strategy/CAllocateModeStrategyProvider.cpp index 9a715a3..84099ca 100644 --- a/src/manager/strategy/CAllocateModeStrategyProvider.cpp +++ b/src/manager/strategy/CAllocateModeStrategyProvider.cpp @@ -1,93 +1,93 @@ -/* - * 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 - -#include -#include -#include -#include -#include - -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; -} +/* + * 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 + +#include +#include +#include +#include +#include + +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; +} diff --git a/src/manager/strategy/CAllocateStrategy.cpp b/src/manager/strategy/CAllocateStrategy.cpp index 621605b..9c99717 100644 --- a/src/manager/strategy/CAllocateStrategy.cpp +++ b/src/manager/strategy/CAllocateStrategy.cpp @@ -1,151 +1,151 @@ -/* - * 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 -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void CAllocateStrategy::ExcludeResources(std::map vresources, std::map* 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(it.first, it.second)); - } -} - -void CAllocateStrategy::ExcludeResources(std::multimap vresources, std::multimap* 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(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 *retirables) -{ - CResourceDB *db = CResourceDB::getInstance(); - std::set 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 *retirables, std::set *excluded) -{ - assert(retirables); - assert(excluded); - std::map 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(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); - } -} +/* + * 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void CAllocateStrategy::ExcludeResources(std::map vresources, std::map* 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(it.first, it.second)); + } +} + +void CAllocateStrategy::ExcludeResources(std::multimap vresources, std::multimap* 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(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 *retirables) +{ + CResourceDB *db = CResourceDB::getInstance(); + std::set 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 *retirables, std::set *excluded) +{ + assert(retirables); + assert(excluded); + std::map 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(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); + } +} diff --git a/src/manager/strategy/CAllocateStrategyProvider.cpp b/src/manager/strategy/CAllocateStrategyProvider.cpp index 840a8a2..3721305 100644 --- a/src/manager/strategy/CAllocateStrategyProvider.cpp +++ b/src/manager/strategy/CAllocateStrategyProvider.cpp @@ -1,153 +1,153 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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; -} +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/src/manager/strategy/CAudioDecoderStrategy.cpp b/src/manager/strategy/CAudioDecoderStrategy.cpp index 984ad8e..5f6b536 100644 --- a/src/manager/strategy/CAudioDecoderStrategy.cpp +++ b/src/manager/strategy/CAudioDecoderStrategy.cpp @@ -1,146 +1,146 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -CVirtualResource *CAudioDecoderStrategy::findCandidate(std::map vresources, CRequest *req) -{ - std::map 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 *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 vresources, CRequest *req, std::multimap* retirables, rms_error_type_e *err_type) -{ - std::map consumer_list; - std::multimap 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(it.first, it.second)); - } -} +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +CVirtualResource *CAudioDecoderStrategy::findCandidate(std::map vresources, CRequest *req) +{ + std::map 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 *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 vresources, CRequest *req, std::multimap* retirables, rms_error_type_e *err_type) +{ + std::map consumer_list; + std::multimap 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(it.first, it.second)); + } +} diff --git a/src/manager/strategy/CExclusiveStrategy.cpp b/src/manager/strategy/CExclusiveStrategy.cpp index 04f9f97..f6e235f 100644 --- a/src/manager/strategy/CExclusiveStrategy.cpp +++ b/src/manager/strategy/CExclusiveStrategy.cpp @@ -1,249 +1,249 @@ -/* - * 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 vresources, CRequest *req) -{ - std::map 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 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 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 *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 *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 vresources, CRequest *req, std::multimap* retirables, rms_error_type_e *err_type) -{ - std::multimap consumer_list; - std::multimap 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(it.first, it.second)); - } -} +/* + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 vresources, CRequest *req) +{ + std::map 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 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 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 *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 *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 vresources, CRequest *req, std::multimap* retirables, rms_error_type_e *err_type) +{ + std::multimap consumer_list; + std::multimap 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(it.first, it.second)); + } +} diff --git a/src/manager/strategy/CInvalidModeStrategy.cpp b/src/manager/strategy/CInvalidModeStrategy.cpp index f314e48..1ec0b83 100644 --- a/src/manager/strategy/CInvalidModeStrategy.cpp +++ b/src/manager/strategy/CInvalidModeStrategy.cpp @@ -1,52 +1,52 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include - -CInvalidModeStrategy::CInvalidModeStrategy() -{ -} - -CInvalidModeStrategy::~CInvalidModeStrategy() -{ -} - -bool CInvalidModeStrategy::CanAllocateResources(std::vector 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 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; -} +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + +CInvalidModeStrategy::CInvalidModeStrategy() +{ +} + +CInvalidModeStrategy::~CInvalidModeStrategy() +{ +} + +bool CInvalidModeStrategy::CanAllocateResources(std::vector 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 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; +} diff --git a/src/manager/strategy/CMixingStrategy.cpp b/src/manager/strategy/CMixingStrategy.cpp index db58961..bd9493c 100644 --- a/src/manager/strategy/CMixingStrategy.cpp +++ b/src/manager/strategy/CMixingStrategy.cpp @@ -1,267 +1,267 @@ -/* - * 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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* 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> 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(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(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* 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 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(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 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> 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; - -} +/* + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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* 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> 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(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(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* 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 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(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 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> 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; + +} diff --git a/src/manager/strategy/CNDecodingVideoDecoderStrategy.cpp b/src/manager/strategy/CNDecodingVideoDecoderStrategy.cpp index 6291dc6..dd00254 100644 --- a/src/manager/strategy/CNDecodingVideoDecoderStrategy.cpp +++ b/src/manager/strategy/CNDecodingVideoDecoderStrategy.cpp @@ -1,448 +1,448 @@ -/* - * 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 vresources, CRequest *req) -{ - std::map 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 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 *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 vresources, CRequest *req, std::multimap* retirables, rms_error_type_e *err_type) -{ - std::multimap consumer_list; - std::multimap 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 bw_consumers = bandwidth->GetConsumers(); - - for (std::map::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 *src, std::map *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(it.first, it.second)); - } -} - -int CNDecodingVideoDecoderStrategy::GetConsumerUsingBW(CRequest *req, unsigned int bw, std::multimap* return_ids) -{ - std::map candidates; - std::map cur_consumers = CBandwidth::GetInstance()->GetConsumers(); //device id, consumer id - - SelectDevicesByMainSub(req, &cur_consumers, &candidates); - - std::multimap 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 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 bw_consumers, std::multimap* 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 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(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(device_id, consumer_id)); - - if (pRsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) { - std::map 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 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* reclaimables, CRequest *req, rms_error_type_e *err_type) -{ - std::map rscs; - CResource *rsc = NULL; - CResourceDB *resource_db = CResourceDB::getInstance(); - std::map 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(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; -} +/* + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 vresources, CRequest *req) +{ + std::map 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 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 *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 vresources, CRequest *req, std::multimap* retirables, rms_error_type_e *err_type) +{ + std::multimap consumer_list; + std::multimap 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 bw_consumers = bandwidth->GetConsumers(); + + for (std::map::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 *src, std::map *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(it.first, it.second)); + } +} + +int CNDecodingVideoDecoderStrategy::GetConsumerUsingBW(CRequest *req, unsigned int bw, std::multimap* return_ids) +{ + std::map candidates; + std::map cur_consumers = CBandwidth::GetInstance()->GetConsumers(); //device id, consumer id + + SelectDevicesByMainSub(req, &cur_consumers, &candidates); + + std::multimap 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 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 bw_consumers, std::multimap* 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 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(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(device_id, consumer_id)); + + if (pRsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) { + std::map 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 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* reclaimables, CRequest *req, rms_error_type_e *err_type) +{ + std::map rscs; + CResource *rsc = NULL; + CResourceDB *resource_db = CResourceDB::getInstance(); + std::map 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(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; +} diff --git a/src/manager/strategy/CNormalModeStrategy.cpp b/src/manager/strategy/CNormalModeStrategy.cpp index be8f4f8..e24e37a 100644 --- a/src/manager/strategy/CNormalModeStrategy.cpp +++ b/src/manager/strategy/CNormalModeStrategy.cpp @@ -1,153 +1,153 @@ -/* - * 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 -#include - -#include -#include -#include -#include -#include -#include -#include - -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 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 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 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++; - } -} +/* + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +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 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 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 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++; + } +} diff --git a/src/manager/strategy/CNormalStrategy.cpp b/src/manager/strategy/CNormalStrategy.cpp index 49846b1..2dd1679 100644 --- a/src/manager/strategy/CNormalStrategy.cpp +++ b/src/manager/strategy/CNormalStrategy.cpp @@ -1,107 +1,107 @@ -/* - * 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 - -#include -#include -#include -#include -#include -#include -#include -#include - -CNormalStrategy::CNormalStrategy() -{ -} - -CNormalStrategy::~CNormalStrategy() -{ -} - -CVirtualResource *CNormalStrategy::findCandidate(std::map vresources, CRequest *req) -{ - std::map 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 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 vresources, CRequest *req, std::multimap* retirables, rms_error_type_e *err_type) -{ - std::multimap consumer_list; - std::multimap 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(it.first, it.second)); - } -} +/* + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +CNormalStrategy::CNormalStrategy() +{ +} + +CNormalStrategy::~CNormalStrategy() +{ +} + +CVirtualResource *CNormalStrategy::findCandidate(std::map vresources, CRequest *req) +{ + std::map 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 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 vresources, CRequest *req, std::multimap* retirables, rms_error_type_e *err_type) +{ + std::multimap consumer_list; + std::multimap 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(it.first, it.second)); + } +} diff --git a/src/manager/strategy/CPreferenceModeStrategy.cpp b/src/manager/strategy/CPreferenceModeStrategy.cpp index 05c60a1..d9da9c7 100644 --- a/src/manager/strategy/CPreferenceModeStrategy.cpp +++ b/src/manager/strategy/CPreferenceModeStrategy.cpp @@ -1,111 +1,111 @@ -/* - * 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 -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -CPreferenceModeStrategy::CPreferenceModeStrategy() -{ -} - -CPreferenceModeStrategy::~CPreferenceModeStrategy() -{ -} - -bool CPreferenceModeStrategy::CanAllocateResources(std::vector 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 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++; - } -} - +/* + * 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 +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +CPreferenceModeStrategy::CPreferenceModeStrategy() +{ +} + +CPreferenceModeStrategy::~CPreferenceModeStrategy() +{ +} + +bool CPreferenceModeStrategy::CanAllocateResources(std::vector 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 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++; + } +} + diff --git a/src/manager/strategy/CScalerStrategy.cpp b/src/manager/strategy/CScalerStrategy.cpp index 5cca781..9962f4a 100644 --- a/src/manager/strategy/CScalerStrategy.cpp +++ b/src/manager/strategy/CScalerStrategy.cpp @@ -1,273 +1,273 @@ -/* - * 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 vresources, CRequest *req) -{ - std::map 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 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> *candidates, std::multimap *result) -{ - CResourceDB *db = CResourceDB::getInstance(); - std::map candidates_by_alloc_t; // allocation time, virtual resource id - - for (auto const &it : *candidates) { - std::multimap candidate = it.second; - for (auto const &itc : candidate) { - CResource *rsc = db->FindResource(itc.first); - candidates_by_alloc_t.insert(std::pair(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 *elected = &ite->second; - - result->insert(elected->begin(), elected->end()); -} - -void CScalerStrategy::SelectConsumersByZoneId(int zone_id, std::map> *candidates, std::multimap *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 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> *candidates) -{ - CResourceDB *db = CResourceDB::getInstance(); - - for (auto const &it : *candidates) { - std::multimap 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 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> *candidates) -{ - CResourceDB *db = CResourceDB::getInstance(); - for (auto const &it : *candidates) { - std::multimap 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> *candidates, std::multimap *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 consumers = rsc_ins->GetConsumers(); - for (auto const &it : consumers) { - SERVER_INFO("insert (%d:%d)", scaler_id_ins, it); - result->insert(std::pair(scaler_id_ins, it)); - } -} - -void CScalerStrategy::GetRetirableConsumers(std::multimap vresources, CRequest *req, std::multimap* retirables, rms_error_type_e *err_type) -{ - std::multimap consumer_list; - std::multimap filtered_vresources; - std::map> candidates; // > - - 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>(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(it.first, it.second)); -} +/* + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 vresources, CRequest *req) +{ + std::map 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 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> *candidates, std::multimap *result) +{ + CResourceDB *db = CResourceDB::getInstance(); + std::map candidates_by_alloc_t; // allocation time, virtual resource id + + for (auto const &it : *candidates) { + std::multimap candidate = it.second; + for (auto const &itc : candidate) { + CResource *rsc = db->FindResource(itc.first); + candidates_by_alloc_t.insert(std::pair(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 *elected = &ite->second; + + result->insert(elected->begin(), elected->end()); +} + +void CScalerStrategy::SelectConsumersByZoneId(int zone_id, std::map> *candidates, std::multimap *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 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> *candidates) +{ + CResourceDB *db = CResourceDB::getInstance(); + + for (auto const &it : *candidates) { + std::multimap 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 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> *candidates) +{ + CResourceDB *db = CResourceDB::getInstance(); + for (auto const &it : *candidates) { + std::multimap 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> *candidates, std::multimap *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 consumers = rsc_ins->GetConsumers(); + for (auto const &it : consumers) { + SERVER_INFO("insert (%d:%d)", scaler_id_ins, it); + result->insert(std::pair(scaler_id_ins, it)); + } +} + +void CScalerStrategy::GetRetirableConsumers(std::multimap vresources, CRequest *req, std::multimap* retirables, rms_error_type_e *err_type) +{ + std::multimap consumer_list; + std::multimap filtered_vresources; + std::map> candidates; // > + + 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>(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(it.first, it.second)); +} diff --git a/src/manager/strategy/CVideoDecoderStrategy.cpp b/src/manager/strategy/CVideoDecoderStrategy.cpp index c02f504..10e6169 100644 --- a/src/manager/strategy/CVideoDecoderStrategy.cpp +++ b/src/manager/strategy/CVideoDecoderStrategy.cpp @@ -1,590 +1,590 @@ -/* - * 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 vresources, CRequest *req) -{ - std::map 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 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 *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> *candidates, std::multimap *result) -{ - CResourceDB *db = CResourceDB::getInstance(); - - for (auto const &it : *candidates) { - std::multimap 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> candidates, std::multimap *result) -{ - CResourceDB *db = CResourceDB::getInstance(); - std::map candidates_by_score; - - for (auto const &it : candidates) { - std::multimap 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(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 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> *candidates, std::multimap *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> *candidates, std::multimap *result) -{ - CResourceDB *db = CResourceDB::getInstance(); - std::map candidates_by_alloc_t; // allocation time, virtual resource id - - std::map conflicts; //virtual resource id, n conflicts - int n_conflicts = 0; - for (auto const &itn : *candidates) { - std::multimap 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(itn.first, n_conflicts)); - } - } - - bool inserted = false; - - for (auto const &it : *candidates) { - std::multimap 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(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(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 *elected = &ite->second; - - result->insert(elected->begin(), elected->end()); -} - -void CVideoDecoderStrategy::GetRetirableConsumers(std::multimap vresources, CRequest *req, std::multimap* retirables, rms_error_type_e *err_type) -{ - std::multimap consumer_list; - std::multimap filtered_vresources; - std::map> 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>(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(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 bw_consumers = bandwidth->GetConsumers(); - - for (std::map::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 *src, std::map *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(it.first, it.second)); - } -} - -int CVideoDecoderStrategy::getConsumerUsingBW(CRequest *req, unsigned int bw, std::multimap *return_ids) -{ - std::map candidates; - std::map cur_consumers = CBandwidth::GetInstance()->GetConsumers(); //device id, consumer id - - SelectDevicesByMainSub(req, &cur_consumers, &candidates); - - std::multimap 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 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 bw_consumers, std::multimap *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 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(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(device_id, consumer_id)); - - if (pRsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) { - std::map 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 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* reclaimables, CRequest *req, rms_error_type_e *err_type) -{ - std::map rscs; - CResource *rsc = NULL; - CResourceDB *db = CResourceDB::getInstance(); - std::map 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(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 active_ndecs = db->GetActiveNVideoDecoders(); - reclaimables->insert(active_ndecs.begin(), active_ndecs.end()); - } - return RMS_OK; - } - } - - return RMS_ERROR; -} +/* + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 vresources, CRequest *req) +{ + std::map 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 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 *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> *candidates, std::multimap *result) +{ + CResourceDB *db = CResourceDB::getInstance(); + + for (auto const &it : *candidates) { + std::multimap 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> candidates, std::multimap *result) +{ + CResourceDB *db = CResourceDB::getInstance(); + std::map candidates_by_score; + + for (auto const &it : candidates) { + std::multimap 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(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 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> *candidates, std::multimap *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> *candidates, std::multimap *result) +{ + CResourceDB *db = CResourceDB::getInstance(); + std::map candidates_by_alloc_t; // allocation time, virtual resource id + + std::map conflicts; //virtual resource id, n conflicts + int n_conflicts = 0; + for (auto const &itn : *candidates) { + std::multimap 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(itn.first, n_conflicts)); + } + } + + bool inserted = false; + + for (auto const &it : *candidates) { + std::multimap 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(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(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 *elected = &ite->second; + + result->insert(elected->begin(), elected->end()); +} + +void CVideoDecoderStrategy::GetRetirableConsumers(std::multimap vresources, CRequest *req, std::multimap* retirables, rms_error_type_e *err_type) +{ + std::multimap consumer_list; + std::multimap filtered_vresources; + std::map> 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>(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(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 bw_consumers = bandwidth->GetConsumers(); + + for (std::map::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 *src, std::map *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(it.first, it.second)); + } +} + +int CVideoDecoderStrategy::getConsumerUsingBW(CRequest *req, unsigned int bw, std::multimap *return_ids) +{ + std::map candidates; + std::map cur_consumers = CBandwidth::GetInstance()->GetConsumers(); //device id, consumer id + + SelectDevicesByMainSub(req, &cur_consumers, &candidates); + + std::multimap 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 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 bw_consumers, std::multimap *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 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(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(device_id, consumer_id)); + + if (pRsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) { + std::map 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 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* reclaimables, CRequest *req, rms_error_type_e *err_type) +{ + std::map rscs; + CResource *rsc = NULL; + CResourceDB *db = CResourceDB::getInstance(); + std::map 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(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 active_ndecs = db->GetActiveNVideoDecoders(); + reclaimables->insert(active_ndecs.begin(), active_ndecs.end()); + } + return RMS_OK; + } + } + + return RMS_ERROR; +} diff --git a/src/manager/strategy/CVideoEncoderExclusiveStrategy.cpp b/src/manager/strategy/CVideoEncoderExclusiveStrategy.cpp index 3e06691..b39ac82 100644 --- a/src/manager/strategy/CVideoEncoderExclusiveStrategy.cpp +++ b/src/manager/strategy/CVideoEncoderExclusiveStrategy.cpp @@ -1,180 +1,180 @@ -/* - * 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 vresources, CRequest *req) -{ - std::map 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 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 *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 vresources, CRequest *req, std::multimap* retirables, rms_error_type_e *err_type) -{ - std::multimap consumer_list; - std::multimap 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(it.first, it.second)); - } -} +/* + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 vresources, CRequest *req) +{ + std::map 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 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 *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 vresources, CRequest *req, std::multimap* retirables, rms_error_type_e *err_type) +{ + std::multimap consumer_list; + std::multimap 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(it.first, it.second)); + } +} -- 2.34.1