--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6...2.29.2)
+PROJECT(rscmgr-service CXX)
+
+SET(PKG_MODULES
+ vconf
+ dlog
+ glib-2.0
+ gio-unix-2.0
+ capi-system-info
+ resource-information
+ capi-system-info
+ libtzplatform-config
+ ttrace
+ aul
+ wayland-client
+)
+SET(EXTERN_DEBUG_MODULES
+ syspopup
+ syspopup-caller
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED ${PKG_MODULES})
+pkg_check_modules(extern_debug_pkgs REQUIRED ${EXTERN_DEBUG_MODULES})
+
+
+IF(NOT DEFINED PACKAGE_NAME)
+ SET(PACKAGE_NAME ${PROJECT_NAME})
+ENDIF(NOT DEFINED PACKAGE_NAME)
+
+ADD_DEFINITIONS(-DLIBDIR="${LIBDIR}")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wformat -Wl,--as-needed -Wl,--rpath=${LIBDIR} -pie")
+
+SET(RSCMGR_SRCS
+ src/rms_service.cpp
+ src/manager/CConsumer.cpp
+ src/manager/CDebugUtils.cpp
+ src/manager/CResource.cpp
+ src/manager/CResourceCategory.cpp
+ src/manager/CResourceDB.cpp
+ src/manager/CResourceState.cpp
+ src/manager/CResourceManager.cpp
+ src/manager/CVirtualResource.cpp
+ src/manager/CConsumerContainer.cpp
+ src/manager/CPriority.cpp
+ src/manager/CCache.cpp
+ src/manager/CVideoController.cpp
+ src/manager/CLockController.cpp
+ src/manager/dependence/CDependencyController.cpp
+ src/manager/dependence/CMemCluster.cpp
+ src/manager/dependence/CAudioCodec.cpp
+ src/manager/dependence/CAudioCodecCollection.cpp
+ src/manager/dependence/CBandwidth.cpp
+ src/manager/dependence/CMixingMode.cpp
+ src/manager/strategy/CAllocateStrategyProvider.cpp
+ src/manager/strategy/CAllocateStrategy.cpp
+ src/manager/strategy/CNormalStrategy.cpp
+ src/manager/strategy/CVideoDecoderStrategy.cpp
+ src/manager/strategy/CNDecodingVideoDecoderStrategy.cpp
+ src/manager/strategy/CAudioDecoderStrategy.cpp
+ src/manager/strategy/CAllocateModeStrategyProvider.cpp
+ src/manager/strategy/CNormalModeStrategy.cpp
+ src/manager/strategy/CPreferenceModeStrategy.cpp
+ src/manager/strategy/CInvalidModeStrategy.cpp
+ src/manager/strategy/CMixingStrategy.cpp
+ src/manager/strategy/CExclusiveStrategy.cpp
+ src/manager/strategy/CScalerStrategy.cpp
+ src/manager/strategy/CVideoEncoderExclusiveStrategy.cpp
+ src/CMessage.cpp
+ src/CDbusHandler.cpp
+ src/CHandleManager.cpp
+ src/CHandle.cpp
+ src/CCallback.cpp
+ src/CResourceService.cpp
+ src/CMessageHandler.cpp
+ src/CQueryHandler.cpp
+ src/CAsyncQueue.cpp
+ src/CMessageQueue.cpp
+ src/CRequest.cpp
+ src/CRequester.cpp
+ src/CSysInfo.cpp
+)
+
+include_directories(${pkgs_INCLUDE_DIRS})
+link_directories(${pkgs_LIBRARY_DIRS})
+
+include_directories(/usr/include)
+include_directories(/usr/include/dlog)
+include_directories(/usr/include/aul)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include_internal)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include_internal/manager)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include_internal/manager/dependence)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include_internal/manager/strategy)
+
+FOREACH (flag ${RSCMNG_SERVER_DEPENDENCY_PKGS_CXXFLAGS})
+ SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${extern_debug_pkgs_CXXFLAGS})
+ SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -O2 -g2 -fPIE -fstack-protector-strong -Wl,-z,relro -D_FORTIFY_SOURCE=2")
+
+MESSAGE(${CMAKE_CXX_FLAGS})
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${RSCMGR_SRCS})
+ADD_EXECUTABLE(gen_rm_msgq src/gen_rm_msgq.cpp)
+
+target_link_libraries(${PROJECT_NAME} ${pkgs_LIBRARIES} "-ldl")
+target_link_libraries(gen_rm_msgq ${pkgs_LIBRARIES})
+
+#install
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR})
+INSTALL(TARGETS gen_rm_msgq DESTINATION ${BINDIR})
+
--- /dev/null
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+ Apache License\r
+ Version 2.0, January 2004\r
+ http://www.apache.org/licenses/\r
+\r
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+ 1. Definitions.\r
+\r
+ "License" shall mean the terms and conditions for use, reproduction,\r
+ and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+ "Licensor" shall mean the copyright owner or entity authorized by\r
+ the copyright owner that is granting the License.\r
+\r
+ "Legal Entity" shall mean the union of the acting entity and all\r
+ other entities that control, are controlled by, or are under common\r
+ control with that entity. For the purposes of this definition,\r
+ "control" means (i) the power, direct or indirect, to cause the\r
+ direction or management of such entity, whether by contract or\r
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+ outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+ "You" (or "Your") shall mean an individual or Legal Entity\r
+ exercising permissions granted by this License.\r
+\r
+ "Source" form shall mean the preferred form for making modifications,\r
+ including but not limited to software source code, documentation\r
+ source, and configuration files.\r
+\r
+ "Object" form shall mean any form resulting from mechanical\r
+ transformation or translation of a Source form, including but\r
+ not limited to compiled object code, generated documentation,\r
+ and conversions to other media types.\r
+\r
+ "Work" shall mean the work of authorship, whether in Source or\r
+ Object form, made available under the License, as indicated by a\r
+ copyright notice that is included in or attached to the work\r
+ (an example is provided in the Appendix below).\r
+\r
+ "Derivative Works" shall mean any work, whether in Source or Object\r
+ form, that is based on (or derived from) the Work and for which the\r
+ editorial revisions, annotations, elaborations, or other modifications\r
+ represent, as a whole, an original work of authorship. For the purposes\r
+ of this License, Derivative Works shall not include works that remain\r
+ separable from, or merely link (or bind by name) to the interfaces of,\r
+ the Work and Derivative Works thereof.\r
+\r
+ "Contribution" shall mean any work of authorship, including\r
+ the original version of the Work and any modifications or additions\r
+ to that Work or Derivative Works thereof, that is intentionally\r
+ submitted to Licensor for inclusion in the Work by the copyright owner\r
+ or by an individual or Legal Entity authorized to submit on behalf of\r
+ the copyright owner. For the purposes of this definition, "submitted"\r
+ means any form of electronic, verbal, or written communication sent\r
+ to the Licensor or its representatives, including but not limited to\r
+ communication on electronic mailing lists, source code control systems,\r
+ and issue tracking systems that are managed by, or on behalf of, the\r
+ Licensor for the purpose of discussing and improving the Work, but\r
+ excluding communication that is conspicuously marked or otherwise\r
+ designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+ "Contributor" shall mean Licensor and any individual or Legal Entity\r
+ on behalf of whom a Contribution has been received by Licensor and\r
+ subsequently incorporated within the Work.\r
+\r
+ 2. Grant of Copyright License. Subject to the terms and conditions of\r
+ this License, each Contributor hereby grants to You a perpetual,\r
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+ copyright license to reproduce, prepare Derivative Works of,\r
+ publicly display, publicly perform, sublicense, and distribute the\r
+ Work and such Derivative Works in Source or Object form.\r
+\r
+ 3. Grant of Patent License. Subject to the terms and conditions of\r
+ this License, each Contributor hereby grants to You a perpetual,\r
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+ (except as stated in this section) patent license to make, have made,\r
+ use, offer to sell, sell, import, and otherwise transfer the Work,\r
+ where such license applies only to those patent claims licensable\r
+ by such Contributor that are necessarily infringed by their\r
+ Contribution(s) alone or by combination of their Contribution(s)\r
+ with the Work to which such Contribution(s) was submitted. If You\r
+ institute patent litigation against any entity (including a\r
+ cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+ or a Contribution incorporated within the Work constitutes direct\r
+ or contributory patent infringement, then any patent licenses\r
+ granted to You under this License for that Work shall terminate\r
+ as of the date such litigation is filed.\r
+\r
+ 4. Redistribution. You may reproduce and distribute copies of the\r
+ Work or Derivative Works thereof in any medium, with or without\r
+ modifications, and in Source or Object form, provided that You\r
+ meet the following conditions:\r
+\r
+ (a) You must give any other recipients of the Work or\r
+ Derivative Works a copy of this License; and\r
+\r
+ (b) You must cause any modified files to carry prominent notices\r
+ stating that You changed the files; and\r
+\r
+ (c) You must retain, in the Source form of any Derivative Works\r
+ that You distribute, all copyright, patent, trademark, and\r
+ attribution notices from the Source form of the Work,\r
+ excluding those notices that do not pertain to any part of\r
+ the Derivative Works; and\r
+\r
+ (d) If the Work includes a "NOTICE" text file as part of its\r
+ distribution, then any Derivative Works that You distribute must\r
+ include a readable copy of the attribution notices contained\r
+ within such NOTICE file, excluding those notices that do not\r
+ pertain to any part of the Derivative Works, in at least one\r
+ of the following places: within a NOTICE text file distributed\r
+ as part of the Derivative Works; within the Source form or\r
+ documentation, if provided along with the Derivative Works; or,\r
+ within a display generated by the Derivative Works, if and\r
+ wherever such third-party notices normally appear. The contents\r
+ of the NOTICE file are for informational purposes only and\r
+ do not modify the License. You may add Your own attribution\r
+ notices within Derivative Works that You distribute, alongside\r
+ or as an addendum to the NOTICE text from the Work, provided\r
+ that such additional attribution notices cannot be construed\r
+ as modifying the License.\r
+\r
+ You may add Your own copyright statement to Your modifications and\r
+ may provide additional or different license terms and conditions\r
+ for use, reproduction, or distribution of Your modifications, or\r
+ for any such Derivative Works as a whole, provided Your use,\r
+ reproduction, and distribution of the Work otherwise complies with\r
+ the conditions stated in this License.\r
+\r
+ 5. Submission of Contributions. Unless You explicitly state otherwise,\r
+ any Contribution intentionally submitted for inclusion in the Work\r
+ by You to the Licensor shall be under the terms and conditions of\r
+ this License, without any additional terms or conditions.\r
+ Notwithstanding the above, nothing herein shall supersede or modify\r
+ the terms of any separate license agreement you may have executed\r
+ with Licensor regarding such Contributions.\r
+\r
+ 6. Trademarks. This License does not grant permission to use the trade\r
+ names, trademarks, service marks, or product names of the Licensor,\r
+ except as required for reasonable and customary use in describing the\r
+ origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+ 7. Disclaimer of Warranty. Unless required by applicable law or\r
+ agreed to in writing, Licensor provides the Work (and each\r
+ Contributor provides its Contributions) on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+ implied, including, without limitation, any warranties or conditions\r
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+ PARTICULAR PURPOSE. You are solely responsible for determining the\r
+ appropriateness of using or redistributing the Work and assume any\r
+ risks associated with Your exercise of permissions under this License.\r
+\r
+ 8. Limitation of Liability. In no event and under no legal theory,\r
+ whether in tort (including negligence), contract, or otherwise,\r
+ unless required by applicable law (such as deliberate and grossly\r
+ negligent acts) or agreed to in writing, shall any Contributor be\r
+ liable to You for damages, including any direct, indirect, special,\r
+ incidental, or consequential damages of any character arising as a\r
+ result of this License or out of the use or inability to use the\r
+ Work (including but not limited to damages for loss of goodwill,\r
+ work stoppage, computer failure or malfunction, or any and all\r
+ other commercial damages or losses), even if such Contributor\r
+ has been advised of the possibility of such damages.\r
+\r
+ 9. Accepting Warranty or Additional Liability. While redistributing\r
+ the Work or Derivative Works thereof, You may choose to offer,\r
+ and charge a fee for, acceptance of support, warranty, indemnity,\r
+ or other liability obligations and/or rights consistent with this\r
+ License. However, in accepting such obligations, You may act only\r
+ on Your own behalf and on Your sole responsibility, not on behalf\r
+ of any other Contributor, and only if You agree to indemnify,\r
+ defend, and hold each Contributor harmless for any liability\r
+ incurred by, or claims asserted against, such Contributor by reason\r
+ of your accepting any such warranty or additional liability.\r
+\r
+ END OF TERMS AND CONDITIONS\r
+\r
+ APPENDIX: How to apply the Apache License to your work.\r
+\r
+ To apply the Apache License to your work, attach the following\r
+ boilerplate notice, with the fields enclosed by brackets "[]"\r
+ replaced with your own identifying information. (Don't include\r
+ the brackets!) The text should be enclosed in the appropriate\r
+ comment syntax for the file format. We also recommend that a\r
+ file or class name and description of purpose be included on the\r
+ same "printed page" as the copyright notice for easier\r
+ identification within third-party archives.\r
+\r
+ Copyright [yyyy] [name of copyright owner]\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __C_ASYNC_QUEUE_H__\r
+#define __C_ASYNC_QUEUE_H__\r
+\r
+#include <glib.h>\r
+\r
+typedef void (*destoryNotify)(void *data);\r
+\r
+class CAsyncQueue{\r
+public:\r
+ CAsyncQueue();\r
+ CAsyncQueue(destoryNotify destory_cb);\r
+ ~CAsyncQueue();\r
+\r
+ void push(void *data);\r
+ void push(CAsyncQueue *src_queue);\r
+ void push_front(void *data);\r
+ void push_front(CAsyncQueue *src_queue);\r
+\r
+ void *pop(void);\r
+ void *pop(unsigned int timeout_ms);\r
+\r
+ int length(void);\r
+\r
+private:\r
+ GAsyncQueue *queue;\r
+};\r
+\r
+#endif // __C_ASYNC_QUEUE_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RMS_CCALLBACK_H__\r
+#define __RMS_CCALLBACK_H__\r
+\r
+class CCallback\r
+{\r
+public:\r
+ CCallback() {}\r
+ ~CCallback() {}\r
+\r
+ static void InitCallback(void);\r
+ static int SendCallbackMessage(int cid, int pid, void *callback_data, int size, int *err);\r
+ static int RemoveFIFOServerToClient(int pid, int cid);\r
+ static int ConvertCallbackType(int rm_return_type);\r
+ static unsigned int GetTimeout(void);\r
+};\r
+\r
+#endif //__RMS_CCALLBACK_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CDBUS_HANDLER_H__\r
+#define __CDBUS_HANDLER_H__\r
+\r
+#include <glib.h>\r
+#include <gio/gio.h>\r
+\r
+#include <CAsyncQueue.h>\r
+\r
+class CDbusHandler\r
+{\r
+public:\r
+ CDbusHandler(CAsyncQueue *queue);\r
+ ~CDbusHandler() = default;\r
+\r
+ static void OnMethodCall(GDBusConnection *conn, const gchar *sender, const gchar *obj_path, const gchar *ifname, const gchar *method_name, GVariant *params, GDBusMethodInvocation *invoc, gpointer data);\r
+ static void OnBusAcquired(GDBusConnection *conn, const gchar *bus_name, gpointer data);\r
+ static void OnNameLost(GDBusConnection *conn, const gchar *bus_name, gpointer data);\r
+\r
+private:\r
+\r
+ static const std::string m_methods;\r
+ static const GDBusInterfaceVTable m_vtable;\r
+\r
+ GDBusConnection *m_conn;\r
+ unsigned int m_reg_id;\r
+ unsigned int m_own_id;\r
+\r
+ CAsyncQueue *m_async_queue;\r
+\r
+ bool MakeDbusConnection(void);\r
+ void RegisterObjects(void);\r
+ void GenerateReadyEvent(void);\r
+};\r
+\r
+#endif // __CDBUS_HANDLER_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RMS_CHANDLE_H__\r
+#define __RMS_CHANDLE_H__\r
+#include <rms_type.h>\r
+class CHandle\r
+{\r
+public:\r
+ CHandle() {}\r
+ CHandle(int handle, int is_used, int pid);\r
+ ~CHandle() {}\r
+\r
+ int handle;\r
+ int is_used;\r
+ int pid;\r
+ int main_priority;\r
+ int sub_priority;\r
+ int app_pid;\r
+ char *app_id;\r
+ char process_name[RMS_NAME_BUF_SIZE];\r
+};\r
+\r
+#endif //__RMS_CHANDLE_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RMS_CHANDLE_MANAGER_H__\r
+#define __RMS_CHANDLE_MANAGER_H__\r
+\r
+#include <map>\r
+#include <CResourceManager.h>\r
+#include <CHandle.h>\r
+\r
+class CHandleManager\r
+{\r
+public:\r
+ CHandleManager(CResourceManager *rsc_mgr);\r
+ ~CHandleManager() {}\r
+\r
+ int GetNewHandle(int pid, int main_priority, int sub_priority, int app_pid, char *app_id);\r
+ int RemoveHandle(int handle, int pid);\r
+ int SetPriority(int handle, int main_priority, int sub_priority);\r
+ int GetPriority(int handle, int *main_priority, int *sub_priority);\r
+ int SetAppID(int handle, char *app_id);\r
+ char *GetAppID(int handle);\r
+ void ReclaimAllInvalidCustomer(int request_pid);\r
+\r
+private:\r
+ int m_RemoveHandle(int handle, int pid);\r
+ int m_IsValidHandle(int handle);\r
+ int m_ReclaimHandle(void);\r
+ int m_AddNewHandle(int handle, int pid, int main_priority, int sub_priority, int app_pid, char *app_id);\r
+ int m_PrintHandleInfo(int handle, int pid);\r
+ void m_PrintHandleList(void);\r
+ CHandle *findHandle(int id);\r
+\r
+ CResourceManager *m_rsc_mgr;\r
+ int m_next_handle;\r
+ std::map<int, CHandle*> m_handles;\r
+};\r
+\r
+#endif //__RMS_CHANDLE_MANAGER_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CMESSAGE_H__\r
+#define __CMESSAGE_H__\r
+\r
+#include <iostream>\r
+#include <gio/gio.h>\r
+#include <rms_type.h>\r
+\r
+typedef enum {\r
+ MSG_SENDER_MSGQ,\r
+ MSG_SENDER_DBUS,\r
+ MSG_SENDER_INTERNAL\r
+} msg_sender_e;\r
+\r
+class CMessage\r
+{\r
+public:\r
+ CMessage(std::string name);\r
+ CMessage(rms_msg_request *msgq_req);\r
+ CMessage(GDBusMethodInvocation *invoc);\r
+ ~CMessage();\r
+\r
+ int GetReqType(void);\r
+ std::string GetName(void) { return m_name; }\r
+ msg_sender_e GetSender(void) { return m_sender; }\r
+ rms_msg_request *GetRequest(void) { return m_msgq_req; }\r
+ GDBusMethodInvocation *GetMethodInvocation(void) { return m_invoc; }\r
+\r
+ bool IsUnlockMsg(void);\r
+ bool IsMsgFor(ResourceType rsc_type);\r
+ void PrintInfo(void);\r
+\r
+private:\r
+ rms_msg_request *m_msgq_req;\r
+ GDBusMethodInvocation *m_invoc;\r
+ msg_sender_e m_sender;\r
+ std::string m_name;\r
+\r
+ void PrintDbus(void);\r
+ void PrintInternal(void);\r
+ void PrintMsgQ(void);\r
+\r
+ bool IsMsgForScaler(void);\r
+ bool IsMsgForScalerDbus(void);\r
+ bool IsMsgForScalerMsgQ(void);\r
+};\r
+\r
+#endif //__CMESSAGE_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RMS_CMESSAGE_HANDLER_H__\r
+#define __RMS_CMESSAGE_HANDLER_H__\r
+\r
+#include <rms_type.h>\r
+#include <gio/gio.h>\r
+#include <glib.h>\r
+#include <map>\r
+\r
+#include <CMessage.h>\r
+#include <CQueryHandler.h>\r
+#include <CResourceManager.h>\r
+#include <CHandleManager.h>\r
+#include <CDbusHandler.h>\r
+#include <CLockController.h>\r
+#include <CMessageQueue.h>\r
+#include <CAsyncQueue.h>\r
+\r
+class CMessageHandler\r
+{\r
+public:\r
+ typedef GVariant *(CMessageHandler::*MsgHandler)(GVariant *params);\r
+\r
+ CMessageHandler(CResourceManager *rsc_mgr);\r
+ ~CMessageHandler(void);\r
+\r
+ int Run(void);\r
+ void NotifyWatchdog(void);\r
+\r
+private:\r
+ void InitDbusHandlers(void);\r
+ void InitInternalMsgHandlers(void);\r
+\r
+ static gpointer msgThread(gpointer data);\r
+ static gpointer msgQThread(gpointer data);\r
+\r
+ int ProcessMessage(void);\r
+ int ProcessCallbackMessage(rms_consumer_tobe_returned_s *consumer_info, int requester_cid);\r
+ void ProcessMessage(CAsyncQueue *queue, CMessage *msg, int cid_requester, int cid_releaser);\r
+ void ProcessMsgQMessage(CMessage *msg);\r
+ void ProcessDbusMessage(CMessage *msg);\r
+ void ProcessInternalMessage(CMessage *msg);\r
+\r
+ void EmptyPendingQueue(void);\r
+ void InsertPendingQueue(CMessage *msg);\r
+\r
+ int SendResponse(rms_msg_response *response);\r
+ int PushMessage(CAsyncQueue *queue, CMessage *msg);\r
+\r
+ bool IsRegisteredHandle(int handle);\r
+ bool IsValidProcess(int pid);\r
+ bool IsValidRequest(int req_type);\r
+ bool IsAllResourcesReclaimed(rms_consumer_tobe_returned_s *consumer_info);\r
+\r
+ int ReleaseInvalidProcessResources(int pid, int handle);\r
+ int ReclaimResources(int reason, int requester_cid, int requester_zone_id, consumer_reclaim_s *conflict_info, bool *need_response);\r
+\r
+ void SetRequesterInfo(rms_msg_request *request);\r
+\r
+ void m_ConstructResponse(rms_msg_response *response, int data_type, rms_response_type_e msg_type, int handle, int pid);\r
+ void m_ConstructRequestedDevice(rms_msg_request *request, rms_requests_device_s *requested_resource);\r
+ void m_FreeAllocatedDevice(rms_return_device_s *allocated_device);\r
+ int *m_SerializeCallbackData(const rms_consumer_tobe_returned_s *consumer_info, int reason, int *data_size);\r
+ void m_Free(consumer_reclaim_s *consumer_info);\r
+\r
+ void m_RegisterConsumer(rms_msg_request *request, rms_msg_response *response);\r
+ void m_UnregisterConsumer(rms_msg_request *request, rms_msg_response *response);\r
+ void m_AllocateResources(rms_msg_request *request, rms_msg_response *response);\r
+ void m_ReleaseResources(rms_msg_request *request, rms_msg_response *response);\r
+ void m_Query(rms_msg_request *request, rms_msg_response *response);\r
+ void m_SetConsumerPriority(rms_msg_request *request, rms_msg_response *response);\r
+ void m_SetAppID(rms_msg_request *request, rms_msg_response *response);\r
+\r
+ GVariant *RegisterResource(GVariant *params);\r
+ GVariant *GetResourceState(GVariant *params);\r
+ GVariant *GetResourceList(GVariant *params);\r
+ GVariant *GetResourceCollectionState(GVariant *params);\r
+ GVariant *FindDeviceId(GVariant *params);\r
+ GVariant *SwapResources(GVariant *params);\r
+ GVariant *GetScalerState(GVariant *params);\r
+ GVariant *GetAppId(GVariant *params);\r
+ GVariant *GetActiveAudioOut(GVariant *params);\r
+ GVariant *GetScalerHWID(GVariant *params);\r
+ GVariant *RestoreResources(GVariant *params);\r
+ GVariant *NotifyResourcePolicy(GVariant *params);\r
+ GVariant *NotifyAppZoneInfo(GVariant *params);\r
+ GVariant *NotifyWatchdog(GVariant *params);\r
+\r
+ void NotifyConflict(consumer_reclaim_s *conflict_info, int zone_id);\r
+\r
+ unsigned long m_req_timeout = 5;\r
+\r
+ CMessageQueue *msgq_rx;\r
+ CMessageQueue *msgq_tx;\r
+ CAsyncQueue *async_queue;\r
+ CAsyncQueue *async_pending_queue;\r
+ CLockController *m_lock_ctr;\r
+ CResourceManager *m_rsc_mgr;\r
+ CHandleManager *m_handle_mgr;\r
+ CQueryHandler *m_query_h;\r
+ CDbusHandler *m_dbus_h;\r
+\r
+ typedef void (CMessageHandler::*msg_handler)(rms_msg_request *request, rms_msg_response *response);\r
+ static msg_handler handlers[RMS_REQUEST_MAX];\r
+ std::map<std::string, MsgHandler> m_dbus_handlers;\r
+ std::map<std::string, MsgHandler> m_internal_msg_handlers;\r
+};\r
+\r
+#endif //__RMS_CMESSAGE_HANDLER_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CMESSAGE_QUEUE_H__\r
+#define __CMESSAGE_QUEUE_H__\r
+\r
+#include <rms_type.h>\r
+#include <CAsyncQueue.h>\r
+\r
+typedef enum {\r
+ MSG_QUEUE_RX = 0,\r
+ MSG_QUEUE_TX\r
+} msgq_type_e;\r
+\r
+class CMessageQueue{\r
+public:\r
+ CMessageQueue(msgq_type_e type);\r
+ ~CMessageQueue();\r
+\r
+ int receive(rms_msg_request *req, int msg_type);\r
+ int send(rms_msg_response *response);\r
+\r
+private:\r
+ int init(void);\r
+ int recover(void);\r
+ static int getKey(msgq_type_e type);\r
+\r
+ msgq_type_e msgq_type;\r
+ int msgq_id;\r
+\r
+ static const long msgq_size = 131072; // 128KB\r
+ static const int key_rx = 8211;\r
+ static const int key_tx = 8212;\r
+};\r
+\r
+#endif //__CMESSAGE_QUEUE_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CQUERY_HANDLER_H__\r
+#define __CQUERY_HANDLER_H__\r
+\r
+#include <rms_type.h>\r
+#include <CResourceManager.h>\r
+\r
+class CQueryHandler\r
+{\r
+public:\r
+ CQueryHandler(CResourceManager *rsc_mgr);\r
+ ~CQueryHandler();\r
+\r
+ int GetAnswer(rms_msg_request *request, int *answer_out);\r
+private:\r
+ CResourceManager *m_rsc_mgr;\r
+};\r
+\r
+#endif //__CQUERY_HANDLER_H__
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CREQUEST_H__\r
+#define __CREQUEST_H__\r
+\r
+#include "rms_type.h"\r
+\r
+class CRequester;\r
+class CRequest\r
+{\r
+public:\r
+ CRequest(CRequester *requester);\r
+ ~CRequest();\r
+\r
+ CRequester *getRequester(void);\r
+\r
+ void SetCategory(int category_id, int category_option);\r
+ void SetState(int req_state);\r
+\r
+ void SetResult(rms_return_code_e req_result);\r
+ void SetReason(rms_error_type_e reason) { m_reason = reason; }\r
+ void ResetResult(void) { m_result = RMS_ERROR; }\r
+ void SetCandidateDevice(int device_id) { m_candidate_device = device_id; }\r
+ void SetAllocatedDevice(int device_id) { m_allocated_device = device_id; }\r
+ void SetAllocatedVirtualDevice(int virtual_id) { m_virtual_device = virtual_id; }\r
+\r
+ bool IsRequestByDevice(void) { return (m_device_id > 0); }\r
+ bool IsMainDeviceRequest(void);\r
+ bool IsSubDeviceRequest(void);\r
+ bool IsAIDeviceRequest(void);\r
+\r
+ rms_rsc_category_e GetCategory(void);\r
+ int GetDevice(void) { return m_device_id; }\r
+ rms_requests_resource_state_e GetState(void) { return m_state; }\r
+ rms_error_type_e GetReason(void) { return m_reason; }\r
+\r
+ rms_return_code_e GetResult(void);\r
+ int GetCandidateDevice(void) { return m_candidate_device; }\r
+ int GetAllocatedDevice(void) { return m_allocated_device; }\r
+ int GetAllocatedVirtualDevice(void) { return m_virtual_device; }\r
+ rms_mixing_mode_e GetMixingMode(void) { return m_mixing_mode; }\r
+\r
+ int GetMultiviewZoneId(void) { return m_mv_zone_id; }\r
+ void PrintResult(void);\r
+\r
+private:\r
+ rms_rsc_category_e ToVideoDecoderCategory(int category, int category_option, bool force_main, bool force_sub);\r
+ rms_rsc_category_e ToJpegDecoderCategory(int category, int category_option);\r
+ rms_rsc_category_e ToMJpegDecoderCategory(int category, int category_option);\r
+ rms_rsc_category_e ToAudioDecoderCategory(int category, int category_option, bool force_main, bool force_sub);\r
+ rms_rsc_category_e ToScalerCategory(int category, int category_option, bool force_main, bool force_sub);\r
+ rms_rsc_category_e ToAudioOutCategory(int category, int category_option, bool force_main, bool force_sub);\r
+ rms_rsc_category_e ToResourceCategory(int category, int category_option);\r
+ rms_rsc_category_e ToImageDecoderCategory(int category, int category_option);\r
+ rms_mixing_mode_e ToMixingMode(int category, int category_option);\r
+ int ToMultiviewZoneId(int category_option);\r
+ bool IsSupportedCategory(int category_option);\r
+ int UnmaskMainSubOptions(int category_option);\r
+ int UnmaskMixingOptions(int category_option);\r
+ int UnmaskMVZoneInfo(int category_option);\r
+ int UnmaskForceOptions(int category_option);\r
+\r
+ CRequester *m_requester;\r
+\r
+ int m_category_id;\r
+ int m_category_option;\r
+ rms_rsc_category_e m_category;\r
+ rms_requests_resource_state_e m_state;\r
+ rms_mixing_mode_e m_mixing_mode;\r
+ int m_device_id;\r
+\r
+ rms_return_code_e m_result;\r
+ int m_candidate_device;\r
+ int m_allocated_device;\r
+ int m_virtual_device;\r
+ int m_mv_zone_id;\r
+ rms_error_type_e m_reason;\r
+};\r
+\r
+#endif //__CREQUEST_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CREQUESTER_H__\r
+#define __CREQUESTER_H__\r
+\r
+#include <string>\r
+\r
+#include "rms_type.h"\r
+\r
+class CRequester\r
+{\r
+public:\r
+ CRequester();\r
+ CRequester(rms_msg_request *req);\r
+ ~CRequester();\r
+\r
+ int getHandle(void);\r
+ int getPid(void);\r
+ int getMainPriority(void);\r
+ int getSubPriority(void);\r
+ std::string getAppId(void) { return m_app_id; }\r
+ void SetCmdName(int pid);\r
+ std::string GetCmdName(void) { return m_cmd_name; }\r
+\r
+private:\r
+ int m_handle;\r
+ int m_pid;\r
+ int m_main_priority;\r
+ int m_sub_priority;\r
+ std::string m_app_id;\r
+ std::string m_cmd_name;\r
+};\r
+\r
+#endif // __CREQUESTER_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RMS_CRESOURCE_SERVICE_H__\r
+#define __RMS_CRESOURCE_SERVICE_H__\r
+\r
+#include <gio/gio.h>\r
+#include <CMessageHandler.h>\r
+\r
+class CResourceService\r
+{\r
+public:\r
+ CResourceService(void) {}\r
+ ~CResourceService(void) {}\r
+ int Init(GMainLoop *main_loop);\r
+\r
+private:\r
+\r
+ CMessageHandler *m_msg_h;\r
+\r
+ int IsFirstLaunch(void);\r
+ void RequestColdPowerOff(void);\r
+ void CreateWatchDogTimer(void);\r
+ void SetVIPProcess(void);\r
+ static gboolean WatchDogCallback(gpointer data);\r
+ static gboolean InvalidResourceTableMsgCallback(gpointer data);\r
+};\r
+\r
+#endif //__RMS_CRESOURCE_SERVICE_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CSYS_INFO_H__\r
+#define __CSYS_INFO_H__\r
+\r
+class CSysInfo\r
+{\r
+public:\r
+ ~CSysInfo() = default;\r
+\r
+ static CSysInfo *GetInstance(void);\r
+ bool IsAudioMixingSupported(void);\r
+private:\r
+ CSysInfo() = default;\r
+\r
+ static CSysInfo *m_instance;\r
+ bool m_support_audio_mixing;\r
+};\r
+\r
+#endif //__CSYS_INFO_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CCACHE_H__\r
+#define __CCACHE_H__\r
+\r
+#include <map>\r
+\r
+class CCache\r
+{\r
+public:\r
+ static CCache *getInstance(void);\r
+ ~CCache() = default;\r
+\r
+ void Drop(void);\r
+ int GetAppStatus(std::string app_id);\r
+ void SetAppStatus(std::string app_id, int status);\r
+\r
+private:\r
+ CCache() = default;\r
+\r
+ static CCache *m_instance;\r
+ std::map<std::string, int> m_visibility; // app id, app status\r
+};\r
+\r
+#endif //__CCACHE_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RSC_MGR_SERVER_CONSUMER_H__\r
+#define __RSC_MGR_SERVER_CONSUMER_H__\r
+\r
+#include <string>\r
+#include <rms_type.h>\r
+#include <set>\r
+\r
+class CConsumer\r
+{\r
+public:\r
+ CConsumer(IN const rms_consumer_s *consumer);\r
+ virtual ~CConsumer() {}\r
+\r
+ long GetPid(void) { return m_pid; }\r
+ int GetId(void) { return m_consumerID; }\r
+ void SetAppID(IN const char *app_id);\r
+ std::string GetAppID(void) { return m_app_id; }\r
+ std::string GetCmdName(void) { return m_cmd_name; }\r
+\r
+ bool AddResource(IN int device_id);\r
+ int ReleaseResource(IN int device_id);\r
+ bool IsUsingResource(IN int device_id);\r
+ std::set<int> GetResources(void) { return m_resources; }\r
+ int GetResourceNum(void) { return m_resources.size(); }\r
+\r
+ void SetPriority(rms_priority_s priority) { m_priority = priority; }\r
+ rms_error_type_e ComparePriority(CConsumer *requester);\r
+\r
+private:\r
+ rms_priority_s GetPriority(void) { return m_priority; }\r
+ bool ComparePriority(IN rms_priority_s priority1, IN rms_priority_s priority2);\r
+ bool CheckVisibility(IN std::string app_id_requester);\r
+ bool GetAppVisibility(IN std::string app_id, bool requester);\r
+ bool CheckWebAppState(IN std::string app_id_requesting);\r
+ bool IsVisibleStatus(int status);\r
+ bool NeedStatusUpdate(std::string app_id);\r
+ int UpdateAppStatus(std::string app_id);\r
+ void SetCmdName(long pid);\r
+ std::string GetAppId(int pid);\r
+\r
+ std::set<int> m_resources;\r
+\r
+ int m_consumerID;\r
+ rms_priority_s m_priority;\r
+ long m_pid;\r
+ std::string m_app_id;\r
+ std::string m_cmd_name;\r
+};\r
+\r
+\r
+#endif // __RSC_MGR_SERVER_CONSUMER_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CCONSUMER_CONTAINER_H__\r
+#define __CCONSUMER_CONTAINER_H__\r
+\r
+#include <map>\r
+\r
+class CConsumer;\r
+class CConsumerContainer\r
+{\r
+public:\r
+ static CConsumerContainer *getInstance(void);\r
+ ~CConsumerContainer() = default;\r
+\r
+ bool AddConsumer(int consumer_id, CConsumer *consumer);\r
+ void RemoveConsumer(int consumer_id);\r
+ CConsumer *findConsumer(int consumer_id);\r
+ std::map<int, CConsumer*> FindConsumers(std::string app_id);\r
+ std::map<int, CConsumer*> findConsumers(int pid);\r
+\r
+private:\r
+ CConsumerContainer() = default;\r
+\r
+ static CConsumerContainer *m_instance;\r
+ std::map<int, CConsumer*> m_consumers;\r
+};\r
+\r
+#endif // __CCONSUMER_CONTAINER_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RSC_MGR_SERVER_DEBUGUTILS_H__\r
+#define __RSC_MGR_SERVER_DEBUGUTILS_H__\r
+\r
+#include <rms_type.h>\r
+#include <sys/types.h>\r
+#include <assert.h>\r
+\r
+#define RMS_CONSOLE_BUF_SIZE 256\r
+\r
+typedef enum {\r
+ RMS_ALARM_NO_CALLBACK_RESPONSE,\r
+ RMS_ALARM_NO_DEALLOCATION,\r
+} rms_alarm_reason_e;\r
+\r
+const char *rm_convert_state_enum_to_string(rms_resource_internal_state_e state_enum);\r
+const char *rm_convert_requested_state_enum_to_string(rms_requests_resource_state_e state_enum);\r
+const char *rm_convert_category_enum_to_string(rms_rsc_category_e category_enum);\r
+const char *rm_print_allocation_failure_reason(int ret_value);\r
+const char *rm_convert_device_enum_to_string(rms_device_e device_enum);\r
+\r
+int rms_get_cmd_name(pid_t pid, char *name_out, int size);\r
+void rms_print_log_console(char *buf);\r
+\r
+int rm_get_product_type(void);\r
+int rm_is_valid_pid(int pid);\r
+int rms_report_emergency(IN int cid, IN int pid, IN int requester);\r
+\r
+int is_symlink_file(const char *path);\r
+const char *rm_convert_error_type_to_string(rms_error_type_e error_type);\r
+\r
+void rms_display_timeout_error_popup(rms_alarm_reason_e reason, rms_consumer_tobe_returned_s info);\r
+void rms_display_resource_table_error_popup(void);\r
+void rms_print_model_info(void);\r
+\r
+bool process_htable_contains(const char *name);\r
+\r
+#endif //__RSC_MGR_SERVER_DEBUGUTILS_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CLOCK_CONTROLLER_H__\r
+#define __CLOCK_CONTROLLER_H__\r
+\r
+#include <map>\r
+#include <CAsyncQueue.h>\r
+#include <CMessage.h>\r
+\r
+class CLockController\r
+{\r
+public:\r
+ static CLockController *GetInstance(void);\r
+ void SetMsgQ(CAsyncQueue *queue) { m_msg_q = queue; }\r
+\r
+ void Lock(ResourceType rsc_type);\r
+ void Unlock(ResourceType rsc_type);\r
+ unsigned int GetLockCount(void);\r
+ bool IsLocked(CMessage *msg);\r
+\r
+private:\r
+ CLockController() = default;\r
+ ~CLockController() = default;\r
+ void NotifyUnlock(void);\r
+\r
+ static CLockController *m_instance;\r
+ std::map<ResourceType, unsigned int> m_locks;\r
+ CAsyncQueue *m_msg_q;\r
+};\r
+\r
+#endif //__CLOCK_CONTROLLER_H__S\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CPRIORITY_H__\r
+#define __CPRIORITY_H__\r
+\r
+#include <rms_type.h>\r
+\r
+enum {\r
+ LOW_PRIORITY = -1,\r
+ SAME_PRIORITY = 0,\r
+ HIGH_PRIORITY = 1\r
+};\r
+\r
+class CPriority\r
+{\r
+public:;\r
+ ~CPriority();\r
+\r
+ static bool isReclaimableConsumer(int consumer_id, int requester_id, rms_error_type_e *err_type);\r
+ static int compareCurConsumers(int device_id, int consumer_id);\r
+ static int compare(int cur_consumer_id, int consumer_id);\r
+ static int getReclaimableConsumers(int device_id, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type);\r
+ static int getReclaimableConsumersShare(int device_id, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type);\r
+private:\r
+ CPriority();\r
+};\r
+\r
+#endif //__CPRIORITY_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RSC_MGR_SERVER_RESOURCE_H__\r
+#define __RSC_MGR_SERVER_RESOURCE_H__\r
+\r
+#include <vector>\r
+#include <map>\r
+#include <set>\r
+\r
+#include <rms_type.h>\r
+#include <CResourceSubject.h>\r
+\r
+class CResource : public CResourceSubject\r
+{\r
+public:\r
+ CResource(IN const int device_id, IN const rms_rsc_category_e category_type, IN const char *name, IN const char *path, \r
+ IN std::set<unsigned int> mem_cluster, IN int is_main_device, IN const char *audio_codec, IN int sharable_count);\r
+ ~CResource();\r
+\r
+ std::string GetName(void) { return std::string(m_device_name); }\r
+ int GetDeviceID(void) { return m_id; }\r
+ int GetVirtualResourceID(void) { return m_vrsc_id; }\r
+ const char *GetDevicePath(void) { return m_device_path; }\r
+ std::string GetAudioCodec(void) { return m_audio_codec; }\r
+ rms_mixing_mode_e GetMixingMode(void) { return m_mixing_mode; }\r
+ rms_rsc_category_e GetCategoryType(void) { return m_category_type; }\r
+ int GetCurCategory(void) { return m_cur_category; }\r
+ int getSharableCount(void) { return (m_sharable_count - m_shared_count - m_reserved_count); }\r
+ int GetCategoryClass(void) { return m_category_class; }\r
+\r
+ bool IsFreeState(void) { return m_state == RMS_INTERNAL_STATE_FREE; };\r
+ bool IsAllocatableState(IN rms_requests_resource_state_e requested_state);\r
+ bool IsSharableState(void) { return (m_state == RMS_INTERNAL_STATE_FREE || m_state == RMS_INTERNAL_STATE_SHARABLE); }\r
+ bool IsReserved(void) { return m_is_reserved; }\r
+ bool IsSharableDevice(void) { return (m_sharable_count >= 2); }\r
+ bool IsMainDevice(void) { return m_is_main_device; }\r
+ bool IsAudioDevice(void);\r
+ bool IsVideoDecoder(void);\r
+ bool IsScaler(void) { return m_is_scaler; }\r
+ bool IsJpegDecoder(void);\r
+\r
+ void AddConsumer(IN int consumer_id, IN rms_requests_resource_state_e state);\r
+ void ResetConsumer(std::set<int> new_consumers);\r
+ int RemoveConsumer(IN int consumer_id, IN bool force);\r
+ std::set<int> GetConsumers(void) { return m_consumer_ids; }\r
+ int GetFirstConsumer(void);\r
+\r
+ int Reserve(IN int consumer_id, rms_requests_resource_state_e state);\r
+ void CancelReservation(rms_requests_resource_state_e state);\r
+\r
+ void SetDefaultBW(unsigned int bw);\r
+ unsigned int GetBW(void) { return m_occupied_bw; }\r
+ int GetDefaultBW(void) { return m_default_bw; }\r
+ void ResetBW(void) { m_occupied_bw = m_default_bw; }\r
+ void SetAllocatedTime(void);\r
+ unsigned long GetAllocatedTime(void) { return m_allocated_time; }\r
+\r
+ void SetVirtualDeviceId(int id) { m_virtual_id = id; }\r
+ int GetVirtualDeviceId(void);\r
+ void SetDedicatedVirtualDeviceId(int id) { m_dedicated_virtual_id = id; }\r
+ int GetDedicatedVirtualDeviceId(void) { return m_dedicated_virtual_id; }\r
+\r
+ std::set<unsigned int> GetMemClusters(void) { return m_mem_clusters; }\r
+ void UpdateProperties(std::set<unsigned int> mem_clusters, int bw, int category, int category_class, int vrsc_id);\r
+ void UpdateAudioCodec(std::string codec_name);\r
+ void updateMixingMode(rms_mixing_mode_e mode) { m_mixing_mode = mode; }\r
+\r
+ void RegisterObserver(CResourceObserver *observer);\r
+ void UnregisterObserver(CResourceObserver *observer);\r
+\r
+ bool Allocate(const int consumer_id, rms_requests_resource_state_e state, int mv_zone_id);\r
+ int GetState(void) { return (int) m_state; }\r
+ int GetZoneId(void) { return m_mv_zone_id; }\r
+ void SetZoneId(int zone_id);\r
+\r
+ void ChangeState(rms_resource_internal_state_e next_state);\r
+\r
+private:\r
+ void m_SetSubScalerFlag(int next_state);\r
+ bool IsRegisteredConsumer(int consumer_id);\r
+ int IncreaseRefCount(int consumer_id);\r
+ int DecreaseRefCount(int consumer_id);\r
+ void NotifyObservers(resource_update_type_e type, int consumer_id);\r
+ bool ChangeStateByAllocation(IN rms_requests_resource_state_e state, const int consumer_id, int mv_zone_id);\r
+ bool ChangeStateByRelease(int consumer_id);\r
+ bool IsScaler(rms_rsc_category_e category);\r
+\r
+ int ReserveExclusive(int consumer_id);\r
+ int ReserveShared(int consumer_id);\r
+\r
+ std::map<int, int> m_consumers; // consumer id, cnt\r
+ std::set<int> m_shared_consumers;\r
+ std::set<int> m_consumer_ids;\r
+\r
+ int m_id;\r
+ int m_vrsc_id;\r
+ int m_virtual_id;\r
+ int m_dedicated_virtual_id;\r
+ rms_resource_internal_state_e m_state;\r
+ rms_rsc_category_e m_category_type;\r
+ const char *m_device_name;\r
+ const char *m_device_path;\r
+ int m_category_class;\r
+ int m_cur_category;\r
+\r
+ unsigned int m_occupied_bw;\r
+ unsigned int m_default_bw;\r
+ int m_is_main_device;\r
+ int m_sharable_count;\r
+\r
+ bool m_is_reserved;\r
+ bool m_is_scaler;\r
+ int m_reserved_consumer_id;\r
+ unsigned long m_allocated_time;\r
+\r
+ int m_shared_count;\r
+ int m_reserved_count;\r
+ int m_mv_zone_id;\r
+\r
+ std::string m_audio_codec;\r
+ std::vector<CResourceObserver*> m_observers;\r
+ std::set<unsigned int> m_mem_clusters;\r
+ rms_mixing_mode_e m_mixing_mode;\r
+};\r
+\r
+#endif // __RSC_MGR_SERVER_RESOURCE_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RSC_MGR_SERVER_CATEGORY_H__\r
+#define __RSC_MGR_SERVER_CATEGORY_H__\r
+\r
+#include <rms_type.h>\r
+#include <CResource.h>\r
+#include <map>\r
+#include <vector>\r
+\r
+#include <CRequest.h>\r
+\r
+class CConsumer;\r
+class CVirtualResource;\r
+class CRequest;\r
+class CAllocateStrategy;\r
+class CResourceCategory\r
+{\r
+public:\r
+ CResourceCategory(rms_rsc_category_e resource_category_id, int category_class);\r
+ virtual ~CResourceCategory() {}\r
+\r
+ rms_rsc_category_e GetCategoryID(void) { return m_categoryID; }\r
+ void AddVirtualResource(IN int device_id, IN CVirtualResource *vresource);\r
+\r
+ CResource *ReserveCandidate(CRequest *req, bool apply_promotion);\r
+ void GetRetirableConsumers(CRequest *req, std::multimap<int, int>* return_ids_in_category, rms_error_type_e *err_type);\r
+ bool hasFreeStateResource(void);\r
+ bool IsAvailableToUse(rms_requests_resource_state_e request_state);\r
+ void GetResources(std::map<int, CResource*> *resource_map);\r
+ CResource *FindMainResource(void);\r
+private:\r
+ std::map<int, CVirtualResource *> m_device_id_to_vresource_map;\r
+\r
+ rms_rsc_category_e m_categoryID;\r
+ CAllocateStrategy *m_alloc_strategy;\r
+\r
+ void MakeResourceMapSortedByAllocTime(std::multimap<unsigned long, CVirtualResource *> *time_resource_map);\r
+};\r
+\r
+#endif // __RSC_MGR_SERVER_CATEGORY_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RSC_MGR_SERVER_DB_H__\r
+#define __RSC_MGR_SERVER_DB_H__\r
+\r
+#include <map>\r
+#include <glib.h>\r
+#include <rms_type.h>\r
+#include <CResourceObserver.h>\r
+#include <CResourceCategory.h>\r
+\r
+class CResourceCategory;\r
+class CVirtualResource;\r
+class CResource;\r
+class CResourceDB : public CResourceObserver\r
+{\r
+public:\r
+ CResourceDB(void) = default;\r
+ virtual ~CResourceDB(void) {}\r
+ static CResourceDB *getInstance(void);\r
+\r
+ void AddVirtualResource(IN CVirtualResource *vrsc, IN rms_rsc_category_e resource_category_id, IN const char *name,\r
+ IN const char *path, IN std::set<unsigned int> mem_cluster_info,\r
+ IN unsigned int device_id_unique, IN int is_main_device, IN const char *audio_codec,\r
+ IN int sharable_count, IN int mixing_count, IN CResourceObserver *observer);\r
+\r
+ void AddResourceCategory(IN rms_rsc_category_e category_id, IN CResourceCategory *resource_category);\r
+\r
+ CResourceCategory *FindResourceCategory(IN rms_rsc_category_e category_id);\r
+ CResource *FindResource(IN const int device_id);\r
+ CVirtualResource *FindVirtualResource(const int vid);\r
+ int FindRealDeviceId(int virtual_id);\r
+ void FindMainResources(IN std::map<int, CResource*> *resource_map);\r
+ void FindActiveVideoDecoders(IN std::map<int, CResource*> *resource_map);\r
+\r
+ void SetMaxVideoDecoders(int n_decs) { m_max_vdecs = n_decs; }\r
+ std::map<int, int> GetActiveVideoDecoders(void) { return m_active_vdecs; }\r
+ std::map<int, int> GetActiveNVideoDecoders(void) { return m_active_nvdecs; }\r
+ int GetActiveDecoderNum(void);\r
+ bool HasAvailableDecoder(void);\r
+ bool HasAvailableDecoderNDecoding(void);\r
+ bool HasAvailableDecoder(std::multimap<int, int> retirables);\r
+ bool HasAvailableDecoderNDecoding(std::multimap<int, int> retirables);\r
+ void AddReclaimResources(consumer_reclaim_s *consumers);\r
+ void ClearReclaimResources(void);\r
+ void Update(resource_update_type_e type, const int device_id, const int consumer_id);\r
+\r
+ void InitScalerTable(void);\r
+ int SwapScaler(int id_a, int id_b);\r
+ void GetScalerList(std::map<int, CResource*> *scalers);\r
+ int ToScalerId(int device_id);\r
+ void UpdateVirtualScalerIds(void);\r
+ void ResetZoneIds(void);\r
+\r
+ static gboolean NotifyResourceStateUpdated(gpointer data);\r
+private:\r
+ CResource *FindResource(const char *device_name);\r
+ CResource *FindMainResource(rms_rsc_category_e category_id);\r
+\r
+ void AddDeviceID(IN int device_id, IN CResource *resource);\r
+ void AddDeviceName(IN const char *device_name, IN CResource *resource);\r
+ void AddVirtualDeviceID(IN CVirtualResource *vresource);\r
+\r
+ void UpdateBWbyRelease(CResource *resource);\r
+ void UpdateBWbyAllocation(const unsigned int bandwidth, CResource *resource);\r
+ void UpdateByRelease(CResource *resource, const int device_id, const int consumer_id);\r
+ void UpdateByAllocation(CResource *resource, const int device_id, const int consumer_id);\r
+ void SetVirtualScalerId(CResource *resource);\r
+ int GetVirtualScalerId(CResource *resource);\r
+ int GetDedicatedVirtualScalerId(int device_id);\r
+ void PrintVirtualScalerMap(void);\r
+\r
+ void AddActiveVideoDecoder(const int device_id, const int consumer_id, const int category_class);\r
+ void RemoveActiveVideoDecoder(const int device_id, const int category_class);\r
+ void AddActiveJpegDecoder(const int device_id, const int consumer_id);\r
+ void RemoveActiveJpegDecoder(const int device_id);\r
+ void PrintVideoDecoderConsumers(void);\r
+\r
+ void NotifyResourceStateUpdatedAsync(CResource *resource, int consumer_id);\r
+\r
+ CResource *FindScaler(int id);\r
+ void InsertVirtualScaler(int virtual_id, CResource *resource);\r
+ void SwapResource(std::set<int> consumers, int cur_device_id, int new_device_id);\r
+ void UpdateConsumerInfoOfResource(CResource *resource, std::set<int> new_consumers, int new_virtual_id);\r
+\r
+ int CountNDecoders(std::map<int, int> retirables);\r
+ void InsertResourceHasZoneId(CResource *resource);\r
+ void RemoveResourceHasZoneId(int device_id);\r
+ std::map<rms_rsc_category_e, CResourceCategory*> m_resourceCategoryMap; //category info\r
+ std::map<int, CVirtualResource *> m_v_deviceid_to_rsc;\r
+ std::map<int, CResource*> m_deviceid_to_rsc;\r
+ std::map<std::string, CResource*> m_devicename_to_rsc;\r
+ std::map<int, CResource*> m_scaler_map;\r
+ std::map<int, CResource*> m_rscs_has_zone_id;\r
+\r
+ static CResourceDB *m_instance;\r
+ unsigned int m_device_id; //for virtual resource\r
+ int m_max_vdecs;\r
+\r
+ std::set<int> m_reclaim_rscs; // resources reclaiming\r
+ std::map<int, int> m_active_vdecs; // device id, consumer id\r
+ std::map<int, int> m_active_jdecs; // device id, consumer id\r
+ std::map<int, int> m_active_nvdecs; // device id, consumer id\r
+};\r
+\r
+#endif // __RSC_MGR_SERVER_DB_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RSC_MGR_SERVER_MANAGER_H__\r
+#define __RSC_MGR_SERVER_MANAGER_H__\r
+#include <glib.h>\r
+#include <CConsumer.h>\r
+#include <rms_type.h>\r
+#include <map>\r
+#include <CResourceDB.h>\r
+#include <CConsumerContainer.h>\r
+\r
+class CResourceManager\r
+{\r
+public:\r
+ CResourceManager();\r
+ ~CResourceManager() = default;\r
+\r
+ int AllocateResources(rms_msg_request *req, rms_return_device_s *allocated_devices);\r
+ int ReleaseResourcesOfPid(IN const int pid);\r
+ int ReleaseResources(IN int consumer_id, IN const rms_requests_device_s *req);\r
+ int RegisterResources(void);\r
+\r
+ int SetAppId(IN int consumer_id, IN const char *app_id);\r
+ int RegisterConsumer(int consumer_id, int process_id, const char *app_id, int main_priority, int sub_priority);\r
+ int UnregisterConsumer(IN int consumer_id);\r
+ int FindReclaimableConsumers(rms_msg_request *req, consumer_reclaim_s *return_consumer, int *zone_id);\r
+ int GetActiveDecoderNum(void);\r
+ int GetActiveAudioOut(int consumer_id);\r
+\r
+ int IsCategoryAvailableToUse(rms_msg_request *request, int *is_available);\r
+ bool IsReclaimed(IN const int device_id, IN const int consumer_id);\r
+\r
+ int GetResourceState(int device_id);\r
+ int FindDeviceId(int virtual_id);\r
+ int GetResourceList(int category_id, GVariantBuilder *builder);\r
+ int GetScalerState(GVariantBuilder *builder);\r
+ int GetResourceCollectionState(int collection, GVariantBuilder *builder);\r
+ int SwapResources(int device_id_a, int device_id_b);\r
+ int RestoreResources(int category_id);\r
+ int GetScalerHWId(int zone_id);\r
+ int GetZoneId(int device_id);\r
+ void ResetZoneIds(void);\r
+ void UpdateZoneIds(std::string app_id, int zone_id);\r
+\r
+private:\r
+ void MakeRequests(CRequester *requester, rms_msg_request *reqs, std::vector<CRequest*> *requests);\r
+ void AllocateCandidates(std::vector<CRequest *> requests);\r
+ void ReleaseResources(const int consumer_id);\r
+ int GetScalerState(int category_id, GVariantBuilder *builder);\r
+\r
+ void MakeResourceMapPerConsumer(std::multimap<int, int> *device_id_to_consumer_id_map, std::map<int, std::set<int> > *consumer_id_to_resource_set_map);\r
+ void MakeConsumerInfoToBeReturned(consumer_reclaim_s *return_consumer, std::map<int, std::set<int> > *consumer_id_to_resource_set_map);\r
+ void PrintConsumerInfoToBeReturned(consumer_reclaim_s *consumer_info);\r
+\r
+ CResourceDB *m_db;\r
+\r
+ int m_is_db_created;\r
+ rms_error_type_e m_error_type;\r
+ CConsumerContainer *m_consumers;\r
+\r
+};\r
+\r
+#endif // __RSC_MGR_SERVER_MANAGER_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CRESOURCE_OBSERVER_H__\r
+#define __CRESOURCE_OBSERVER_H__\r
+\r
+typedef enum _resource_update_type_e {\r
+ UPDATED_BY_ALLOC = 0,\r
+ UPDATED_BY_RELEASE\r
+} resource_update_type_e;\r
+\r
+class CResourceObserver\r
+{\r
+public:\r
+ virtual ~CResourceObserver() {}\r
+ virtual void Update(resource_update_type_e type, const int device_id, const int consumer_id) = 0;\r
+};\r
+\r
+#endif // __CRESOURCE_OBSERVER_H__\r
--- /dev/null
+/*\r
+* Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+*\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+*/\r
+\r
+#ifndef __CRESOURCE_STATE_H__\r
+#include <iostream>\r
+\r
+class CResourceState\r
+{\r
+public:\r
+ CResourceState(int device_id, int category_type, int consumer_id, int state, std::string app_id);\r
+ ~CResourceState() = default;\r
+\r
+ int GetDeviceId(void) { return m_device_id; }\r
+ int GetConsumerId(void) { return m_consumer_id; }\r
+ int GetState(void) { return m_state; }\r
+ int GetCategoryType(void) { return m_category_type; }\r
+ std::string GetAppId(void) { return m_app_id; }\r
+\r
+private:\r
+ int m_device_id;\r
+ int m_consumer_id;\r
+ int m_state;\r
+ int m_category_type;\r
+ std::string m_app_id;\r
+};\r
+\r
+#endif //__CRESOURCE_STATE_H__
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CRESOURCE_SUBJECT_H__\r
+#define __CRESOURCE_SUBJECT_H__\r
+\r
+#include <CResourceObserver.h>\r
+\r
+class CResourceObserver;\r
+class CResourceSubject\r
+{\r
+public:\r
+ virtual ~CResourceSubject() {}\r
+\r
+ virtual void RegisterObserver(CResourceObserver *observer) = 0;\r
+ virtual void UnregisterObserver(CResourceObserver *observer) = 0;\r
+ virtual void NotifyObservers(resource_update_type_e type, const int consumer_id) = 0;\r
+};\r
+\r
+#endif // __CRESOURCE_SUBJECT_H__\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __C_VIDEO_CONTROLLER_H__\r
+#define __C_VIDEO_CONTROLLER_H__\r
+\r
+#include <map>\r
+#include <glib.h>\r
+#include <wayland-client.h>\r
+#include <CLockController.h>\r
+\r
+class CVideoController\r
+{\r
+public:\r
+ ~CVideoController(void);\r
+ static CVideoController *GetInstance(void);\r
+ void UpdateVirtualScalerIds(std::map<int, int> scaler_id_map);\r
+\r
+private:\r
+ typedef struct _scaler_id_pair {\r
+ unsigned int virtual_scaler_id;\r
+ unsigned int scaler_id;\r
+ } scaler_id_pair_t;\r
+\r
+ CVideoController(void);\r
+ void WaylandDisplayCreate(void);\r
+ void WaylandDisplayDestroy(void);\r
+ void RunWaitingThread(void);\r
+ static gpointer WaitingThread(gpointer data);\r
+\r
+ static CVideoController *m_instance;\r
+ struct wl_display *m_wl_display;\r
+ struct wl_registry *m_wl_registry;\r
+ struct tizen_video_rsc *m_tizen_video_rsc;\r
+ struct wl_registry_listener m_registry_listener;\r
+\r
+ GThread *m_waiting_thread;\r
+ CLockController *m_lock_ctr;\r
+};\r
+\r
+#endif //__C_VIDEO_CONTROLLER_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef _RM_VIRTUAL_RESOURCE_H_INCLUDED\r
+#define _RM_VIRTUAL_RESOURCE_H_INCLUDED\r
+\r
+#include <rms_type.h>\r
+#include <map>\r
+#include <set>\r
+\r
+class CResource;\r
+class CVirtualResource\r
+{\r
+public:\r
+ CVirtualResource(const int virtual_device_id, const rms_rsc_category_e category_type, unsigned int bw, std::set<unsigned int> dependent, bool is_main_device, const char *audio_codec, int category_class);\r
+ virtual ~CVirtualResource(void) {}\r
+\r
+ CResource *GetResource(void) { return m_rsc; }\r
+ void SetResource(CResource *resource);\r
+\r
+ int GetVResourceID(void) { return m_vir_rsc_id; }\r
+ rms_rsc_category_e GetCategoryType(void) { return m_category_type; }\r
+ int GetCategoryClass(void) { return m_category_class; }\r
+ unsigned int GetBW(void) { return m_vir_rsc_bw; }\r
+ std::set<unsigned int> GetMemClusters(void) { return m_mem_clusters; }\r
+ std::string GetAudioCodec(void) { return m_audio_codec; }\r
+\r
+ bool IsMainDevice(void) { return m_is_main_device; }\r
+ bool IsAIDevice(void) { return m_is_ai_device; }\r
+private:\r
+ int m_vir_rsc_id;\r
+ rms_rsc_category_e m_category_type;\r
+ unsigned int m_vir_rsc_bw;\r
+ bool m_is_main_device;\r
+ bool m_is_ai_device;\r
+ int m_category_class;\r
+ std::set<unsigned int> m_mem_clusters;\r
+ std::string m_audio_codec;\r
+\r
+ CResource *m_rsc;\r
+};\r
+\r
+#endif // _RM_VIRTUAL_RESOURCE_H_INCLUDED\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CAUDIO_CODEC_H__\r
+#define __CAUDIO_CODEC_H__\r
+\r
+#include <map>\r
+#include <set>\r
+#include <string>\r
+\r
+class CAudioCodec{\r
+public:\r
+ CAudioCodec(const char *name);\r
+ ~CAudioCodec();\r
+\r
+ std::string getName(void) { return m_name; }\r
+ std::set<int> getResourcesOfConsumer(int consumer_id);\r
+\r
+ void increaseRef(int device_id, int consumer_id);\r
+ void decreaseRef(int device_id, int consumer_id);\r
+ void increaseMaxRef(void);\r
+\r
+ bool isAvailableToUse(void);\r
+ bool isMixingSupported(void) { return (m_ref_count_max >= 2 || m_name.length() == 0); }\r
+ bool canBeUsedByMultiApp(void) { return (m_name.length() == 0); }\r
+ std::map<int, int> GetConsumers(void) { return m_consumers; }\r
+\r
+private:\r
+ bool isUnknownCodec(void) { return (m_name.length() == 0); }\r
+ std::string m_name;\r
+ unsigned int m_ref_count;\r
+ unsigned int m_ref_count_max;\r
+ std::map<int, int> m_consumers; // consumer id, ref_count\r
+ std::map<int, int> m_resources; // device_id, consumer id\r
+};\r
+\r
+#endif //__CAUDIO_CODEC_H__
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CAUDIO_CODEC_COLLECTION_H__\r
+#define __CAUDIO_CODEC_COLLECTION_H__\r
+\r
+#include <map>\r
+#include <string>\r
+\r
+class CAudioCodec;\r
+class CAudioCodecCollection {\r
+public:\r
+ static CAudioCodecCollection *getInstance();\r
+ ~CAudioCodecCollection();\r
+\r
+ void registerAudioCodec(const char *name, int count);\r
+ CAudioCodec *findAudioCodec(std::string name);\r
+private:\r
+ CAudioCodecCollection();\r
+\r
+ static CAudioCodecCollection *m_instance;\r
+ std::map<std::string, CAudioCodec*> m_audio_codecs;\r
+};\r
+\r
+#endif //__CAUDIO_CODEC_COLLECTION_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CBANDWIDTH_H__\r
+#define __CBANDWIDTH_H__\r
+\r
+#include <map>\r
+#include <set>\r
+\r
+class CBandwidth\r
+{\r
+public:\r
+ static CBandwidth *GetInstance();\r
+\r
+ void SetMax(unsigned int max) { m_max = m_avail = max; }\r
+ unsigned int GetMax(void) { return m_max; }\r
+ unsigned int GetAvail(void) { return m_avail; }\r
+ void AddConsumer(int device_id, int consumer_id, int category_id, int category_class);\r
+ void RemoveConsumer(int device_id, int category_id, int category_class);\r
+ void Decrease(unsigned int bw, int category_id, int category_class, int device_id);\r
+ void Increase(unsigned int bw, int category_id, int category_class, int device_id);\r
+ int GetNConsumersNDec(int category_id);\r
+ void GetConsumersNDec(int category_id, std::map<int, int> *consumers);\r
+ std::map<int, int> GetConsumers(void) { return m_consumers; }\r
+\r
+private:\r
+ static CBandwidth *m_instance;\r
+\r
+ void AddConsumerNDec(int device_id, int consumer_id, int category_id);\r
+ void RemoveConsumerNDec(int device_id, int category_id);\r
+ bool IncludeSameDeviceGroup(int category_id, int device_id);\r
+ bool IsSameMemClusters(std::set<unsigned int> c_mc, std::set<unsigned int> u_mc);\r
+\r
+ std::map<int, int> m_consumers; // device_id, consumer_id\r
+ std::map<int, std::map<int, int>> m_ndec_consumers; // category id, <device_id, consumer_id>\r
+ unsigned int m_max;\r
+ unsigned int m_avail;\r
+};\r
+\r
+#endif //__CBANDWIDTH_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CDEPENDENCY_CONTROLLER_H__\r
+#define __CDEPENDENCY_CONTROLLER_H__\r
+\r
+#include <map>\r
+#include <set>\r
+#include <CResourceObserver.h>\r
+\r
+class CMemCluster;\r
+class CMixingMode;\r
+class CAudioCodec;\r
+class CResourceObserver;\r
+class CDependencyController : public CResourceObserver\r
+{\r
+public:\r
+ static CDependencyController *getInstance(void);\r
+ ~CDependencyController();\r
+\r
+ void RegisterMemCluster(unsigned int id);\r
+ bool isAvailableMemClusters(std::set<unsigned int> mc_ids);\r
+ bool isAvailableMemClusters(std::set<unsigned int> mc_ids, int category_class, int category_id);\r
+ bool isAvailableMemClusters(std::set<unsigned int> mc_ids, std::string app_id);\r
+ bool isSharableMemClusters(std::set<unsigned int> mc_ids, int device_id);\r
+ bool canReclaimMemClusters(std::set<unsigned int> mc_ids, int consumer_id);\r
+ bool canReclaimMemClusters(std::set<unsigned int> mc_ids, int consumer_id, std::string app_id);\r
+ int getReclaimableMemClusterConsumers(std::set<unsigned int> mc_ids, int consumer_id, std::multimap<int, int>* reclaimables);\r
+ int getReclaimableMemClusterConsumers(std::set<unsigned int> mc_ids, int consumer_id, std::multimap<int, int>* reclaimables, std::string app_id);\r
+ void SwapConsumers(int device_id_a, std::set<int> consumers_a, int device_id_b, std::set<int> consumers_b);\r
+\r
+ bool isAvailableAudioCodec(std::string name);\r
+ bool isAudioCodecBeingUsed(void) { return (m_acodec_consumers.size() > 0); }\r
+ std::map<unsigned long, std::pair<int, int>> getAudioCodecConsumers(void);\r
+\r
+ CMixingMode *getCurMixingMode(void) { return m_cur_mixing_mode; }\r
+ CMixingMode *findMixingMode(rms_mixing_mode_e mode);\r
+ void Update(resource_update_type_e type, const int device_id, const int consumer_id);\r
+private:\r
+ CDependencyController();\r
+\r
+ void registerMixingModes(void);\r
+ bool IsRegisteredMemCluster(unsigned int id);\r
+ void addMemClusterConsumer(int device_id, int consumer_id);\r
+ void removeMemClusterConsumer(int device_id, int consumer_id);\r
+ void ClearMemClusterConsumer(int device_id);\r
+ CMemCluster *findMemCluster(unsigned int id);\r
+\r
+ static CDependencyController *m_instance;\r
+ std::map<unsigned int, CMemCluster*> m_mem_clusters;\r
+\r
+ void addAudioCodecConsumer(int device_id, int consumer_id);\r
+ void removeAudioCodecConsumer(int device_id, int consumer_id);\r
+ void setCurMixingMode(int device_id, int consumer_id);\r
+ void resetCurMixingMode(int device_id, int consumer_id);\r
+\r
+ std::map<int, int> m_acodec_consumers; // device id, consumer id\r
+ unsigned int m_acodec_ref_count_max = 2;\r
+\r
+ std::map<rms_mixing_mode_e, CMixingMode*> m_mixing_modes;\r
+ CMixingMode *m_cur_mixing_mode;\r
+};\r
+\r
+#endif // __CDEPENDENCY_CONTROLLER_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CMEM_CLUSTER_H__\r
+#define __CMEM_CLUSTER_H__\r
+\r
+#include <set>\r
+#include <map>\r
+\r
+class CMemCluster{\r
+public:\r
+ CMemCluster(unsigned int m_id);\r
+ ~CMemCluster();\r
+\r
+ bool IsUsed(void);\r
+ bool IsUsedBy(std::string app_id);\r
+ bool IsSharable(int device_id);\r
+\r
+ unsigned int GetId(void) { return m_id; }\r
+ std::set<int> GetAssignedDeviceId(int consumer_id);\r
+ int GetCategoryClass(void) { return m_category_class; }\r
+ int GetCategoryId(void) { return m_category_id; }\r
+\r
+ void AddConsumer(int consumer_id, int device_id, int category_class, int category_id);\r
+ void RemoveConsumer(int consumer_id, int device_id);\r
+ void ClearConsumers(void);\r
+ std::set<int> GetConsumers(void);\r
+private:\r
+ unsigned int m_id;\r
+ std::map<int, std::set<int>> m_consumers; // consumer, device ids\r
+ int m_category_class;\r
+ int m_category_id;\r
+};\r
+\r
+#endif //__CMEM_CLUSTER_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CMIXING_MODE_H__\r
+#define __CMIXING_MODE_H__\r
+\r
+#include <map>\r
+#include <string>\r
+#include <rms_type.h>\r
+\r
+class CAudioCodec;\r
+class CMixingMode{\r
+public:\r
+ CMixingMode(rms_mixing_mode_e mode) { m_mode = mode; }\r
+ ~CMixingMode() = default;\r
+\r
+ int AddConsumer(int device_id, int consumer_id);\r
+ int RemoveConsumer(int device_id, int consumer_id);\r
+ rms_mixing_mode_e getMode(void) { return m_mode; }\r
+ std::map<int, int> GetConsumers(void) { return m_consumers; }\r
+private:\r
+ rms_mixing_mode_e m_mode;\r
+ std::map<std::string, CAudioCodec*> m_audio_codecs;\r
+ std::map<int, int> m_consumers; // device id, consumer id\r
+};\r
+\r
+#endif //__CAUDIO_MIXING_MODE_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CALLOCATE_MODE_STRATEGY_H__\r
+#define __CALLOCATE_MODE_STRATEGY_H__\r
+\r
+#include <rms_type.h>\r
+#include <vector>\r
+\r
+class CRequest;\r
+class CAllocateModeStrategy\r
+{\r
+public:\r
+ virtual ~CAllocateModeStrategy() {}\r
+\r
+ virtual bool CanAllocateResources(std::vector<CRequest *> requests, rms_allocate_result_s *result) = 0;\r
+ virtual void WriteAllocResult(rms_allocate_result_s *alloc_result, std::vector<CRequest *> requests, rms_return_device_s *allocated_devices) = 0;\r
+};\r
+\r
+\r
+#endif //__CALLOCATE_MODE_STRATEGY_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CALLOCATE_MODE_STRATEGY_PROVIDER_H__\r
+#define __CALLOCATE_MODE_STRATEGY_PROVIDER_H__\r
+\r
+#include <rms_type.h>\r
+\r
+class CAllocateModeStrategy;\r
+class CAllocateModeStrategyProvider\r
+{\r
+public:\r
+ static CAllocateModeStrategyProvider *getInstance();\r
+ ~CAllocateModeStrategyProvider();\r
+\r
+ CAllocateModeStrategy *GetStrategy(rms_msg_request *req);\r
+private:\r
+ CAllocateModeStrategyProvider();\r
+\r
+ int getAllocateMode(rms_msg_request *req);\r
+\r
+ static CAllocateModeStrategyProvider *m_instance;\r
+};\r
+\r
+#endif //__CALLOCATE_MODE_PROVIDER_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CALLOCATE_STRATEGY_H__\r
+#define __CALLOCATE_STRATEGY_H__\r
+\r
+#include <rms_type.h>\r
+#include <map>\r
+#include <set>\r
+\r
+class CVirtualResource;\r
+class CRequest;\r
+class CAllocateStrategy\r
+{\r
+public:\r
+ virtual ~CAllocateStrategy() {}\r
+ virtual CVirtualResource *findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req) = 0;\r
+ virtual int reserveResource(CVirtualResource *vrsc, CRequest *req) = 0;\r
+ virtual void GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource*> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type) = 0;\r
+\r
+protected:\r
+ void ExcludeResources(std::map<int, CVirtualResource *> vresources, std::map<int, CVirtualResource *>* filtered_resources, CRequest *req);\r
+ void ExcludeResources(std::multimap<unsigned long, CVirtualResource *> vresources, std::multimap<unsigned long, CVirtualResource *>* filtered_resources, CRequest *req);\r
+ void ExcludeDuplicatedNDecoders(std::multimap<int, int> *retirables, std::set<int> *excluded);\r
+ void updateReasonByResourceState(int device_id, CRequest *req);\r
+ void updateReasonBySharableCount(int device_id, CRequest *req);\r
+ int GetReclaimedBW(std::multimap<int, int> *retirables);\r
+};\r
+\r
+#endif //__CALLOCATE_STRATEGY_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CALLOCATE_STRATEGY_PROVIDER_H__\r
+#define __CALLOCATE_STRATEGY_PROVIDER_H__\r
+\r
+#include <rms_type.h>\r
+\r
+class CAllocateStrategy;\r
+class CAllocateStrategyProvider\r
+{\r
+public:\r
+ static CAllocateStrategyProvider *getInstance();\r
+ ~CAllocateStrategyProvider();\r
+\r
+ CAllocateStrategy *GetStrategy(rms_rsc_category_e category, int category_class);\r
+\r
+private:\r
+ CAllocateStrategyProvider();\r
+\r
+ bool IsAudioDecoderCategory(rms_rsc_category_e category);\r
+ bool IsVideoDecoderCategory(rms_rsc_category_e category);\r
+ bool IsBGScalerCategory(rms_rsc_category_e category);\r
+ bool IsNDecordingVideoDecoderCategory(int category_class);\r
+ bool IsMultiviewScalerCategory(rms_rsc_category_e category);\r
+ bool IsSubScalerCategory(rms_rsc_category_e category);\r
+\r
+ static CAllocateStrategyProvider *m_instance;\r
+};\r
+\r
+#endif //__CALLOCATE_STRATEGY_PROVIDER_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CAUDIO_DECODER_STRATEGY_H__\r
+#define __CAUDIO_DECODER_STRATEGY_H__\r
+\r
+#include <map>\r
+#include <rms_type.h>\r
+\r
+class CRequest;\r
+class CVirtualResource;\r
+class CAllocateStrategy;\r
+class CAudioDecoderStrategy: public CAllocateStrategy\r
+{\r
+public:\r
+ CAudioDecoderStrategy() = default;\r
+ ~CAudioDecoderStrategy() = default;\r
+\r
+ CVirtualResource *findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req);\r
+ int reserveResource(CVirtualResource *vrsc, CRequest *req);\r
+ void GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type);\r
+private:\r
+ int GetRetirableConsumers(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type);\r
+};\r
+\r
+#endif //__CAUDIO_DECODER_STRATEGY_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CEXCLUSIVE_STRATEGY_H__\r
+#define __CEXCLUSIVE_STRATEGY_H__\r
+\r
+#include <map>\r
+#include <rms_type.h>\r
+#include <CAllocateStrategy.h>\r
+\r
+class CRequest;\r
+class CVirtualResource;\r
+class CAllocateStrategy;\r
+class CExclusiveStrategy: public CAllocateStrategy\r
+{\r
+public:\r
+ CExclusiveStrategy() = default;\r
+ ~CExclusiveStrategy() = default;\r
+\r
+ CVirtualResource *findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req);\r
+ int reserveResource(CVirtualResource * vrsc, CRequest *req);\r
+ void GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type);\r
+\r
+private:\r
+ int getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type);\r
+ int getRetirableConsumersShare(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type);\r
+ void updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req);\r
+ bool isAllocatableResource(CVirtualResource *vresource, CRequest *req);\r
+ bool ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources);\r
+ bool isSharableResource(CVirtualResource *vresource, CRequest *req);\r
+ bool ContainSharableResource(std::multimap<unsigned long, CVirtualResource *> vresources);\r
+};\r
+\r
+#endif //__CEXCLUSIVE_STRATEGY_H__\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CINVALID_MODE_STRATEGY_H__\r
+#define __CINVALID_MODE_STRATEGY_H__\r
+\r
+#include <rms_type.h>\r
+#include <vector>\r
+\r
+class CRequest;\r
+class CAllocateModeStrategy;\r
+class CInvalidModeStrategy: public CAllocateModeStrategy\r
+{\r
+public:\r
+ CInvalidModeStrategy();\r
+ ~CInvalidModeStrategy();\r
+\r
+ bool CanAllocateResources(std::vector<CRequest *> requests, rms_allocate_result_s *result);\r
+ void WriteAllocResult(rms_allocate_result_s *alloc_result, std::vector<CRequest *> requests, rms_return_device_s *allocated_devices);\r
+};\r
+\r
+#endif// __CINVALID_MODE_STRATEGY_H__\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CMIXING_STRATEGY_H__\r
+#define __CMIXING_STRATEGY_H__\r
+\r
+#include <map>\r
+#include <rms_type.h>\r
+\r
+class CRequest;\r
+class CAudioCodec;\r
+class CVirtualResource;\r
+class CMixingMode;\r
+class CMixingStrategy\r
+{\r
+public:\r
+ static CMixingStrategy *getInstance();\r
+ ~CMixingStrategy() = default;\r
+\r
+ bool isAvailableAudioCodec(std::string name, int consumer_id, rms_error_type_e *reason);\r
+ int getReclaimableAudioCodecConsumers(std::string codec_name, int consumer_id, CRequest *req, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type);\r
+ void updateReasonByAudioCodec(CVirtualResource *vresource, CRequest *req, rms_error_type_e cur_reason);\r
+\r
+ int getReclaimableMixingModeConsumers(rms_mixing_mode_e mode, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type);\r
+ void updateReasonByMixingMode(CVirtualResource *vresource, CRequest *req, rms_error_type_e cur_reason);\r
+ bool isAvailableMixingMode(rms_mixing_mode_e mode);\r
+\r
+private:\r
+ CMixingStrategy() = default;\r
+\r
+ bool needReclaimCheck(rms_error_type_e reason);\r
+ bool canReclaimAudioCodec(std::string codec_name, int consumer_id);\r
+ bool canReclaimMixingMode(rms_mixing_mode_e mode, int consumer_id);\r
+ bool canReclaimMixingMode(rms_mixing_mode_e mode, CMixingMode *cur_mode, int consumer_id);\r
+\r
+ static CMixingStrategy *m_instance;\r
+};\r
+\r
+#endif //__CMIXING_STRATEGY_H__\r
--- /dev/null
+/*\r
+* Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+*\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+*/\r
+\r
+#ifndef __C_NDECODING_VIDEO_DECODER_STRATEGY_H__\r
+#define __C_NDECODING_VIDEO_DECODER_STRATEGY_H__\r
+\r
+#include <map>\r
+#include <rms_type.h>\r
+#include <CAllocateStrategy.h>\r
+\r
+class CRequest;\r
+class CVirtualResource;\r
+class CAllocateStrategy;\r
+class CNDecodingVideoDecoderStrategy: public CAllocateStrategy\r
+{\r
+public:\r
+ CNDecodingVideoDecoderStrategy() = default;\r
+ ~CNDecodingVideoDecoderStrategy() = default;\r
+\r
+ CVirtualResource *findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req);\r
+ int reserveResource(CVirtualResource *vrsc, CRequest *req);\r
+ void GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type);\r
+\r
+private:\r
+ int getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type);\r
+ void updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req);\r
+ void updateReasonByBW(CVirtualResource *vresource, CRequest *req);\r
+ void updateReasonByTripleDecoding(CRequest *req);\r
+ bool isAllocatableResource(CVirtualResource *vresource, CRequest *req);\r
+ bool ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources);\r
+ bool canReclaimRequiredBW(CRequest *req, unsigned int bw);\r
+ int GetConsumerUsingBW(CRequest *req, unsigned int bw, std::multimap<int, int>* return_ids);\r
+ bool canReclaimActiveVideoDecoders(CRequest *req);\r
+ int GetReclaimableVideoDecoderConsumers(int consumer_id, std::multimap<int, int>* reclaimables, CRequest *req, rms_error_type_e *err_type);\r
+ void SelectDevicesByMainSub(CRequest *req, std::map<int, int> *src, std::map<int, int> *result);\r
+ int GetConsumerUsingBWByAllocationTime(int requester_id, unsigned int required_bw, std::map<int, int> bw_consumers, std::multimap<int, int> *reclaimed_consumers);\r
+};\r
+\r
+#endif //__C_NDECODING_VIDEO_DECODER_STRATEGY_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CNORMAL_MODE_STRATEGY_H__\r
+#define __CNORMAL_MODE_STRATEGY_H__\r
+\r
+#include <vector>\r
+#include <rms_type.h>\r
+\r
+class CRequest;\r
+class CAllocateModeStrategy;\r
+class CNormalModeStrategy:public CAllocateModeStrategy\r
+{\r
+public:\r
+ CNormalModeStrategy();\r
+ ~CNormalModeStrategy();\r
+\r
+ bool CanAllocateResources(std::vector<CRequest *> requests, rms_allocate_result_s *result);\r
+ void WriteAllocResult(rms_allocate_result_s *alloc_result, std::vector<CRequest *> requests, rms_return_device_s *allocated_devices);\r
+private:\r
+ rms_error_type_e GetCandidateFindResult(std::vector<CRequest *> requests);\r
+};\r
+\r
+#endif //__CNORMAL_MODE_STRATEGY_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CNORMAL_STRATEGY_H__\r
+#define __CNORMAL_STRATEGY_H__\r
+\r
+#include <map>\r
+#include <rms_type.h>\r
+#include <CAllocateStrategy.h>\r
+\r
+class CRequest;\r
+class CVirtualResource;\r
+class CNormalStrategy: public CAllocateStrategy\r
+{\r
+public:\r
+ CNormalStrategy();\r
+ ~CNormalStrategy();\r
+\r
+ CVirtualResource *findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req);\r
+ int reserveResource(CVirtualResource *vrsc, CRequest *req);\r
+ void GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource*> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type);\r
+\r
+private:\r
+ bool ContainFreeResource(std::multimap<unsigned long, CVirtualResource *> vresources);\r
+};\r
+\r
+#endif //__CALLOCATE_STRATEGY_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CPREFERENCE_MODE_STRATEGY_H__\r
+#define __CPREFERENCE_MODE_STRATEGY_H__\r
+\r
+#include <vector>\r
+#include <rms_type.h>\r
+\r
+class CRequest;\r
+class CAllocateModeStrategy;\r
+class CPreferenceModeStrategy: public CAllocateModeStrategy\r
+{\r
+public:\r
+ CPreferenceModeStrategy();\r
+ ~CPreferenceModeStrategy();\r
+\r
+ bool CanAllocateResources(std::vector<CRequest *> requests, rms_allocate_result_s *result);\r
+ void WriteAllocResult(rms_allocate_result_s *alloc_result, std::vector<CRequest *> requests, rms_return_device_s *allocated_devices);\r
+};\r
+\r
+#endif //__CPREFERENCE_MODE_STRATEGY_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CSCALER_STRATEGY_H__\r
+#define __CSCALER_STRATEGY_H__\r
+\r
+#include <map>\r
+#include <rms_type.h>\r
+#include <CAllocateStrategy.h>\r
+\r
+class CRequest;\r
+class CVirtualResource;\r
+class CScalerStrategy: public CAllocateStrategy\r
+{\r
+public:\r
+ CScalerStrategy();\r
+ ~CScalerStrategy();\r
+\r
+ CVirtualResource * findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req);\r
+ int reserveResource(CVirtualResource * vrsc, CRequest *req);\r
+ void GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type);\r
+ void SelectConsumersByZoneId(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result);\r
+ void SelectConsumersByAllocationTime(std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result);\r
+\r
+private:\r
+ bool ContainFreeResource(std::multimap<unsigned long, CVirtualResource *> vresources);\r
+ bool ContainInterlacedNotSupportedApp(std::map<int, std::multimap<int, int>> *candidates);\r
+ int FindScalerInSameZone(int zone_id);\r
+ int FindScalerUsedByAppInterlacedNotSupported(std::map<int, std::multimap<int, int>> *candidates);\r
+ void SelectConsumersBySwap(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result);\r
+ void updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req);\r
+};\r
+\r
+#endif //__CSCALER_STRATEGY_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CVIDEO_DECODER_STRATEGY_H__\r
+#define __CVIDEO_DECODER_STRATEGY_H__\r
+\r
+#include <map>\r
+#include <rms_type.h>\r
+#include <CAllocateStrategy.h>\r
+\r
+class CRequest;\r
+class CVirtualResource;\r
+class CAllocateStrategy;\r
+class CVideoDecoderStrategy: public CAllocateStrategy\r
+{\r
+public:\r
+ CVideoDecoderStrategy();\r
+ ~CVideoDecoderStrategy() = default;\r
+\r
+ CVirtualResource *findCandidate(std::map<int, CVirtualResource*> vresources, CRequest *req);\r
+ int reserveResource(CVirtualResource *vrsc, CRequest *req);\r
+ void GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource*> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type);\r
+\r
+private:\r
+ int getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type);\r
+ void updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req);\r
+ void updateReasonByBW(CVirtualResource *vresource, CRequest *req);\r
+ void updateReasonByTripleDecoding(CRequest *req);\r
+ bool isAllocatableResource(CVirtualResource *vresource, CRequest *req);\r
+ bool ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources);\r
+ bool canReclaimRequiredBW(CRequest *req, unsigned int bw);\r
+ int getConsumerUsingBW(CRequest *req, unsigned int bw, std::multimap<int, int>* return_ids);\r
+ int GetConsumerUsingBWByAllocationTime(int requester_id, unsigned int bw, std::map<int, int> candidates, std::multimap<int, int>* return_ids);\r
+ bool canReclaimActiveVideoDecoders(CRequest *req);\r
+ int GetReclaimableVideoDecoderConsumers(int consumer_id, std::multimap<int, int>* reclaimables, CRequest *req, rms_error_type_e *err_type);\r
+ void SelectConsumersByAllocationTime(std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result);\r
+ void SelectConsumersByZoneId(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result);\r
+ void SelectInSameCategoryAndZone(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result);\r
+ void SelectInSameZone(int zone_id, std::map<int, std::multimap<int, int>> candidates, std::multimap<int, int> *result);\r
+ void SelectDevicesByMainSub(CRequest *req, std::map<int, int> *src, std::map<int, int> *result);\r
+ int GetConflictScore(int n_conflicts);\r
+\r
+ bool m_reclaim_policy_by_zone_id;\r
+};\r
+\r
+#endif //_CVIDEO_DECODER_STRATEGY_H__\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __CVIDEO_ENCODER_EXCLUSIVE_STRATEGY_H__\r
+#define __CVIDEO_ENCODER_EXCLUSIVE_STRATEGY_H__\r
+\r
+#include <map>\r
+#include <rms_type.h>\r
+#include <CAllocateStrategy.h>\r
+\r
+class CRequest;\r
+class CVirtualResource;\r
+class CAllocateStrategy;\r
+class CVideoEncoderExclusiveStrategy: public CAllocateStrategy\r
+{\r
+public:\r
+ CVideoEncoderExclusiveStrategy() = default;\r
+ ~CVideoEncoderExclusiveStrategy() = default;\r
+\r
+ CVirtualResource *findCandidate(std::map<int, CVirtualResource*> vresources, CRequest *req);\r
+ int reserveResource(CVirtualResource *vrsc, CRequest *req);\r
+ void GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource*> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type);\r
+\r
+private:\r
+ int getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type);\r
+ void updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req);\r
+ bool isAllocatableResource(CVirtualResource *vresource, CRequest *req);\r
+ bool ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req);\r
+};\r
+\r
+#endif //__CVIDEO_ENCODER_EXCLUSIVE_STRATEGY_H__\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<node>
+ <interface name="com.samsung.rmservice">
+ <annotation name= "com.Samsung.Exportable" value= "true"/>
+ <method name="TestCall">
+ <arg type="i" name="in_data" direction="in"/>
+ <arg type="i" name="out_data" direction="out"/>
+ </method>
+ <method name="NotifyAllocation">
+ <arg type="i" name="cid" direction="in"/>
+ <arg type="i" name="pid" direction="in"/>
+ <arg type="ai" name="alloc_list" direction="in"/>
+ <arg type="i" name="ret" direction="out"/>
+ <arg type="ai" name="ret_list" direction="out"/>
+ </method>
+ <method name="NotifyConsumerTobeReturned">
+ <arg type="i" name="cid" direction="in"/>
+ <arg type="i" name="pid" direction="in"/>
+ <arg type="ai" name="alloc_list" direction="in"/>
+ <arg type="i" name="ret" direction="out"/>
+ <arg type="ai" name="cid_list" direction="out"/>
+ <arg type="ai" name="pid_list" direction="out"/>
+ <arg type="ai" name="conflict_rsc_num_list" direction="out"/>
+ <arg type="ai" name="devices" direction="out"/>
+ <arg type="ai" name="num_of_rsc" direction="out"/>
+ </method>
+ <method name="NotifyDeallocation">
+ <arg type="i" name="cid" direction="in"/>
+ <arg type="ai" name="dealloc_list" direction="in"/>
+ <arg type="i" name="ret_val" direction="out"/>
+ </method>
+ <method name="NotifyDeallocationByCid">
+ <arg type="i" name="cid" direction="in"/>
+ <arg type="i" name="ret_val" direction="out"/>
+ </method>
+ <method name="NotifyDeallocationByPid">
+ <arg type="i" name="pid" direction="in"/>
+ <arg type="i" name="ret_val" direction="out"/>
+ </method>
+ <method name="NotifyCallback">
+ <arg type="ai" name="list" direction="in"/>
+ <arg type="i" name="ret_val" direction="out"/>
+ </method>
+ </interface>
+</node>
--- /dev/null
+/*\r
+* Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+*\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+*/\r
+\r
+#ifndef __RMS_DEBUG_H__\r
+#define __RMS_DEBUG_H__\r
+\r
+#include <dlog.h>\r
+\r
+\r
+#ifdef LOG_TAG\r
+#undef LOG_TAG\r
+#endif//LOG_TAG\r
+\r
+#define LOG_TAG "RSC_MGR_SERVER"\r
+\r
+#ifndef SERVER_ERR\r
+#define SERVER_ERR(fmt, args...)SLOGE(fmt, ##args)\r
+#endif\r
+\r
+#ifndef SERVER_DBG\r
+#define SERVER_DBG(fmt, args...)SLOGD(fmt, ##args)\r
+#endif\r
+\r
+#ifndef SERVER_INFO\r
+#define SERVER_INFO(fmt, args...)SLOGI(fmt, ##args)\r
+#endif\r
+\r
+#ifndef SERVER_WARN\r
+#define SERVER_WARN(fmt, args...)SLOGW(fmt, ##args)\r
+#endif\r
+\r
+\r
+#endif//__RMS_DEBUG_H__\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RMS_LOG_H__\r
+#define __RMS_LOG_H__\r
+\r
+#include <stdio.h>\r
+\r
+static char g_rms_dlog_msg[4096] = {0,};\r
+static int g_rms_dlog_msg_pose = 0;\r
+\r
+static void rms_log_reset() { g_rms_dlog_msg_pose = 0; }\r
+static void rms_log_add(const char *format_str, ...) __attribute__ ((format (printf, 1, 2)));\r
+static void rms_log_add(const char *format_str, ...) {\r
+ va_list argptr;\r
+ va_start(argptr, format_str);\r
+ g_rms_dlog_msg_pose += vsnprintf(g_rms_dlog_msg + g_rms_dlog_msg_pose, sizeof(g_rms_dlog_msg) - 1 - g_rms_dlog_msg_pose, format_str, argptr);\r
+ va_end(argptr);\r
+}\r
+\r
+#define RMS_LOGE_FLUSH() SLOGE("%s", g_rms_dlog_msg); g_rms_dlog_msg_pose = 0\r
+#define RMS_LOGI_FLUSH() SLOGI("%s", g_rms_dlog_msg); g_rms_dlog_msg_pose = 0\r
+#define RMS_LOGD_FLUSH() SLOGD("%s", g_rms_dlog_msg); g_rms_dlog_msg_pose = 0\r
+\r
+#endif //__RMS_LOG_H__\r
+\r
--- /dev/null
+/*
+ * 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.
+ */
+
+#ifndef __RMS_TYPE_H__
+#define __RMS_TYPE_H__
+
+#include <resource-information/ri-common-type.h>
+
+#define IN
+#define OUT
+
+#define RMS_REMOTE_CONSUMER_ID 1000
+#define RMS_APPID_LENGTH 1024
+#define RMS_NAME_BUF_SIZE 128
+#define RMS_MAX_DEVICE 10
+
+typedef enum {
+ RMS_CALLBACK_TYPE_UNKNOWN = 1,
+ RMS_CALLBACK_TYPE_RESOURCE_CONFLICT, // common resource conflict
+ RMS_CALLBACK_TYPE_RESOURCE_CONFLICT_UD, // resource conflict by ud device
+} rms_callback_type_e;
+
+typedef enum {
+ RMS_CATEGORY_IMAGE_DECODER_NOT_SUPPORTED = RI_CATEGORY_IMAGE_DECODER_NOT_SUPPORTED,
+ RMS_CATEGORY_NOT_PERMITTED = RI_CATEGORY_NOT_PERMITTED, /**< Not permitted category by resource policy */
+ RMS_CATEGORY_MJPEG_DECODER_NOT_SUPPORTED = RI_CATEGORY_MJPEG_DECODER_NOT_SUPPORTED,
+ RMS_CATEGORY_JPEG_DECODER_NOT_SUPPORTED = RI_CATEGORY_JPEG_DECODER_NOT_SUPPORTED,
+ RMS_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED = RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED,
+ RMS_CATEGORY_NONE = RI_CATEGORY_NONE,
+ RMS_CATEGORY_AUDIO_DECODER = RI_CATEGORY_AUDIO_DECODER, /* Audio Decoder */
+ RMS_CATEGORY_AUDIO_EVENT_COMPRESS = RI_CATEGORY_AUDIO_EVENT_COMPRESS,
+ RMS_CATEGORY_AUDIO_SPDIF_ES_OUTPUT = RI_CATEGORY_AUDIO_SPDIF_ES_OUTPUT,
+ RMS_CATEGORY_VIDEO_DECODER = RI_CATEGORY_VIDEO_DECODER, /* Video Decoder - MFD (Multi Format Decoder), FullHD */
+ RMS_CATEGORY_DEMUX = RI_CATEGORY_DEMUX, /* Demux */
+ RMS_CATEGORY_AUDIO_ENCODER = RI_CATEGORY_AUDIO_ENCODER, /* Audio Encoder */
+ RMS_CATEGORY_VIDEO_ENCODER = RI_CATEGORY_VIDEO_ENCODER, /* Video Encoder */
+ RMS_CATEGORY_SCALER = RI_CATEGORY_SCALER, /* Main Scaler */
+ RMS_CATEGORY_TUNER = RI_CATEGORY_TUNER, /* Tuner */
+ RMS_CATEGORY_AUDIO_MAIN_OUT = RI_CATEGORY_AUDIO_MAIN_OUT, /* Logical resource to manage ALSA main out source */
+ RMS_CATEGORY_AUDIO_REMOTE_OUT = RI_CATEGORY_AUDIO_REMOTE_OUT, /* Logical resource to manage ALSA remote out source */
+ RMS_CATEGORY_AUDIO_SCART_OUT = RI_CATEGORY_AUDIO_SCART_OUT, /* Logical resource to manage ALSA scart out source */
+ RMS_CATEGORY_MM_PCM_OUT = RI_CATEGORY_MM_PCM_OUT, /* PCM out - used by mm-player */
+ RMS_CATEGORY_AUDIO_DECODER_SUB = RI_CATEGORY_AUDIO_DECODER_SUB, /* Sub Audio Decoder */
+ RMS_CATEGORY_AUDIO_DECODER_PRIMARY = RI_CATEGORY_AUDIO_DECODER_PRIMARY, /* Sub Audio Decoder */
+ RMS_CATEGORY_JPEG_DECODER = RI_CATEGORY_JPEG_DECODER, /* JPEG Decoder */
+ RMS_CATEGORY_SCALER_SUB = RI_CATEGORY_SCALER_SUB, /* Sub Scaler */
+ RMS_CATEGORY_EXT_VIDEO_SRC = RI_CATEGORY_EXT_VIDEO_SRC, /* Logical resource to manage video input path - used by player */
+ RMS_CATEGORY_EXT_AUDIO_SRC = RI_CATEGORY_EXT_AUDIO_SRC, /* Logical resource to manage audio input path - used by player */
+ RMS_CATEGORY_EXT_HDMI_SRC = RI_CATEGORY_EXT_HDMI_SRC, /* Logical resource to manage hdmi input path - used by player */
+ RMS_CATEGORY_VIDEO_DECODER_SUB = RI_CATEGORY_VIDEO_DECODER_SUB, /* Sub Video Decoder - MFD (Multi Format Decoder), FullHD */
+ RMS_CATEGORY_CAMERA = RI_CATEGORY_CAMERA, /* Logical resource to manage camera device */
+ RMS_CATEGORY_DEMUX_REC = RI_CATEGORY_DEMUX_REC, /* Demux for recording */
+ RMS_CATEGORY_TUNER_SUB = RI_CATEGORY_TUNER_SUB, /* Sub Tuner */
+ RMS_CATEGORY_MJPEG_DECODER = RI_CATEGORY_MJPEG_DECODER, /* MJPEG decoder */
+
+ RMS_CATEGORY_INPUT_SRC_DTV = RI_CATEGORY_INPUT_SRC_DTV,
+ RMS_CATEGORY_INPUT_SRC_ATV = RI_CATEGORY_INPUT_SRC_ATV,
+ RMS_CATEGORY_INPUT_SRC_HDMI = RI_CATEGORY_INPUT_SRC_HDMI,
+ RMS_CATEGORY_INPUT_SRC_COMP = RI_CATEGORY_INPUT_SRC_COMP,
+ RMS_CATEGORY_INPUT_SRC_AV = RI_CATEGORY_INPUT_SRC_AV,
+ RMS_CATEGORY_INPUT_SRC_SCART = RI_CATEGORY_INPUT_SRC_SCART,
+
+ RMS_CATEGORY_MIC = RI_CATEGORY_MIC, /* MIC */
+ RMS_CATEGORY_EXT_COMP_SRC = RI_CATEGORY_EXT_COMP_SRC,
+ RMS_CATEGORY_EXT_AV_SRC = RI_CATEGORY_EXT_AV_SRC,
+ RMS_CATEGORY_SW_DECODER = RI_CATEGORY_SW_DECODER,
+ RMS_CATEGORY_MMP_MEMORY_CLUSTER = RI_CATEGORY_MMP_MEMORY_CLUSTER,
+
+ RMS_CATEGORY_EXT_AUDIO_SRC_DVI = RI_CATEGORY_EXT_AUDIO_SRC_DVI, //LFD only
+ RMS_CATEGORY_EXT_AUDIO_SRC_HDMI = RI_CATEGORY_EXT_AUDIO_SRC_HDMI,//LFD only
+ RMS_CATEGORY_EXT_AUDIO_SRC_DP = RI_CATEGORY_EXT_AUDIO_SRC_DP, //LFD only, Diplay Port
+ RMS_CATEGORY_EXT_AUDIO_SRC_SBB = RI_CATEGORY_EXT_AUDIO_SRC_SBB, //LFD only, MagicInfo I
+ RMS_CATEGORY_EXT_AUDIO_SRC_OPS = RI_CATEGORY_EXT_AUDIO_SRC_OPS, //LFD only, PIM(Plug In Module)
+ RMS_CATEGORY_EXT_VIDEO_SRC_DVI = RI_CATEGORY_EXT_VIDEO_SRC_DVI, //LFD only
+ RMS_CATEGORY_EXT_VIDEO_SRC_HDMI = RI_CATEGORY_EXT_VIDEO_SRC_HDMI,//LFD only
+ RMS_CATEGORY_EXT_VIDEO_SRC_DP = RI_CATEGORY_EXT_VIDEO_SRC_DP, //LFD only, Diplay Port
+ RMS_CATEGORY_EXT_VIDEO_SRC_SBB = RI_CATEGORY_EXT_VIDEO_SRC_SBB, //LFD only, MagicInfo I
+ RMS_CATEGORY_EXT_VIDEO_SRC_OPS = RI_CATEGORY_EXT_VIDEO_SRC_OPS, //LFD only, PIM(Plug In Module)
+ RMS_CATEGORY_EXT_PC_SRC = RI_CATEGORY_EXT_PC_SRC,
+
+ RMS_CATEGORY_SCALER_BG = RI_CATEGORY_SCALER_BG,
+ RMS_CATEGORY_AUDIO_SUB_OUT = RI_CATEGORY_AUDIO_SUB_OUT,
+ RMS_CATEGORY_GRAPHIC_PLANE = RI_CATEGORY_GRAPHIC_PLANE,
+ RMS_CATEGORY_DISPLAY_OUT = RI_CATEGORY_DISPLAY_OUT,
+ RMS_CATEGORY_IMAGE_DECODER = RI_CATEGORY_IMAGE_DECODER,
+ RMS_CATEGORY_VIDEO_ENCODER_EXCLUSIVE = RI_CATEGORY_VIDEO_ENCODER_EXCLUSIVE,
+
+ RMS_CATEGORY_JPEG_DECODER_OPTION = RI_CATEGORY_JPEG_DECODER_OPTION,
+ RMS_CATEGORY_JPEG_DECODER_FHD = RI_CATEGORY_JPEG_DECODER_FHD,
+ RMS_CATEGORY_JPEG_DECODER_UHD = RI_CATEGORY_JPEG_DECODER_UHD,
+ RMS_CATEGORY_JPEG_DECODER_8K = RI_CATEGORY_JPEG_DECODER_8K,
+ RMS_CATEGORY_JPEG_DECODER_OPTION_MAX = (RMS_CATEGORY_JPEG_DECODER_8K + 1),
+
+ RMS_CATEGORY_MJPEG_DECODER_OPTION = RI_CATEGORY_MJPEG_DECODER_OPTION,
+ RMS_CATEGORY_MJPEG_DECODER_FHD = RI_CATEGORY_MJPEG_DECODER_FHD,
+ RMS_CATEGORY_MJPEG_DECODER_UHD = RI_CATEGORY_MJPEG_DECODER_UHD,
+ RMS_CATEGORY_MJPEG_DECODER_8K = RI_CATEGORY_MJPEG_DECODER_8K,
+ RMS_CATEGORY_MJPEG_DECODER_OPTION_MAX = (RMS_CATEGORY_MJPEG_DECODER_8K + 1),
+
+ RMS_CATEGORY_HEIC_DECODER_OPTION = RI_CATEGORY_HEIC_DECODER_OPTION,
+ RMS_CATEGORY_HEIC_DECODER = RI_CATEGORY_HEIC_DECODER,
+ RMS_CATEGORY_HEIC_DECODER_OPTION_MAX = (RMS_CATEGORY_HEIC_DECODER + 1),
+
+ RMS_CATEGORY_AUDIO_DECODER_OPTION = RI_CATEGORY_AUDIO_DECODER_OPTION, /**< Audio Decoder option min*/
+ RMS_CATEGORY_AUDIO_DECODER_ANY = RI_CATEGORY_AUDIO_DECODER_ANY, /**< Available audio Decoder will be allocated*/
+ RMS_CATEGORY_AUDIO_DECODER_NOT_SUPPORTED = RI_CATEGORY_AUDIO_DECODER_NOT_SUPPORTED, /**< Audio Decoder is not supported*/
+ RMS_CATEGORY_AUDIO_DECODER_MPEG = RI_CATEGORY_AUDIO_DECODER_MPEG,
+ RMS_CATEGORY_AUDIO_DECODER_AC3 = RI_CATEGORY_AUDIO_DECODER_AC3,
+ RMS_CATEGORY_AUDIO_DECODER_E_AC3 = RI_CATEGORY_AUDIO_DECODER_E_AC3,
+ RMS_CATEGORY_AUDIO_DECODER_TRUEHD = RI_CATEGORY_AUDIO_DECODER_TRUEHD,
+ RMS_CATEGORY_AUDIO_DECODER_AC4 = RI_CATEGORY_AUDIO_DECODER_AC4,
+ RMS_CATEGORY_AUDIO_DECODER_VORBIS = RI_CATEGORY_AUDIO_DECODER_VORBIS,
+ RMS_CATEGORY_AUDIO_DECODER_G2COOK = RI_CATEGORY_AUDIO_DECODER_G2COOK,
+ RMS_CATEGORY_AUDIO_DECODER_AAC = RI_CATEGORY_AUDIO_DECODER_AAC,
+ RMS_CATEGORY_AUDIO_DECODER_HE_AAC = RI_CATEGORY_AUDIO_DECODER_HE_AAC,
+ RMS_CATEGORY_AUDIO_DECODER_WMA = RI_CATEGORY_AUDIO_DECODER_WMA,
+ RMS_CATEGORY_AUDIO_DECODER_ADPCM = RI_CATEGORY_AUDIO_DECODER_ADPCM,
+ RMS_CATEGORY_AUDIO_DECODER_MPEG_H = RI_CATEGORY_AUDIO_DECODER_MPEG_H,
+ RMS_CATEGORY_AUDIO_DECODER_OPUS = RI_CATEGORY_AUDIO_DECODER_OPUS,
+ RMS_CATEGORY_AUDIO_DECODER_PCM = RI_CATEGORY_AUDIO_DECODER_PCM,
+ RMS_CATEGORY_AUDIO_DECODER_OPTION_MAX = (RMS_CATEGORY_AUDIO_DECODER_PCM + 1),
+
+ RMS_CATEGORY_SCALER_OPTION = RI_CATEGORY_SCALER_OPTION,
+ RMS_CATEGORY_SCALER_MULTIVIEW = RI_CATEGORY_SCALER_MULTIVIEW,
+ RMS_CATEGORY_SCALER_SUB2 = RI_CATEGORY_SCALER_SUB2,
+ RMS_CATEGORY_SCALER_SUB3 = RI_CATEGORY_SCALER_SUB3,
+ RMS_CATEGORY_SCALER_VR360_DETILED = RI_CATEGORY_SCALER_VR360_DETILED,
+ RMS_CATEGORY_SCALER_VR360_NATIVE_OUT = RI_CATEGORY_SCALER_VR360_NATIVE_OUT,
+ RMS_CATEGORY_SCALER_INTERLACED = RI_CATEGORY_SCALER_INTERLACED,
+ RMS_CATEGORY_SCALER_OPTION_MAX = (RMS_CATEGORY_SCALER_INTERLACED + 1),
+
+ RMS_CATEGORY_VIDEO_DECODER_OPTION = RI_CATEGORY_VIDEO_DECODER_OPTION,
+ RMS_CATEGORY_VIDEO_DECODER_UHD = RI_CATEGORY_VIDEO_DECODER_UHD, /* Video Decoder, UHD */
+ RMS_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_H264_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H264_UHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_H264_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_H264_UHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_420_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_420_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_420_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_420_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_422_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_422_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_422_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_422_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_420_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_420_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_420_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_420_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_422_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_422_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_422_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_422_60P,
+ RMS_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_UHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_UHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_60P,
+
+ //VR360
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_420_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_420_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_420_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_420_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_420_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_420_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_420_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_420_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_422_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_422_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_422_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_422_60P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_422_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_422_30P,
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_422_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_422_60P,
+ RMS_CATEGORY_VIDEO_DECODER_H264_VR360_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H264_VR360_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_H264_VR360_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_H264_VR360_FHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_H264_VR360_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H264_VR360_UHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_H264_VR360_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_H264_VR360_UHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_8BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_8BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_30P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_60P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_420_30P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_420_30P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_420_60P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_420_60P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_420_30P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_420_30P,
+ RMS_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_420_60P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_420_60P,
+
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_SHVC_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_SHVC_8BIT_30P, /**< video decoder for hevc */
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_SHVC_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_SHVC_8BIT_60P, /**< video decoder for hevc */
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_SHVC_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_SHVC_10BIT_30P, /**< video decoder for hevc */
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_SHVC_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_SHVC_10BIT_60P, /**< video decoder for hevc */
+
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_8K_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_8K_8BIT_30P, /**< 1080: video decoder for hevc 8k */
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_8K_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_8K_8BIT_60P, /**< 1081: video decoder for hevc 8k */
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_30P, /**< 1082: video decoder for hevc 8k */
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_60P, /**< 1083: video decoder for hevc 8k */
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_420_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_420_30P, /**< 1084: video decoder for hevc 8k */
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_420_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_420_60P, /**< 1085: video decoder for hevc 8k */
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_120P, /**< 1086: video decoder for hevc */
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_120P, /**< 1087: video decoder for hevc */
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_420_120P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_420_120P, /**< 1088: video decoder for hevc */
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_422_120P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_422_120P, /**< 1089: video decoder for hevc */
+
+ RMS_CATEGORY_VIDEO_DECODER_AV1_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_FHD_8BIT_30P, /**< 1090: video decoder for av1 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_FHD_8BIT_60P, /**< 1091: video decoder for av1 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_30P, /**< 1092: video decoder for av1 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_60P, /**< 1093: video decoder for av1 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_30P, /**< 1094: video decoder for av1 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_60P, /**< 1095: video decoder for av1 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_30P, /**< 1096: video decoder for av1 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_60P, /**< 1097: video decoder for av1 */
+
+ RMS_CATEGORY_VIDEO_DECODER_AV1_8K_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_8K_8BIT_30P, /**< 1098: video decoder for av1 8k */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_8K_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_8K_8BIT_60P, /**< 1099: video decoder for av1 8k */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_8K_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_8K_10BIT_30P, /**< 1100: video decoder for av1 8k */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_8K_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_8K_10BIT_60P, /**< 1101: video decoder for av1 8k */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_8BIT_30P, /**< 1102: video decoder for vp9 vr360 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_8BIT_60P, /**< 1103: video decoder for vp9 vr360 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_10BIT_30P,/**< 1104: video decoder for vp9 vr360 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_10BIT_60P,/**< 1105: video decoder for vp9 vr360 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_8BIT_30P, /**< 1106: video decoder for vp9 vr360 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_8BIT_60P, /**< 1107: video decoder for vp9 vr360 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_10BIT_30P,/**< 1108: video decoder for vp9 vr360 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_10BIT_60P,/**< 1109: video decoder for vp9 vr360 */
+
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_120P, /**< 1110: video decoder for hevc */
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_120P, /**< 1111: video decoder for hevc */
+ RMS_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_422_120P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_422_120P, /**< 1112: video decoder for hevc */
+ RMS_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_120P, /**< 1113: video decoder for h264 */
+ RMS_CATEGORY_VIDEO_DECODER_H264_HD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H264_HD_8BIT_30P, /**< 1114: video decoder for h264 */
+ RMS_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_120P, /**< 1115: video decoder for mpeg1 */
+ RMS_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_120P, /**< 1116: video decoder for mpeg2 */
+ RMS_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_120P, /**< 1117: video decoder for mpeg4 */
+ RMS_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_120P, /**< 1118: video decoder for h263 */
+ RMS_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_120P, /**< 1119: video decoder for vp8 */
+ RMS_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_120P, /**< 1120: video decoder for vp8 */
+ RMS_CATEGORY_VIDEO_DECODER_VP9_FHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_VP9_FHD_10BIT_120P, /**< 1121: video decoder for vp8 */
+ RMS_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_120P, /**< 1122: video decoder for rv */
+ RMS_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_120P, /**< 1123: video decoder for wmv9 */
+ RMS_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_120P, /**< 1124: video decoder for avs */
+ RMS_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_120P, /**< 1125: video decoder for avs+ */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_AV1_FHD_8BIT_120P, /**< 1126: video decoder for av1 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_120P, /**< 1127: video decoder for av1 */
+
+ RMS_CATEGORY_VIDEO_DECODER_AVS2_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS2_FHD_8BIT_30P, /**< 1128: video decoder for avs2 */
+ RMS_CATEGORY_VIDEO_DECODER_AVS2_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS2_FHD_8BIT_60P, /**< 1129: video decoder for avs2 */
+ RMS_CATEGORY_VIDEO_DECODER_AVS2_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_AVS2_FHD_8BIT_120P, /**< 1130: video decoder for avs2 */
+ RMS_CATEGORY_VIDEO_DECODER_AVS2_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS2_FHD_10BIT_30P, /**< 1131: video decoder for avs2 */
+ RMS_CATEGORY_VIDEO_DECODER_AVS2_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS2_FHD_10BIT_60P, /**< 1132: video decoder for avs2 */
+ RMS_CATEGORY_VIDEO_DECODER_AVS2_FHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_AVS2_FHD_10BIT_120P, /**< 1133: video decoder for avs2 */
+
+ RMS_CATEGORY_VIDEO_DECODER_AVS2_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS2_UHD_8BIT_30P, /**< 1134: video decoder for avs2 */
+ RMS_CATEGORY_VIDEO_DECODER_AVS2_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS2_UHD_8BIT_60P, /**< 1135: video decoder for avs2 */
+ RMS_CATEGORY_VIDEO_DECODER_AVS2_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS2_UHD_10BIT_30P, /**< 1136: video decoder for avs2 */
+ RMS_CATEGORY_VIDEO_DECODER_AVS2_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS2_UHD_10BIT_60P, /**< 1137: video decoder for avs2 */
+
+ RMS_CATEGORY_VIDEO_DECODER_VP9_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_FHD_10BIT_30P, /**< 1138: video decoder for vp9 */
+ RMS_CATEGORY_VIDEO_DECODER_VP9_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_FHD_10BIT_60P, /**< 1139: video decoder for vp9 */
+ RMS_CATEGORY_VIDEO_DECODER_VP9_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_UHD_10BIT_30P, /**< 1140: video decoder for vp9 */
+ RMS_CATEGORY_VIDEO_DECODER_VP9_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_UHD_10BIT_60P, /**< 1141: video decoder for vp9 */
+
+ RMS_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_120P, /**< 1142: video decoder for av1 */
+ RMS_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_120P, /**< 1143: video decoder for av1 */
+ RMS_CATEGORY_VIDEO_DECODER_VP8_qHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP8_qHD_8BIT_30P, /**< 1144: video decoder for vp8 */
+ RMS_CATEGORY_VIDEO_DECODER_H264_FHD_N_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H264_FHD_N_8BIT_30P, /**< 1145: video decoder for h264 */
+ RMS_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_MV = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_MV, /**< 1146: video decoder for h264 multiview scenario */
+ RMS_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_MV = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_MV, /**< 1147: video decoder for h264 multiview scenario */
+ RMS_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_PORTRAIT = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_PORTRAIT, /**< 1148: video decoder for h264 portrait */
+ RMS_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_PORTRAIT = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_PORTRAIT, /**< 1149: video decoder for h264 portrait */
+ RMS_CATEGORY_VIDEO_DECODER_OPTION_MAX = (RMS_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_PORTRAIT + 1)
+} rms_rsc_category_e;
+
+typedef enum {
+ RMS_DEVICE_NONE = RI_DEVICE_UNDEFINED,
+ RMS_DEVICE_AUDIO_MAIN_OUT = RI_DEVICE_AUDIO_MAIN_OUT,
+ RMS_DEVICE_AUDIO_REMOTE_OUT = RI_DEVICE_AUDIO_REMOTE_OUT,
+ RMS_DEVICE_AUDIO_SCART_OUT = RI_DEVICE_AUDIO_SCART_OUT,
+ RMS_DEVICE_AUDIO_EVENT_COMPRESS = RI_DEVICE_AUDIO_EVENT_COMPRESS,
+ RMS_DEVICE_MM_PCM_OUT = RI_DEVICE_MM_PCM_OUT,
+ RMS_DEVICE_JPEG_DECODER = RI_DEVICE_JPEG_DECODER,
+ RMS_DEVICE_DEMUX0 = RI_DEVICE_DEMUX0,
+ RMS_DEVICE_DEMUX1 = RI_DEVICE_DEMUX1,
+ RMS_DEVICE_DEMUX2 = RI_DEVICE_DEMUX2,
+ RMS_DEVICE_AUDIO_ENCODER = RI_DEVICE_AUDIO_ENCODER,
+ RMS_DEVICE_VIDEO_ENCODER = RI_DEVICE_VIDEO_ENCODER,
+ RMS_DEVICE_SCALER = RI_DEVICE_SCALER,
+ RMS_DEVICE_EXT_VIDEO_SRC = RI_DEVICE_EXT_VIDEO_SRC,
+ RMS_DEVICE_EXT_AUDIO_SRC = RI_DEVICE_EXT_AUDIO_SRC,
+ RMS_DEVICE_EXT_HDMI_SRC = RI_DEVICE_EXT_HDMI_SRC,
+ RMS_DEVICE_CAMERA = RI_DEVICE_CAMERA,
+ RMS_DEVICE_TUNER = RI_DEVICE_TUNER,
+ RMS_DEVICE_TUNER_SUB = RI_DEVICE_TUNER_SUB,
+ RMS_DEVICE_SCALER_SUB = RI_DEVICE_SCALER_SUB,
+ RMS_DEVICE_AUDIO_DECODER = RI_DEVICE_AUDIO_DECODER,
+ RMS_DEVICE_AUDIO_DECODER_SUB = RI_DEVICE_AUDIO_DECODER_SUB,
+ RMS_DEVICE_AUDIO_DECODER_PRIMARY = RI_DEVICE_AUDIO_DECODER_PRIMARY,
+ RMS_DEVICE_VIDEO_DECODER_MAIN = RI_DEVICE_VIDEO_DECODER_MAIN,
+ RMS_DEVICE_VIDEO_DECODER_SUB = RI_DEVICE_VIDEO_DECODER_SUB,
+ RMS_DEVICE_VIDEO_DECODER_UDDEC = RI_DEVICE_VIDEO_DECODER_UDDEC,
+ RMS_DEVICE_VIDEO_DECODER_UDHEVC = RI_DEVICE_VIDEO_DECODER_UDHEVC,
+ RMS_DEVICE_AUDIO_SPDIF_ES_OUTPUT = RI_DEVICE_AUDIO_SPDIF_ES_OUTPUT,
+ RMS_DEVICE_MIC = RI_DEVICE_MIC,
+ RMS_DEVICE_EXT_COMP_SRC = RI_DEVICE_EXT_COMP_SRC,
+ RMS_DEVICE_EXT_AV_SRC = RI_DEVICE_EXT_AV_SRC,
+ RMS_DEVICE_MJPEG_DECODER = RI_DEVICE_MJPEG_DECODER,
+ RMS_DEVICE_JPEG_DECODER_UHD = RI_DEVICE_JPEG_DECODER_UHD,
+ RMS_DEVICE_MJPEG_DECODER_UHD = RI_DEVICE_MJPEG_DECODER_UHD,
+ RMS_DEVICE_SW_DECODER = RI_DEVICE_SW_DECODER,
+ RMS_DEVICE_DEMUX3 = RI_DEVICE_DEMUX3,
+ RMS_DEVICE_MMP_MEMORY_CLUSTER1 = RI_DEVICE_MMP_MEMORY_CLUSTER1,
+ RMS_DEVICE_MMP_MEMORY_CLUSTER2 = RI_DEVICE_MMP_MEMORY_CLUSTER2,
+ RMS_DEVICE_MMP_MEMORY_CLUSTER3 = RI_DEVICE_MMP_MEMORY_CLUSTER3,
+ RMS_DEVICE_MMP_MEMORY_CLUSTER4 = RI_DEVICE_MMP_MEMORY_CLUSTER4,
+ RMS_DEVICE_MMP_MEMORY_CLUSTER5 = RI_DEVICE_MMP_MEMORY_CLUSTER5,
+ RMS_DEVICE_EXT_AUDIO_SRC_DVI = RI_DEVICE_EXT_AUDIO_SRC_DVI, //LFD only
+ RMS_DEVICE_EXT_AUDIO_SRC_HDMI = RI_DEVICE_EXT_AUDIO_SRC_HDMI,//LFD only
+ RMS_DEVICE_EXT_AUDIO_SRC_DP = RI_DEVICE_EXT_AUDIO_SRC_DP, //LFD only, Diplay Port
+ RMS_DEVICE_EXT_AUDIO_SRC_SBB = RI_DEVICE_EXT_AUDIO_SRC_SBB, //LFD only, MagicInfo I
+ RMS_DEVICE_EXT_AUDIO_SRC_OPS = RI_DEVICE_EXT_AUDIO_SRC_OPS, //LFD only, PIM(Plug In Module)
+ RMS_DEVICE_EXT_VIDEO_SRC_DVI = RI_DEVICE_EXT_VIDEO_SRC_DVI, //LFD only
+ RMS_DEVICE_EXT_VIDEO_SRC_HDMI = RI_DEVICE_EXT_VIDEO_SRC_HDMI,//LFD only
+ RMS_DEVICE_EXT_VIDEO_SRC_DP = RI_DEVICE_EXT_VIDEO_SRC_DP, //LFD only, Diplay Port
+ RMS_DEVICE_EXT_VIDEO_SRC_SBB = RI_DEVICE_EXT_VIDEO_SRC_SBB, //LFD only, MagicInfo I
+ RMS_DEVICE_EXT_VIDEO_SRC_OPS = RI_DEVICE_EXT_VIDEO_SRC_OPS, //LFD only, PIM(Plug In Module)
+ RMS_DEVICE_VIDEO_DECODER_DVDE0 = RI_DEVICE_VIDEO_DECODER_DVDE0,
+ RMS_DEVICE_VIDEO_DECODER_DVDE1 = RI_DEVICE_VIDEO_DECODER_DVDE1,
+ RMS_DEVICE_VIDEO_DECODER_HEN = RI_DEVICE_VIDEO_DECODER_HEN,
+ RMS_DEVICE_DEMUX4 = RI_DEVICE_DEMUX4,
+ RMS_DEVICE_DEMUX5 = RI_DEVICE_DEMUX5,
+ RMS_DEVICE_DEMUX6 = RI_DEVICE_DEMUX6,
+ RMS_DEVICE_DEMUX7 = RI_DEVICE_DEMUX7,
+ RMS_DEVICE_EXT_PC_SRC = RI_DEVICE_EXT_PC_SRC,
+ RMS_DEVICE_VIDEO_DECODER_VR360DEC = RI_DEVICE_VIDEO_DECODER_VR360DEC,
+ RMS_DEVICE_VIDEO_DECODER_HEVC_8K = RI_DEVICE_VIDEO_DECODER_HEVC_8K,
+ RMS_DEVICE_AUDIO_SUB_OUT = RI_DEVICE_AUDIO_SUB_OUT,
+ RMS_DEVICE_MJPEG_DECODER_SUB = RI_DEVICE_MJPEG_DECODER_SUB,
+ RMS_DEVICE_GRAPHIC_PLANE = RI_DEVICE_GRAPHIC_PLANE,
+ RMS_DEVICE_VIDEO_DECODER_DVDE2 = RI_DEVICE_VIDEO_DECODER_DVDE2,
+ RMS_DEVICE_VIDEO_DECODER_DVDE3 = RI_DEVICE_VIDEO_DECODER_DVDE3,
+ RMS_DEVICE_HEIC_DECODER = RI_DEVICE_HEIC_DECODER,
+ RMS_DEVICE_VIDEO_DECODER_DVDE4 = RI_DEVICE_VIDEO_DECODER_DVDE4,
+ RMS_DEVICE_VIDEO_DECODER_DVDE5 = RI_DEVICE_VIDEO_DECODER_DVDE5,
+ RMS_DEVICE_VIDEO_DECODER_DVDE6 = RI_DEVICE_VIDEO_DECODER_DVDE6,
+ RMS_DEVICE_VIDEO_DECODER_DVDE7 = RI_DEVICE_VIDEO_DECODER_DVDE7,
+ RMS_DEVICE_VIDEO_DECODER_OVDE = RI_DEVICE_VIDEO_DECODER_OVDE,
+ RMS_DEVICE_SCALER_SUB2 = RI_DEVICE_SCALER_SUB2,
+ RMS_DEVICE_SCALER_SUB3 = RI_DEVICE_SCALER_SUB3,
+ RMS_DEVICE_VIDEO_DECODER_MFC2 = RI_DEVICE_VIDEO_DECODER_MFC2,
+ RMS_DEVICE_VIDEO_DECODER_MFC3 = RI_DEVICE_VIDEO_DECODER_MFC3,
+ RMS_DEVICE_VIDEO_DECODER_MFC4 = RI_DEVICE_VIDEO_DECODER_MFC4,
+ RMS_DEVICE_JPEG_DECODER_SUB = RI_DEVICE_JPEG_DECODER_SUB,
+ RMS_DEVICE_VIDEO_ENCODER_EXCLUSIVE = RI_DEVICE_VIDEO_ENCODER_EXCLUSIVE
+} rms_device_e;
+
+typedef enum {
+ RMS_STATE_PASSIVE,
+ RMS_STATE_SHARABLE,
+ RMS_STATE_EXCLUSIVE,
+ RMS_STATE_EXCLUSIVE_CONDITIONAL, //no need to request for deallocating resource in case that resource is used by other consumer
+ RMS_STATE_EXCLUSIVE_AUTO,
+ RMS_STATE_EXCLUSIVE_PREFERENCE,
+} rms_requests_resource_state_e;
+
+typedef enum {
+ RMS_INTERNAL_STATE_FREE,
+ RMS_INTERNAL_STATE_SHARABLE,
+ RMS_INTERNAL_STATE_SHARED,
+ RMS_INTERNAL_STATE_EXCLUSIVE,
+ RMS_INTERNAL_STATE_ERROR
+} rms_resource_internal_state_e;
+
+typedef enum {
+ RMS_CONFLICT_NORMAL,
+ RMS_CONFLICT_UHD_RESOURCE_REQUEST
+} rms_resource_conflict_msg_e;
+
+typedef struct {
+ int device_id;
+ rms_requests_resource_state_e requested_state;
+} rms_device_s;
+
+typedef struct {
+ int resources_num;
+ rms_device_s devices[RMS_MAX_DEVICE];
+} rms_requests_device_s;
+
+typedef struct {
+ int device_id;
+ const char *device_path;
+} rms_return_device_info_s;
+
+typedef struct {
+ int result;
+ int error_type;
+ int resources_num;
+ int *device_ids;
+ rms_return_device_info_s *devices;
+} rms_return_device_s;
+
+typedef struct {
+ int main;
+ int sub;
+} rms_priority_s;
+
+typedef struct {
+ int consumer_id;
+ long process_id;
+ rms_priority_s priority;
+ int app_pid;
+ char app_id[RMS_APPID_LENGTH];
+} rms_consumer_s;
+
+typedef struct {
+ rms_rsc_category_e category_id;
+ int device_id;
+ int virtual_id;
+} rms_conflicted_resource_info_s;
+
+typedef struct {
+ int consumer_id;
+ long process_id;
+ int n_conflicted; //needs to be released
+ rms_conflicted_resource_info_s *conflicted_resources;
+ int resources_num; //The number of resources consumer is using
+} rms_consumer_tobe_returned_s;
+
+typedef struct {
+ int ret_quantity; //num of consumer who needs to release resources
+ rms_consumer_tobe_returned_s *consumer_info;
+} consumer_reclaim_s;
+
+typedef enum {
+ RMS_OK, // success
+ RMS_ERROR, // error
+ RMS_ERROR_TAKE_RESOURCE_FROM_OTHER_CONSUMER, // other consumer who has low or same priority is using resource
+ RMS_OK_UHD_RESOURCE_CONFLICT, // UHD device is conflicted
+ RMS_ERROR_HIGH_PRIORITY_CONSUMER_IS_USING, // other consumer who has high priority is using resource
+} rms_return_code_e;
+
+// request type from client
+typedef enum {
+ RMS_REQUEST_DATA_TYPE_ALL = 0,
+ RMS_REQUEST_DATA_TYPE_COMMON = 1,
+ RMS_REQUEST_DATA_TYPE_REGISTER = (0x2 << 29)
+} rms_request_data_type;
+
+// response type to client
+typedef enum {
+ RMS_RESPONSE_DATA_TYPE_COMMON = 1,
+ RMS_RESPONSE_DATA_TYPE_REGISTER = (0x2 << 29)
+} rms_response_data_type;
+
+typedef enum {
+ RMS_REQUEST_REGISTER,
+ RMS_REQUEST_UNREGISTER,
+ RMS_REQUEST_ALLOCATE_RESOURCE,
+ RMS_REQUEST_RELEASE_RESOURCES,
+ RMS_REQUEST_QUERY,
+ RMS_REQUEST_SET_PRIORITY,
+ RMS_REQUEST_SET_APPID,
+ RMS_REQUEST_MAX,
+} rms_request_type_e;
+
+typedef enum {
+ RMS_RESPONSE_REGISTER,
+ RMS_RESPONSE_UNREGISTER,
+ RMS_RESPONSE_ALLOCATE_RESOURCE,
+ RMS_RESPONSE_RELEASE_RESOURCES,
+ RMS_RESPONSE_QUERY,
+ RMS_RESPONSE_SET_PRIORITY,
+ RMS_RESPONSE_SET_APPID,
+ RMS_RESPONSE_MAX,
+} rms_response_type_e;
+
+typedef enum {
+ RMS_ERR_TYPE_TERMINATED_PROCESS = -1,
+ RMS_ERR_TYPE_NONE = 0,
+ RMS_ERR_TYPE_REQUEST_OF_INVISIBLE_PROCESS = 1,
+ RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS,
+ RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE,
+ RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST,
+ RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER,
+ RMS_ERR_TYPE_RESOURCE_EXHAUSTED,
+ RMS_ERR_TYPE_INVALID_REQUEST,
+ RMS_ERR_TYPE_NOT_PERMITTED
+} rms_error_type_e;
+
+#define RMS_REQUEST_RESOURCE_MAX 10
+
+typedef struct {
+ long data_type;
+ int type;
+ int handle;
+ int pid;
+ int request_num;
+ int resource[RMS_REQUEST_RESOURCE_MAX];
+ int resource_option[RMS_REQUEST_RESOURCE_MAX];
+ int state[RMS_REQUEST_RESOURCE_MAX];
+ int main_priority;
+ int sub_priority;
+ int app_pid;
+ char app_id[RMS_APPID_LENGTH];
+ int device_id[RMS_REQUEST_RESOURCE_MAX];
+ int sub_type;
+ unsigned long time;
+} rms_msg_request;
+
+typedef struct {
+ long data_type;
+ rms_response_type_e type;
+ int result;
+ int resource_num;
+ int resource[RMS_REQUEST_RESOURCE_MAX];
+ rms_resource_internal_state_e resource_state[RMS_REQUEST_RESOURCE_MAX];
+ int is_available;
+ int handle;
+ rms_error_type_e error_type;
+ int pid;
+} rms_msg_response;
+
+typedef enum {
+ RMS_HANDLE_NOT_AVAILABLE = -1,
+ RMS_HANDLE_FREE = 0,
+ RMS_HANDLE_USE = 1
+} rms_handle_used;
+
+typedef struct {
+ int pid;
+ int is_used;
+ int handle;
+ int main_priority;
+ int sub_priority;
+ int app_pid;
+ char app_id[RMS_APPID_LENGTH];
+ char process_name[RMS_NAME_BUF_SIZE];
+} rms_register_handle_s;
+
+/**
+ * @enum rm_emergency_error_e
+ * @brief these values are used to handle emergency
+ *
+ */
+
+typedef enum {
+ RMS_EMERGENCY_UNKNOWN = -1,
+ RMS_EMERGENCY_CONSUMER_NOT_RESPONDING = 0
+} rms_emergency_error_e;
+
+typedef enum {
+ RMS_DEVICE_OPT_NONE = 0,
+ RMS_DEVICE_OPT_MAIN = (0x1 << 29),
+ RMS_DEVICE_OPT_SUB = (0x1 << 28),
+} rms_device_option_e;
+
+typedef enum {
+ RMS_FORCE_TO_MAIN = (0x1 << 27),
+ RMS_FORCE_TO_SUB = (0x1 << 26)
+} rms_device_request_e;
+
+typedef enum {
+ RMS_MIXING_MODE_DEFAULT = RI_MIXING_MODE_DEFAULT,
+ RMS_MIXING_MODE_MULTIVIEW = RI_MIXING_MODE_MULTIVIEW,
+ RMS_MIXING_MODE_INTERACTION_SOUND = RI_MIXING_MODE_INTERACTION_SOUND
+} rms_mixing_mode_e;
+
+typedef enum {
+ RMS_VIDEO_DEC_OPT_AI = (0x1 << 25)
+} rms_video_dec_option_e;
+
+typedef enum {
+ RMS_MIXING_OPT_DEFAULT = 0,
+ RMS_MIXING_OPT_MULTIVIEW = RMS_MIXING_OPT_DEFAULT,
+ RMS_MIXING_OPT_INTERACTION_SOUND = (0x1 << 24)
+} rms_mixing_option_e;
+
+typedef struct {
+ int cid;
+ rms_requests_resource_state_e state;
+ int option; //main, sub
+ int device_id;
+ rms_priority_s priority;
+ char app_id[RMS_APPID_LENGTH];
+} rms_allocate_request_s;
+
+typedef struct {
+ rms_return_code_e result;
+ rms_error_type_e reason;
+} rms_allocate_result_s;
+
+typedef enum {
+ RMS_QUERY_NONE,
+ RMS_QUERY_ALLOCATION,
+ RMS_QUERY_TERMINATE,
+ RMS_QUERY_ACTIVE_DECS
+} query_type_e;
+
+typedef enum {
+ RMS_RSC_COLLECTION_MAIN = 0,
+ RMS_RSC_COLLECTION_SUB,
+ RMS_RSC_COLLECTION_ACTIVE_VIDEO_DECODER
+} _rsc_collection_e;
+
+typedef enum {
+ RMS_AUDIO_OUT_NONE = 0,
+ RMS_AUDIO_OUT_MAIN = 0x1,
+ RMS_AUDIO_OUT_SUB = 0x2,
+} rms_audio_out_e;
+
+typedef enum {
+ RMS_CATEGORY_CLASS_NORMAL = 0,
+ RMS_CATEGORY_CLASS_N_DECODING = 100
+} rms_category_class_e;
+
+enum class ResourceType {
+ VIDEO_SCALER
+};
+
+#define RM_DBUS_BUS_NAME "rscmgr.resource"
+#define RM_DBUS_INTERFACE_NAME "rscmgr.resource"
+#define RM_DBUS_OBJ_PATH "/rscmgr/resource"
+
+#endif //__RMS_TYPE_H__
--- /dev/null
+[Unit]
+Description=service for resource manager
+DefaultDependencies=no
+
+[Service]
+Type=simple
+Environment=LD_USE_LOAD_BIAS=1
+ExecStartPre=/usr/bin/gen_rm_msgq
+ExecStart=/usr/bin/rscmgr-service
+Restart=always
+MemoryMax=10M
+RestartSec=0
--- /dev/null
+Name: rscmgr-service
+Summary: Daemon for resource manager
+Version: 0.1
+Release: 1
+Group: Multimedia/Libraries
+License: Apache-2.0
+Source0: %{name}-%{version}.tar.gz
+Source1: rscmgr-service.service
+BuildRequires: cmake >= 2.8.12
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(gio-2.0)
+BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(resource-information)
+BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(aul)
+BuildRequires: python
+BuildRequires: python-xml
+BuildRequires: pkgconfig(libtzplatform-config)
+BuildRequires: pkgconfig(ttrace)
+BuildRequires: pkgconfig(syspopup)
+BuildRequires: pkgconfig(syspopup-caller)
+BuildRequires: pkgconfig(wayland-client)
+
+%description
+This package provides service for vconf key usage
+
+%package devel
+Summary: The development package for daemon
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+The development package for vconf daemon
+
+%prep
+%setup -q
+
+%build
+export CFLAGS="$CFLAGS %{?_vd_cflags}"
+export CXXFLAGS="$CXXFLAGS %{?__vd_cxxflags}"
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+cmake . \
+ -DPACKAGE_NAME=%{name} \
+ -DINCLUDEDIR=%{_includedir} \
+ -DVERSION=%{version} \
+ -DBINDIR=%{TZ_SYS_BIN} \
+ -DMAJORVERSION=%{MAJORVER} \
+ -DLIBDIR=%{_libdir}
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+mkdir -p %{buildroot}%{_unitdir}/basic.target.wants
+mkdir -p %{buildroot}%{_sbindir}
+install -m 0644 %SOURCE1 %{buildroot}%{_unitdir}/rscmgr-service.service
+%install_service basic.target.wants rscmgr-service.service
+ln -sf ../rscmgr-service.service %{buildroot}%{_unitdir}/basic.target.wants/
+
+%clean
+rm -rf %{buildroot}
+
+%post
+
+%{TZ_SYS_BIN}/chsmack -e "System::Run" %{TZ_SYS_BIN}/gen_rm_msgq
+
+%files
+%manifest rscmgr-service.manifest
+%license LICENSE.APLv2
+%defattr(-,root,root,-)
+%{TZ_SYS_BIN}/rscmgr-service
+%{TZ_SYS_BIN}/gen_rm_msgq
+%{_unitdir}/rscmgr-service.service
+%{_unitdir}/basic.target.wants/rscmgr-service.service
+
+%files devel
+%defattr(-,root,root,-)
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <rms_debug.h>\r
+#include <CAsyncQueue.h>\r
+\r
+CAsyncQueue::CAsyncQueue(void)\r
+{\r
+ queue = g_async_queue_new();\r
+}\r
+\r
+CAsyncQueue::CAsyncQueue(destoryNotify destory_cb)\r
+{\r
+ queue = g_async_queue_new_full(destory_cb);\r
+}\r
+\r
+CAsyncQueue::~CAsyncQueue(void)\r
+{\r
+ g_async_queue_unref(queue);\r
+}\r
+\r
+void CAsyncQueue::push(void *data)\r
+{\r
+ g_async_queue_push(queue, data);\r
+}\r
+\r
+void CAsyncQueue::push(CAsyncQueue *src_queue)\r
+{\r
+ if (src_queue->length() <= 0)\r
+ return;\r
+\r
+ SERVER_INFO("push given queue (%d)", src_queue->length());\r
+\r
+ g_async_queue_lock(queue);\r
+\r
+ while (src_queue->length() > 0) {\r
+ g_async_queue_push_unlocked(queue, src_queue->pop());\r
+ }\r
+\r
+ g_async_queue_unlock(queue);\r
+}\r
+\r
+void CAsyncQueue::push_front(void *data)\r
+{\r
+ g_async_queue_push_front(queue, data);\r
+}\r
+\r
+void CAsyncQueue::push_front(CAsyncQueue *src_queue)\r
+{\r
+ if (src_queue->length() <= 0)\r
+ return;\r
+\r
+ SERVER_INFO("push_front given queue (%d)", src_queue->length());\r
+\r
+ g_async_queue_lock(queue);\r
+\r
+ while (src_queue->length() > 0) {\r
+ g_async_queue_push_front_unlocked(queue, src_queue->pop());\r
+ }\r
+\r
+ g_async_queue_unlock(queue);\r
+}\r
+\r
+void *CAsyncQueue::pop(void)\r
+{\r
+ return g_async_queue_pop(queue);\r
+}\r
+\r
+void *CAsyncQueue::pop(unsigned int timeout_ms)\r
+{\r
+ guint64 timeout_us = (guint64)((guint64) timeout_ms * 1000);\r
+\r
+ return g_async_queue_timeout_pop(queue, timeout_us);\r
+}\r
+\r
+int CAsyncQueue::length(void)\r
+{\r
+ return g_async_queue_length(queue);\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <CCallback.h>\r
+\r
+#include <rms_debug.h>\r
+#include <rms_type.h>\r
+#include <CDebugUtils.h>\r
+\r
+#include <errno.h>\r
+#include <sys/stat.h>\r
+#include <stdio.h>\r
+#include <fcntl.h>\r
+#include <poll.h>\r
+#include <unistd.h>\r
+#include <system_info.h>\r
+\r
+#define CB_TIMEOUT_3_SEC_IN_MS 3000\r
+#define CB_TIMEOUT_10_SEC_IN_MS 10000\r
+\r
+#define RMS_IS_DEBUG_IMAGE (access("/etc/debug", F_OK) == 0)\r
+\r
+unsigned int CCallback::GetTimeout(void)\r
+{\r
+ return (RMS_IS_DEBUG_IMAGE) ? CB_TIMEOUT_10_SEC_IN_MS : CB_TIMEOUT_3_SEC_IN_MS;\r
+}\r
+\r
+void CCallback::InitCallback(void)\r
+{\r
+ const char *cb_path = "/run/rsc_mgr";\r
+ mode_t dir_mode = 0666 | 0111;\r
+\r
+ if (mkdir(cb_path, dir_mode) !=0) {\r
+ SERVER_ERR("failed to create cb directory (%d)", errno);\r
+ return;\r
+ }\r
+\r
+ chmod(cb_path, dir_mode);\r
+}\r
+\r
+int CCallback::SendCallbackMessage(int cid, int pid, void *callback_data, int size, int *err)\r
+{\r
+ int fd = -1;\r
+ int ret = 0;\r
+\r
+ char callback_path[256] = {0,};\r
+\r
+ snprintf(callback_path, 256, "/run/rsc_mgr/%d.%d.s2c.cb", pid, cid);\r
+\r
+ if ((fd = open(callback_path, O_WRONLY|O_NONBLOCK)) < 0) {\r
+ SERVER_ERR("open error (%s), errno(%d)\n", callback_path, errno);\r
+ *err = errno;\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ if (is_symlink_file(callback_path)) {\r
+ SERVER_ERR("%s is symbolic link file", callback_path);\r
+ *err = EPERM;\r
+ close(fd);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ ret = write(fd, callback_data, size);\r
+\r
+ if (ret <= 0) {\r
+ SERVER_ERR("failed to write callback.(%s) ret(%d), errno(%d)\n", callback_path, ret, errno);\r
+ *err = errno;\r
+ close(fd);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ SERVER_DBG("succeeded to write callback.(%s)", callback_path);\r
+\r
+ close(fd);\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+int CCallback::RemoveFIFOServerToClient(int pid, int cid)\r
+{\r
+ struct stat stat_info;\r
+ char cb_path_s2c[256] = {0, };\r
+\r
+ snprintf(cb_path_s2c, 256, "/run/rsc_mgr/%d.%d.s2c.cb", pid, cid);\r
+\r
+ if (stat(cb_path_s2c, &stat_info) != 0) {\r
+ SERVER_INFO("%s not exists", cb_path_s2c);\r
+ return RMS_OK;\r
+ }\r
+\r
+ if (remove(cb_path_s2c) != 0) {\r
+ SERVER_ERR("failed to remove cb for S2C(%s)-(%d)", cb_path_s2c, errno);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ SERVER_DBG("Removed cb for S2C(%s)", cb_path_s2c);\r
+ return RMS_OK;\r
+}\r
+\r
+int CCallback::ConvertCallbackType(int rm_return_type)\r
+{\r
+ switch (rm_return_type) {\r
+ case RMS_ERROR_TAKE_RESOURCE_FROM_OTHER_CONSUMER:\r
+ return RMS_CALLBACK_TYPE_RESOURCE_CONFLICT;\r
+ case RMS_OK_UHD_RESOURCE_CONFLICT:\r
+ return RMS_CALLBACK_TYPE_RESOURCE_CONFLICT_UD;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ SERVER_ERR("return RMS_CALLBACK_TYPE_UNKNOWN(%d)", RMS_CALLBACK_TYPE_UNKNOWN);\r
+\r
+ return RMS_CALLBACK_TYPE_UNKNOWN;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <assert.h>\r
+#include <iostream>\r
+#include <glib.h>\r
+#include <gio/gio.h>\r
+#include <trace.h>\r
+\r
+#include <rms_type.h>\r
+#include <rms_debug.h>\r
+#include <CMessage.h>\r
+#include <CAsyncQueue.h>\r
+#include <CDbusHandler.h>\r
+\r
+const GDBusInterfaceVTable CDbusHandler::m_vtable = { CDbusHandler::OnMethodCall, NULL, NULL, {0} };\r
+\r
+const std::string CDbusHandler::m_methods =\r
+ "<node>"\r
+ "<interface name = 'rscmgr.resource'>"\r
+ "<method name = 'GetResourceState'>"\r
+ "<arg direction='in' type='i' name='device_id'/>"\r
+ "<arg direction='out' type='i' name='state'/>"\r
+ "</method>"\r
+ "<method name = 'GetResourceList'>"\r
+ "<arg direction='in' type='i' name='category_id'/>"\r
+ "<arg direction='out' type='a(iissi)'/>"\r
+ "</method>"\r
+ "<method name = 'GetRscCollectionState'>"\r
+ "<arg direction='in' type='i' name='collection'/>"\r
+ "<arg direction='out' type='a(isiiis)'/>"\r
+ "</method>"\r
+ "<method name = 'FindDeviceId'>"\r
+ "<arg direction='in' type='i' name='virtual_id'/>"\r
+ "<arg direction='out' type='i' name='real_id'/>"\r
+ "</method>"\r
+ "<method name = 'SwapResources'>"\r
+ "<arg direction='in' type='i' name='device_id_a'/>"\r
+ "<arg direction='in' type='i' name='device_id_b'/>"\r
+ "<arg direction='out' type='i' name='result'/>"\r
+ "</method>"\r
+ "<method name = 'GetScalerState'>"\r
+ "<arg direction='in' type='i' name='category_id'/>"\r
+ "<arg direction='out' type='a(iiiiis)'/>"\r
+ "</method>"\r
+ "<method name = 'GetAppId'>"\r
+ "<arg direction='in' type='i' name='handle'/>"\r
+ "<arg direction='out' type='i' name='result'/>"\r
+ "<arg direction='out' type='s' name='app_id'/>"\r
+ "</method>"\r
+ "<method name = 'GetActiveAudioOut'>"\r
+ "<arg direction='in' type='i' name='handle'/>"\r
+ "<arg direction='out' type='i' name='audio_out'/>"\r
+ "</method>"\r
+ "<method name = 'GetScalerHWID'>"\r
+ "<arg direction='in' type='i' name='zone_id'/>"\r
+ "<arg direction='out' type='i' name='hw_id'/>"\r
+ "</method>"\r
+ "<method name = 'RestoreResources'>"\r
+ "<arg direction='in' type='i' name='category_id'/>"\r
+ "<arg direction='out' type='i' name='result'/>"\r
+ "</method>"\r
+ "<method name = 'NotifyResourcePolicy'>"\r
+ "<arg direction='in' type='i' name='policy'/>"\r
+ "<arg direction='out' type='i' name='result'/>"\r
+ "</method>"\r
+ "<method name = 'NotifyAppZoneInfo'>"\r
+ "<arg direction='in' type='s' name='appid'/>"\r
+ "<arg direction='in' type='i' name='zoneid'/>"\r
+ "<arg direction='out' type='i' name='reply'/>"\r
+ "</method>"\r
+ "</interface>"\r
+ "</node>";\r
+\r
+CDbusHandler::CDbusHandler(CAsyncQueue *queue)\r
+{\r
+ assert(queue);\r
+ m_async_queue = queue;\r
+ m_reg_id = 0;\r
+\r
+ if (!MakeDbusConnection())\r
+ return;\r
+\r
+ RegisterObjects();\r
+}\r
+\r
+bool CDbusHandler::MakeDbusConnection(void)\r
+{\r
+ m_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);\r
+\r
+ if (!m_conn) {\r
+ SERVER_ERR("failed to make dbus connection");\r
+ return false;\r
+ }\r
+\r
+ SERVER_INFO("making dbus connection success");\r
+ return true;\r
+}\r
+\r
+void CDbusHandler::OnMethodCall(GDBusConnection *conn, const gchar *sender, const gchar *obj_path, const gchar *ifname, const gchar *method_name, GVariant *params, GDBusMethodInvocation *invoc, gpointer data)\r
+{\r
+ CDbusHandler *handler = static_cast<CDbusHandler*>(data);\r
+ CAsyncQueue *queue = handler->m_async_queue;\r
+ CMessage *msg = new CMessage(invoc);\r
+\r
+ SERVER_INFO("push msg(%s)", method_name);\r
+\r
+ queue->push(msg);\r
+}\r
+\r
+void CDbusHandler::GenerateReadyEvent(void)\r
+{\r
+ SERVER_INFO("We will notify clients when the server is ready by generating a ready event");\r
+}\r
+\r
+void CDbusHandler::OnBusAcquired(GDBusConnection *conn, const gchar *bus_name, gpointer data)\r
+{\r
+ trace_begin("[RSC_MGR] OnBusAcquired");\r
+ trace_end();\r
+ SERVER_INFO("bus acquired (%s)", bus_name);\r
+\r
+ CDbusHandler *handler = static_cast<CDbusHandler*>(data);\r
+ handler->GenerateReadyEvent();\r
+}\r
+\r
+void CDbusHandler::OnNameLost(GDBusConnection *conn, const gchar *bus_name, gpointer data)\r
+{\r
+ SERVER_ERR("name lost (%s)", bus_name);\r
+}\r
+\r
+void CDbusHandler::RegisterObjects(void)\r
+{\r
+ assert(m_conn);\r
+ GError *err = NULL;\r
+\r
+ GDBusNodeInfo *node_info = g_dbus_node_info_new_for_xml(m_methods.c_str(), &err);\r
+\r
+ if (!node_info) {\r
+ SERVER_ERR("failed to get node_info (%s)", err ? err->message : "unknown");\r
+ g_clear_error(&err);\r
+ return;\r
+ }\r
+\r
+ m_reg_id = g_dbus_connection_register_object(m_conn, RM_DBUS_OBJ_PATH, *(node_info->interfaces), &m_vtable, this, NULL, &err);\r
+\r
+ if (m_reg_id == 0) {\r
+ SERVER_ERR("failed to register objects (%s)", err ? err->message : "unknown");\r
+ g_clear_error(&err);\r
+ return;\r
+ }\r
+\r
+ m_own_id = g_bus_own_name_on_connection(m_conn, RM_DBUS_BUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, CDbusHandler::OnBusAcquired, CDbusHandler::OnNameLost, this, NULL);\r
+\r
+ if (m_own_id == 0) {\r
+ SERVER_ERR("failed to own dbus name (%s)", RM_DBUS_BUS_NAME);\r
+ return;\r
+ }\r
+\r
+ SERVER_INFO("registering dbus objects success");\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <CHandle.h>\r
+#include <stdlib.h>\r
+#include <rms_type.h>\r
+#include <CDebugUtils.h>\r
+CHandle::CHandle(int in_handle, int in_is_used, int in_pid)\r
+{\r
+ handle = in_handle;\r
+ is_used = in_is_used;\r
+ pid = in_pid;\r
+ rms_get_cmd_name(pid,process_name,RMS_NAME_BUF_SIZE);\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <CHandleManager.h>\r
+#include <CHandle.h>\r
+#include <CConsumer.h>\r
+#include <CConsumerContainer.h>\r
+#include <CCallback.h>\r
+#include <CDebugUtils.h>\r
+\r
+#include <rms_type.h>\r
+#include <rms_debug.h>\r
+#include <rms_log.h>\r
+\r
+#include <map>\r
+#include <stdio.h>\r
+#include <fcntl.h>\r
+#include <signal.h>\r
+#include <stdlib.h>\r
+\r
+\r
+static const int M_MIN_HANDLE = 101;\r
+static const int M_MAX_HANDLE = 200;\r
+\r
+CHandleManager::CHandleManager(CResourceManager *rsc_mgr)\r
+{\r
+ assert(rsc_mgr);\r
+ m_rsc_mgr = rsc_mgr;\r
+ m_next_handle = M_MIN_HANDLE;\r
+}\r
+\r
+int CHandleManager::m_IsValidHandle(int handle)\r
+{\r
+ return ((handle >= M_MIN_HANDLE) && (handle <= M_MAX_HANDLE)) ? 1 : 0;\r
+}\r
+\r
+int CHandleManager::m_ReclaimHandle(void)\r
+{\r
+ for (int i = M_MIN_HANDLE; i < M_MAX_HANDLE; i++) {\r
+ CHandle *handle_info = findHandle(i);\r
+\r
+ if (!handle_info)\r
+ return i;\r
+\r
+ if (!rm_is_valid_pid(handle_info->pid)) {\r
+ SERVER_INFO("reclaim pid(%d)/handle(%d)", handle_info->pid, handle_info->handle);\r
+\r
+ // release resources allocated to terminated process\r
+ m_rsc_mgr->UnregisterConsumer(handle_info->handle);\r
+ m_RemoveHandle(handle_info->handle, handle_info->pid);\r
+ return i;\r
+ }\r
+ }\r
+\r
+ return RMS_HANDLE_NOT_AVAILABLE;\r
+}\r
+\r
+void CHandleManager::m_PrintHandleList(void)\r
+{\r
+ for (int i = M_MIN_HANDLE; i < M_MAX_HANDLE; i++) {\r
+ std::map<int, CHandle*>::iterator it = m_handles.find(i);\r
+\r
+ if (it == m_handles.end())\r
+ return ;\r
+\r
+ CHandle *handle_info = (*it).second;\r
+ m_PrintHandleInfo(handle_info->handle, handle_info->pid);\r
+ }\r
+}\r
+\r
+int CHandleManager::m_AddNewHandle(int handle, int pid, int main_priority, int sub_priority, int app_pid, char *app_id)\r
+{\r
+ CHandle *handle_info = new(std::nothrow) CHandle(handle, RMS_HANDLE_USE, pid);\r
+ if (!handle_info) {\r
+ SERVER_ERR("cannot create handle class");\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ handle_info->main_priority = main_priority;\r
+ handle_info->sub_priority = sub_priority;\r
+ handle_info->app_pid = app_pid;\r
+ handle_info->app_id = strndup(app_id, strlen(app_id));\r
+\r
+ m_handles.insert(std::pair<int, CHandle*>(handle, handle_info));\r
+ SERVER_DBG("handle(%d) pid(%d) inserted", handle, pid);\r
+\r
+ return RMS_OK;\r
+}\r
+int CHandleManager::m_RemoveHandle(int handle, int pid)\r
+{\r
+ CHandle *handle_info = findHandle(handle);\r
+\r
+ if (!handle_info) {\r
+ SERVER_ERR("can't find handle (%d) in list. no need to remove", handle);\r
+ return RMS_OK;\r
+ }\r
+\r
+ if (handle_info->pid != pid) {\r
+ SERVER_ERR("cannot remove handle (%d) - owner(%d)/requester(%d)", handle, handle_info->pid, pid);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ if (handle_info->app_id) {\r
+ free(handle_info->app_id);\r
+ handle_info->app_id = NULL;\r
+ }\r
+\r
+ for (int i = 0; i < RMS_NAME_BUF_SIZE; i++) {\r
+ handle_info->process_name[i] = 0;\r
+ }\r
+\r
+ delete handle_info;\r
+ m_handles.erase(handle);\r
+\r
+ CCallback::RemoveFIFOServerToClient(pid, handle);\r
+\r
+ return RMS_OK;\r
+}\r
+int CHandleManager::GetNewHandle(int pid, int main_priority, int sub_priority, int app_pid, char *app_id)\r
+{\r
+ int handle = -1;\r
+\r
+ if (m_next_handle >= (M_MAX_HANDLE - 1))\r
+ m_next_handle = M_MIN_HANDLE;\r
+\r
+ std::map<int, CHandle*>::iterator it = m_handles.find(m_next_handle);\r
+\r
+ handle = (it == m_handles.end()) ? m_next_handle:m_ReclaimHandle();\r
+\r
+ if (handle == RMS_HANDLE_NOT_AVAILABLE) {\r
+ SERVER_ERR("ERROR! can't assign new handle (FULL)");\r
+ m_PrintHandleList();\r
+ return RMS_HANDLE_NOT_AVAILABLE;\r
+ }\r
+\r
+ m_AddNewHandle(handle, pid, main_priority, sub_priority, app_pid, app_id);\r
+ ++m_next_handle;\r
+\r
+ return handle;\r
+}\r
+\r
+int CHandleManager::RemoveHandle(int handle, int pid)\r
+{\r
+ return m_RemoveHandle(handle, pid);\r
+}\r
+\r
+int CHandleManager::SetPriority(int handle, int main_priority, int sub_priority)\r
+{\r
+ CHandle *handle_info = findHandle(handle);\r
+\r
+ if (!handle_info) {\r
+ SERVER_ERR("can't find handle (%d)", handle);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ CConsumer *consumer = CConsumerContainer::getInstance()->findConsumer(handle);\r
+\r
+ if (!consumer) {\r
+ SERVER_ERR("handle[%d] not registered consumer", handle);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ handle_info->main_priority = main_priority;\r
+ handle_info->sub_priority = sub_priority;\r
+\r
+ rms_priority_s priority;\r
+ priority.main = main_priority;\r
+ priority.sub = sub_priority;\r
+\r
+ consumer->SetPriority(priority);\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+CHandle *CHandleManager::findHandle(int id)\r
+{\r
+ auto it = m_handles.find(id);\r
+\r
+ return (it == m_handles.end()) ? NULL:it->second;\r
+}\r
+\r
+int CHandleManager::GetPriority(int handle, int *main_priority, int *sub_priority)\r
+{\r
+ CHandle *handle_info = findHandle(handle);\r
+\r
+ if (!handle_info) {\r
+ SERVER_ERR("can't find handle (%d)", handle);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ *main_priority = handle_info->main_priority;\r
+ *sub_priority = handle_info->sub_priority;\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+int CHandleManager::SetAppID(int handle, char *app_id)\r
+{\r
+ CHandle *handle_info = findHandle(handle);\r
+\r
+ if (!handle_info) {\r
+ SERVER_ERR("can't find handle (%d)", handle);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ if (handle_info->app_id) {\r
+ free(handle_info->app_id);\r
+ handle_info->app_id = NULL;\r
+ }\r
+\r
+ handle_info->app_id = strndup(app_id, strlen(app_id));\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+char *CHandleManager::GetAppID(int handle)\r
+{\r
+ CHandle *handle_info = findHandle(handle);\r
+\r
+ if (!handle_info) {\r
+ SERVER_ERR("can't find handle (%d)", handle);\r
+ return NULL;\r
+ }\r
+\r
+ return strndup(handle_info->app_id, strlen(handle_info->app_id));\r
+}\r
+\r
+int CHandleManager::m_PrintHandleInfo(int handle, int pid)\r
+{\r
+ char name[RMS_NAME_BUF_SIZE] = {0,};\r
+ rms_get_cmd_name(pid, name, sizeof(name));\r
+\r
+ rms_log_reset();\r
+ rms_log_add("handle(%d) pid(%d) name(%s)", handle, pid, name);\r
+\r
+ CConsumer *consumer = CConsumerContainer::getInstance()->findConsumer(handle);\r
+\r
+ if (!consumer) {\r
+ rms_log_add(": no consumer info");\r
+\r
+ RMS_LOGE_FLUSH();\r
+ return RMS_OK;\r
+ }\r
+\r
+ rms_log_add(": using %d resource(s)", consumer->GetResourceNum());\r
+\r
+ RMS_LOGE_FLUSH();\r
+ return RMS_OK;\r
+}\r
+\r
+void CHandleManager::ReclaimAllInvalidCustomer(int request_pid)\r
+{\r
+ for (std::map<int, CHandle*>::iterator it = m_handles.begin(); it != m_handles.end(); it++) {\r
+ CHandle *handle_info = (*it).second;\r
+ int cid = handle_info->handle;\r
+ int pid = handle_info->pid;\r
+\r
+ if ((pid != request_pid) &&(!rm_is_valid_pid(pid))) {\r
+ SERVER_ERR("Reclaim handle(%d)/pid(%d)", cid, pid);\r
+ m_rsc_mgr->ReleaseResourcesOfPid(pid);\r
+ RemoveHandle(cid, pid);\r
+ CCallback::RemoveFIFOServerToClient(pid, cid);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <assert.h>\r
+#include <ri-api.h>\r
+#include <ri-module-api.h>\r
+#include <rms_debug.h>\r
+#include <CMessage.h>\r
+\r
+CMessage::CMessage(std::string name)\r
+{\r
+ m_sender = MSG_SENDER_INTERNAL;\r
+ m_msgq_req = NULL;\r
+ m_name = name;\r
+}\r
+\r
+CMessage::CMessage(rms_msg_request *req)\r
+{\r
+ assert(req);\r
+\r
+ m_msgq_req = (rms_msg_request*) calloc(1, sizeof(rms_msg_request));\r
+ assert(m_msgq_req);\r
+ memcpy(m_msgq_req, req, sizeof(rms_msg_request));\r
+\r
+ m_sender = MSG_SENDER_MSGQ;\r
+}\r
+\r
+CMessage::CMessage(GDBusMethodInvocation *invoc)\r
+{\r
+ assert(invoc);\r
+\r
+ m_invoc = invoc;\r
+ m_sender = MSG_SENDER_DBUS;\r
+ m_msgq_req = NULL;\r
+}\r
+\r
+CMessage::~CMessage(void)\r
+{\r
+ if (m_msgq_req)\r
+ free(m_msgq_req);\r
+}\r
+\r
+int CMessage::GetReqType(void)\r
+{\r
+ int req_type = RMS_REQUEST_MAX;\r
+ assert(m_msgq_req);\r
+\r
+ switch (m_sender) {\r
+ case MSG_SENDER_MSGQ:\r
+ req_type = m_msgq_req->type;\r
+ break;\r
+ case MSG_SENDER_DBUS:\r
+ case MSG_SENDER_INTERNAL:\r
+ break;\r
+ default:\r
+ SERVER_ERR("undefined sender(%d)", m_sender);\r
+ break;\r
+ }\r
+\r
+ return req_type;\r
+}\r
+\r
+bool CMessage::IsMsgForScalerDbus(void)\r
+{\r
+ std::string method_name = g_dbus_method_invocation_get_method_name(m_invoc);\r
+\r
+ if (!method_name.compare("FindDeviceId"))\r
+ return true;\r
+ if (!method_name.compare("SwapResources"))\r
+ return true;\r
+ if (!method_name.compare("GetScalerState"))\r
+ return true;\r
+ if (!method_name.compare("GetScalerHWID"))\r
+ return true;\r
+ if (!method_name.compare("RestoreResources"))\r
+ return true;\r
+\r
+ return false;\r
+}\r
+\r
+bool CMessage::IsMsgForScalerMsgQ(void)\r
+{\r
+ bool result = false;\r
+ switch (m_msgq_req->type) {\r
+ case RMS_REQUEST_ALLOCATE_RESOURCE:\r
+ for (int i = 0; i < m_msgq_req->request_num; i++) {\r
+ if (ri_is_video_scaler_category(m_msgq_req->resource[i]))\r
+ {\r
+ result = true;\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+ case RMS_REQUEST_RELEASE_RESOURCES:\r
+ int category_type;\r
+ for (int i = 0; i < m_msgq_req->request_num; i++) {\r
+ ri_get_category_type_by_device_id(m_msgq_req->resource[i], &category_type);\r
+ if (ri_is_video_scaler_category(category_type))\r
+ {\r
+ result = true;\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+ case RMS_REQUEST_UNREGISTER:\r
+ case RMS_REQUEST_REGISTER:\r
+ case RMS_REQUEST_QUERY:\r
+ case RMS_REQUEST_SET_PRIORITY:\r
+ case RMS_REQUEST_SET_APPID:\r
+ result = false;\r
+ break;\r
+ default:\r
+ SERVER_ERR("undefined req type(%d)", m_msgq_req->type);\r
+ break;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+void CMessage::PrintInfo(void)\r
+{\r
+ switch (m_sender) {\r
+ case MSG_SENDER_MSGQ:\r
+ PrintMsgQ();\r
+ break;\r
+ case MSG_SENDER_DBUS:\r
+ PrintDbus();\r
+ break;\r
+ case MSG_SENDER_INTERNAL:\r
+ PrintInternal();\r
+ break;\r
+ default:\r
+ SERVER_ERR("undefined sender(%d)", m_sender);\r
+ break;\r
+ }\r
+}\r
+\r
+void CMessage::PrintDbus(void)\r
+{\r
+ SERVER_ERR("Sender:Dbus/%s", g_dbus_method_invocation_get_method_name(m_invoc));\r
+}\r
+\r
+void CMessage::PrintInternal(void)\r
+{\r
+ SERVER_ERR("Sender:Internal/%s", m_name.c_str());\r
+}\r
+\r
+void CMessage::PrintMsgQ(void)\r
+{\r
+ SERVER_ERR("Sender:MsgQ/type(%d)/cid(%d)/num(%d)", m_msgq_req->type, m_msgq_req->handle, m_msgq_req->request_num);\r
+}\r
+\r
+bool CMessage::IsUnlockMsg(void)\r
+{\r
+ if (m_sender != MSG_SENDER_INTERNAL)\r
+ return false;\r
+\r
+ return (!m_name.compare("NotifyUnlock"));\r
+}\r
+\r
+bool CMessage::IsMsgForScaler(void)\r
+{\r
+ bool result = false;\r
+\r
+ switch (m_sender) {\r
+ case MSG_SENDER_MSGQ:\r
+ result = IsMsgForScalerMsgQ();\r
+ break;\r
+ case MSG_SENDER_DBUS:\r
+ result = IsMsgForScalerDbus();\r
+ break;\r
+ case MSG_SENDER_INTERNAL:\r
+ result = false;\r
+ break;\r
+ default:\r
+ SERVER_ERR("undefined sender(%d)", m_sender);\r
+ break;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+bool CMessage::IsMsgFor(ResourceType rsc_type)\r
+{\r
+ bool result = false;\r
+\r
+ switch (rsc_type) {\r
+ case ResourceType::VIDEO_SCALER:\r
+ result = IsMsgForScaler();\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return result;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <iostream>\r
+#include <sys/types.h>\r
+#include <sys/ipc.h>\r
+#include <sys/msg.h>\r
+#include <unistd.h>\r
+#include <errno.h>\r
+#include <trace.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <assert.h>\r
+#include <gio/gio.h>\r
+\r
+#include <CMessage.h>\r
+#include <CMessageHandler.h>\r
+#include <CCallback.h>\r
+#include <CDebugUtils.h>\r
+#include <rms_debug.h>\r
+#include <CHandleManager.h>\r
+#include <CResourceManager.h>\r
+#include <CConsumerContainer.h>\r
+#include <CQueryHandler.h>\r
+#include <CAsyncQueue.h>\r
+#include <CCache.h>\r
+#include <CDbusHandler.h>\r
+\r
+#define RMS_HANLDE_COMMON 100 // common handle for the request rm_register() is not required\r
+#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))\r
+\r
+struct rms_msg_handler {\r
+ const char *msg_name;\r
+ CMessageHandler::MsgHandler handler;\r
+};\r
+\r
+CMessageHandler::CMessageHandler(CResourceManager *rsc_mgr)\r
+{\r
+ assert(rsc_mgr);\r
+\r
+ msgq_rx = new CMessageQueue(MSG_QUEUE_RX);\r
+ msgq_tx = new CMessageQueue(MSG_QUEUE_TX);\r
+ async_queue = new CAsyncQueue();\r
+ async_pending_queue = new CAsyncQueue();\r
+\r
+ m_rsc_mgr = rsc_mgr;\r
+ m_query_h = new CQueryHandler(rsc_mgr);\r
+ m_handle_mgr = new CHandleManager(rsc_mgr);\r
+ m_lock_ctr = CLockController::GetInstance();\r
+ m_lock_ctr->SetMsgQ(async_queue);\r
+\r
+ CCallback::InitCallback();\r
+ InitDbusHandlers();\r
+ InitInternalMsgHandlers();\r
+}\r
+\r
+CMessageHandler::~CMessageHandler(void)\r
+{\r
+\r
+}\r
+\r
+void CMessageHandler::InitDbusHandlers(void)\r
+{\r
+ struct rms_msg_handler dbus_handlers[] = {\r
+ {"RegisterResource", &CMessageHandler::RegisterResource},\r
+ {"GetResourceState", &CMessageHandler::GetResourceState},\r
+ {"GetResourceList", &CMessageHandler::GetResourceList},\r
+ {"GetRscCollectionState", &CMessageHandler::GetResourceCollectionState},\r
+ {"FindDeviceId", &CMessageHandler::FindDeviceId},\r
+ {"SwapResources", &CMessageHandler::SwapResources},\r
+ {"GetScalerState", &CMessageHandler::GetScalerState},\r
+ {"GetAppId", &CMessageHandler::GetAppId},\r
+ {"GetActiveAudioOut", &CMessageHandler::GetActiveAudioOut},\r
+ {"GetScalerHWID", &CMessageHandler::GetScalerHWID},\r
+ {"RestoreResources", &CMessageHandler::RestoreResources},\r
+ {"NotifyResourcePolicy", &CMessageHandler::NotifyResourcePolicy},\r
+ {"NotifyAppZoneInfo", &CMessageHandler::NotifyAppZoneInfo}\r
+ // Please add a new dbus message handler here\r
+ };\r
+\r
+ std::string msg_name;\r
+ for (unsigned int i = 0; i < ARRAY_SIZE(dbus_handlers); i++) {\r
+ msg_name.assign(dbus_handlers[i].msg_name);\r
+ m_dbus_handlers.insert(std::pair<std::string, CMessageHandler::MsgHandler>(msg_name, dbus_handlers[i].handler));\r
+ }\r
+}\r
+\r
+void CMessageHandler::InitInternalMsgHandlers(void)\r
+{\r
+ struct rms_msg_handler internal_msg_handlers[] = {\r
+ {"NotifyWatchdog", &CMessageHandler::NotifyWatchdog}\r
+ // Please add a new internal message handler here\r
+ };\r
+\r
+ std::string msg_name;\r
+ for (unsigned int i = 0; i < ARRAY_SIZE(internal_msg_handlers); i++) {\r
+ msg_name.assign(internal_msg_handlers[i].msg_name);\r
+ m_internal_msg_handlers.insert(std::pair<std::string, CMessageHandler::MsgHandler>(msg_name, internal_msg_handlers[i].handler));\r
+ }\r
+}\r
+\r
+void CMessageHandler::m_ConstructRequestedDevice(rms_msg_request *request, rms_requests_device_s *requested_resource)\r
+{\r
+ requested_resource->resources_num = request->request_num;\r
+\r
+ for (int i = 0; i < requested_resource->resources_num; i++) {\r
+ requested_resource->devices[i].device_id = request->resource[i];\r
+ requested_resource->devices[i].requested_state = (rms_requests_resource_state_e) request->state[i];\r
+ }\r
+}\r
+\r
+int CMessageHandler::Run(void)\r
+{\r
+ if (g_thread_new("rms_msgq_thread", msgQThread, this) == NULL) {\r
+ SERVER_ERR("failed to create rms_msgq thread");\r
+ assert(0);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ if (g_thread_new("rms_msg_thread", msgThread, this) == NULL) {\r
+ SERVER_ERR("event loop thread create failed\n");\r
+ assert(0);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ m_dbus_h = new CDbusHandler(async_queue);\r
+ return RMS_OK;\r
+}\r
+\r
+gpointer CMessageHandler::msgQThread(gpointer data)\r
+{\r
+ assert(data);\r
+\r
+ CMessageHandler *msg_handler = (CMessageHandler*) data;\r
+ CAsyncQueue *asyncq = msg_handler->async_queue;\r
+ CMessageQueue *msgq = msg_handler->msgq_rx;\r
+ rms_msg_request req;\r
+\r
+ while (1) {\r
+ memset(&req, 0, sizeof(rms_msg_request));\r
+\r
+ if (msgq->receive(&req, RMS_REQUEST_DATA_TYPE_ALL) != RMS_OK)\r
+ continue;\r
+\r
+ SERVER_DBG("push req type(%d)-pid(%d)-cid(%d)-len(%d)", req.type, req.pid, req.handle, asyncq->length());\r
+\r
+ CMessage *msg = new CMessage(&req);\r
+ asyncq->push(msg);\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+gpointer CMessageHandler::msgThread(gpointer data)\r
+{\r
+ assert(data);\r
+ SERVER_INFO("prepare to handle messages");\r
+\r
+ CMessageHandler *msg_handler = (CMessageHandler*) data;\r
+\r
+ while (1) {\r
+ msg_handler->ProcessMessage();\r
+ usleep(30000);\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+bool CMessageHandler::IsRegisteredHandle(int handle)\r
+{\r
+ return (CConsumerContainer::getInstance()->findConsumer(handle) != NULL);\r
+}\r
+\r
+void CMessageHandler::SetRequesterInfo(rms_msg_request *request)\r
+{\r
+ char *app_id = m_handle_mgr->GetAppID(request->handle);\r
+ m_handle_mgr->GetPriority(request->handle, &request->main_priority, &request->sub_priority);\r
+\r
+ snprintf(request->app_id, RMS_APPID_LENGTH, "%s", (app_id) ? app_id : "");\r
+\r
+ SERVER_INFO("handle(%d)-app_id(%s)", request->handle, request->app_id);\r
+\r
+ if (app_id)\r
+ free(app_id);\r
+}\r
+\r
+\r
+void CMessageHandler::m_RegisterConsumer(rms_msg_request *request, rms_msg_response *response)\r
+{\r
+ char cmd[RMS_NAME_BUF_SIZE] = {0,};\r
+\r
+ int handle = m_handle_mgr->GetNewHandle(request->pid, request->main_priority, request->sub_priority, request->app_pid, request->app_id);\r
+\r
+ response->result = (handle == RMS_HANDLE_NOT_AVAILABLE) ? RMS_ERROR : RMS_OK;\r
+\r
+ m_ConstructResponse(response, request->data_type, RMS_RESPONSE_REGISTER, handle, request->pid);\r
+\r
+ if (response->result == RMS_ERROR)\r
+ return;\r
+\r
+ if (m_rsc_mgr->RegisterConsumer(handle, request->pid, request->app_id, request->main_priority, request->sub_priority) != RMS_OK)\r
+ SERVER_ERR("failed to add consumer to manager. handle[%d]", handle);\r
+\r
+ rms_get_cmd_name(request->pid, cmd, sizeof(cmd));\r
+\r
+ SERVER_INFO("newly assigned handle(%d) - pid(%d)-(%s)", response->handle, request->pid, cmd);\r
+}\r
+\r
+void CMessageHandler::m_UnregisterConsumer(rms_msg_request *request, rms_msg_response *response)\r
+{\r
+ SERVER_INFO("request for unregister handle(%d)", request->handle);\r
+\r
+ m_ConstructResponse(response, request->data_type, RMS_RESPONSE_UNREGISTER, request->handle, request->pid);\r
+\r
+ if (!IsRegisteredHandle(request->handle)) {\r
+ response->result = RMS_ERROR;\r
+ return;\r
+ }\r
+\r
+ response->result = m_handle_mgr->RemoveHandle(request->handle, request->pid);\r
+\r
+ if (response->result != RMS_OK)\r
+ return;\r
+\r
+ m_rsc_mgr->UnregisterConsumer(request->handle);\r
+}\r
+\r
+void CMessageHandler::m_FreeAllocatedDevice(rms_return_device_s *allocated_device)\r
+{\r
+ if (allocated_device->device_ids) {\r
+ free(allocated_device->device_ids);\r
+ allocated_device->device_ids = NULL;\r
+ }\r
+\r
+ for (int i=0 ; i < allocated_device->resources_num; i++) {\r
+ if (allocated_device->devices[i].device_path) {\r
+ free((void*)allocated_device->devices[i].device_path);\r
+ allocated_device->devices[i].device_path = NULL;\r
+ }\r
+ }\r
+\r
+ if (allocated_device->devices) {\r
+ free(allocated_device->devices);\r
+ allocated_device->devices = NULL;\r
+ }\r
+}\r
+\r
+void CMessageHandler::m_Free(consumer_reclaim_s *consumer_info)\r
+{\r
+ if (!consumer_info)\r
+ return;\r
+\r
+ if (!consumer_info->consumer_info)\r
+ return;\r
+\r
+ for (int i = 0; i < consumer_info->ret_quantity; i++) {\r
+ if (consumer_info->consumer_info[i].conflicted_resources != NULL)\r
+ free(consumer_info->consumer_info[i].conflicted_resources);\r
+ }\r
+\r
+ free(consumer_info->consumer_info);\r
+}\r
+\r
+void CMessageHandler::m_AllocateResources(rms_msg_request *request, rms_msg_response *response)\r
+{\r
+ trace_begin("RSC ALLOCATE START");\r
+ trace_end();\r
+\r
+ if (!IsRegisteredHandle(request->handle)) {\r
+ m_ConstructResponse(response, request->data_type, RMS_RESPONSE_ALLOCATE_RESOURCE, request->handle, request->pid);\r
+ response->result = RMS_ERROR;\r
+ return;\r
+ }\r
+\r
+ int result = RMS_OK;\r
+ bool need_response = true;\r
+ rms_return_device_s allocated_device;\r
+ memset(&allocated_device, 0, sizeof(rms_return_device_s));\r
+\r
+ m_handle_mgr->ReclaimAllInvalidCustomer(request->pid);\r
+\r
+ SetRequesterInfo(request);\r
+\r
+ result = m_rsc_mgr->AllocateResources(request, &allocated_device);\r
+\r
+ bool needReclaimResources = (result == RMS_ERROR_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
+\r
+ if (needReclaimResources) {\r
+ consumer_reclaim_s consumers_reclaim;\r
+ memset(&consumers_reclaim, 0, sizeof(consumers_reclaim));\r
+ int zone_id = -1;\r
+ if (m_rsc_mgr->FindReclaimableConsumers(request, &consumers_reclaim, &zone_id) == RMS_OK) {\r
+ CResourceDB::getInstance()->AddReclaimResources(&consumers_reclaim);\r
+ if (ReclaimResources(result, request->handle, zone_id, &consumers_reclaim, &need_response) == RMS_OK) {\r
+ result = m_rsc_mgr->AllocateResources(request, &allocated_device);\r
+ }\r
+ CResourceDB::getInstance()->ClearReclaimResources();\r
+ }\r
+ m_Free(&consumers_reclaim);\r
+ }\r
+\r
+ m_ConstructResponse(response, request->data_type, RMS_RESPONSE_ALLOCATE_RESOURCE, request->handle, request->pid);\r
+\r
+ response->result = result;\r
+ response->error_type = (result == RMS_OK) ? RMS_ERR_TYPE_NONE : (rms_error_type_e)allocated_device.error_type;\r
+ response->resource_num = allocated_device.resources_num;\r
+\r
+ if (!need_response)\r
+ response->error_type = RMS_ERR_TYPE_TERMINATED_PROCESS;\r
+\r
+ for (int i = 0; i < response->resource_num; i++) {\r
+ response->resource[i] = allocated_device.device_ids[i];\r
+ }\r
+\r
+ m_FreeAllocatedDevice(&allocated_device);\r
+ CCache::getInstance()->Drop();\r
+\r
+ trace_begin("RSC ALLOCATE END");\r
+ trace_end();\r
+}\r
+\r
+void CMessageHandler::m_ReleaseResources(rms_msg_request *request, rms_msg_response *response)\r
+{\r
+ SERVER_DBG("request for deallocation");\r
+\r
+ m_ConstructResponse(response, request->data_type, RMS_RESPONSE_RELEASE_RESOURCES, request->handle, request->pid);\r
+\r
+ if (!IsRegisteredHandle(request->handle)) {\r
+ response->result = RMS_ERROR;\r
+ return;\r
+ }\r
+\r
+ rms_requests_device_s requested_resource;\r
+ memset(&requested_resource, 0, sizeof(rms_requests_device_s));\r
+\r
+ m_ConstructRequestedDevice(request, &requested_resource);\r
+\r
+ response->result = m_rsc_mgr->ReleaseResources(request->handle, &requested_resource);\r
+}\r
+\r
+void CMessageHandler::m_Query(rms_msg_request *request, rms_msg_response *response)\r
+{\r
+ int answer = 0;\r
+\r
+ m_ConstructResponse(response, request->data_type, RMS_RESPONSE_QUERY, request->handle, request->pid);\r
+\r
+ m_handle_mgr->ReclaimAllInvalidCustomer(request->handle);\r
+\r
+ response->result = m_query_h->GetAnswer(request, &answer);\r
+ response->is_available = answer;\r
+\r
+ SERVER_INFO("query on (%d), result(%d)", request->sub_type, answer);\r
+}\r
+\r
+void CMessageHandler::m_SetConsumerPriority(rms_msg_request *request, rms_msg_response *response)\r
+{\r
+ SERVER_INFO("request for priority setting. priority(%d)", request->main_priority);\r
+\r
+ m_ConstructResponse(response, request->data_type, RMS_RESPONSE_SET_PRIORITY, request->handle, request->pid);\r
+\r
+ response->result = m_handle_mgr->SetPriority(request->handle, request->main_priority, request->sub_priority);\r
+}\r
+\r
+void CMessageHandler::m_SetAppID(rms_msg_request *request, rms_msg_response *response)\r
+{\r
+ SERVER_INFO("request for appid setting. appid(%s)", request->app_id);\r
+\r
+ m_ConstructResponse(response, request->data_type, RMS_RESPONSE_SET_APPID, request->handle, request->pid);\r
+\r
+ int ret = m_handle_mgr->SetAppID(request->handle, request->app_id);\r
+\r
+ if (ret != RMS_OK) {\r
+ SERVER_ERR("cannot update appid. handle(%d). ret(%d)", request->handle, ret);\r
+\r
+ response->result = RMS_ERROR;\r
+ return;\r
+ }\r
+\r
+ response->result = m_rsc_mgr->SetAppId(request->handle, request->app_id);\r
+}\r
+\r
+CMessageHandler::msg_handler CMessageHandler::handlers[RMS_REQUEST_MAX] = {\r
+ &CMessageHandler::m_RegisterConsumer,\r
+ &CMessageHandler::m_UnregisterConsumer,\r
+ &CMessageHandler::m_AllocateResources,\r
+ &CMessageHandler::m_ReleaseResources,\r
+ &CMessageHandler::m_Query,\r
+ &CMessageHandler::m_SetConsumerPriority,\r
+ &CMessageHandler::m_SetAppID,\r
+};\r
+\r
+void CMessageHandler::ProcessMsgQMessage(CMessage *msg)\r
+{\r
+ if (!IsValidRequest(msg->GetReqType())) {\r
+ SERVER_ERR("invalid req type(%d)", msg->GetReqType());\r
+ return;\r
+ }\r
+\r
+ rms_msg_response resp;\r
+ memset(&resp, 0, sizeof(rms_msg_response));\r
+\r
+ rms_msg_request *req = msg->GetRequest();\r
+ SERVER_INFO("req type(%d)-pid(%d)-cid(%d)-t(%lu)", req->type, req->pid, req->handle, req->time);\r
+\r
+ (this->*handlers[req->type])(msg->GetRequest(), &resp);\r
+\r
+ if (resp.error_type == RMS_ERR_TYPE_TERMINATED_PROCESS) {\r
+ SERVER_ERR("skip to send a response (%d)", req->pid);\r
+ return;\r
+ }\r
+\r
+ if (msgq_tx->send(&resp) != RMS_OK) {\r
+ SERVER_ERR("failed to send response");\r
+ }\r
+}\r
+\r
+GVariant *CMessageHandler::RegisterResource(GVariant *params)\r
+{\r
+ char *dev_name;\r
+ char *dev_node;\r
+ int category;\r
+ int sharable_count;\r
+\r
+ g_variant_get(params, "(&ssii)", &dev_name, &dev_node, &category, &sharable_count);\r
+\r
+ SERVER_INFO("dev_name(%s)/dev_node(%s)/category(%d)/sharable(%d)", dev_name, dev_node, category, sharable_count);\r
+ return g_variant_new("(i)", RMS_OK);\r
+}\r
+\r
+GVariant *CMessageHandler::GetResourceState(GVariant *params)\r
+{\r
+ int device_id;\r
+ int state;\r
+\r
+ g_variant_get(params, "(i)", &device_id);\r
+\r
+ state = m_rsc_mgr->GetResourceState(device_id);\r
+\r
+ SERVER_INFO("state (%d:%d)", device_id, state);\r
+\r
+ return g_variant_new("(i)", state);\r
+}\r
+\r
+GVariant *CMessageHandler::FindDeviceId(GVariant *params)\r
+{\r
+ int virtual_id;\r
+ int real_id;\r
+\r
+ g_variant_get(params, "(i)", &virtual_id);\r
+\r
+ real_id = m_rsc_mgr->FindDeviceId(virtual_id);\r
+\r
+ SERVER_INFO("real id (%d:%d)", virtual_id, real_id);\r
+\r
+ return g_variant_new("(i)", real_id);\r
+}\r
+\r
+GVariant *CMessageHandler::GetScalerHWID(GVariant *params)\r
+{\r
+ int zone_id;\r
+ int hw_id;\r
+\r
+ g_variant_get(params, "(i)", &zone_id);\r
+\r
+ hw_id = m_rsc_mgr->GetScalerHWId(zone_id);\r
+\r
+ SERVER_INFO("hw id (%d:%d)", zone_id, hw_id);\r
+\r
+ return g_variant_new("(i)", hw_id);\r
+}\r
+\r
+GVariant *CMessageHandler::SwapResources(GVariant *params)\r
+{\r
+ int device_id_a;\r
+ int device_id_b;\r
+ int result = 0;\r
+\r
+ g_variant_get(params, "(ii)", &device_id_a, &device_id_b);\r
+\r
+ result = m_rsc_mgr->SwapResources(device_id_a, device_id_b);\r
+\r
+ SERVER_INFO("swap result (%d:%d) > (%d)", device_id_a, device_id_b, result);\r
+\r
+ return g_variant_new("(i)", result);\r
+}\r
+\r
+GVariant *CMessageHandler::RestoreResources(GVariant *params)\r
+{\r
+ int category_id;\r
+ int result = 0;\r
+\r
+ g_variant_get(params, "(i)", &category_id);\r
+\r
+ result = m_rsc_mgr->RestoreResources(category_id);\r
+\r
+ SERVER_INFO("restore result (%d) > (%d)", category_id, result);\r
+\r
+ return g_variant_new("(i)", result);\r
+}\r
+\r
+GVariant *CMessageHandler::NotifyResourcePolicy(GVariant *params)\r
+{\r
+ int policy;\r
+ int result = 0;\r
+\r
+ g_variant_get(params, "(i)", &policy);\r
+\r
+ m_rsc_mgr->ResetZoneIds();\r
+\r
+ SERVER_INFO("notify result (%d) > (%d)", policy, result);\r
+ return g_variant_new("(i)", result);\r
+}\r
+\r
+GVariant *CMessageHandler::NotifyAppZoneInfo(GVariant *params)\r
+{\r
+ char *app_id;\r
+ int zone_id;\r
+ int result = 0;\r
+\r
+ g_variant_get(params, "(&si)", &app_id, &zone_id);\r
+\r
+ if (!app_id) {\r
+ result = -1;\r
+ SERVER_INFO("invalid param (%s:%d) - result(%d)", "null", zone_id, result);\r
+ return g_variant_new("(i)", result);\r
+ }\r
+\r
+ m_rsc_mgr->UpdateZoneIds(app_id, zone_id);\r
+\r
+ SERVER_INFO("notify result (%s:%d) > (%d)", app_id, zone_id, result);\r
+ return g_variant_new("(i)", result);\r
+}\r
+\r
+GVariant *CMessageHandler::GetResourceList(GVariant *params)\r
+{\r
+ int category_id;\r
+\r
+ g_variant_get(params, "(i)", &category_id);\r
+\r
+ SERVER_DBG("category (%d)", category_id);\r
+\r
+ GVariantBuilder builder;\r
+ g_variant_builder_init(&builder, G_VARIANT_TYPE("(a(iissi))"));\r
+\r
+ g_variant_builder_open(&builder, G_VARIANT_TYPE("a(iissi)"));\r
+ m_rsc_mgr->GetResourceList(category_id, &builder);\r
+ g_variant_builder_close(&builder);\r
+\r
+ return g_variant_builder_end(&builder);\r
+}\r
+\r
+GVariant *CMessageHandler::GetScalerState(GVariant *params)\r
+{\r
+ SERVER_INFO("GetScalerState");\r
+\r
+ GVariantBuilder builder;\r
+ g_variant_builder_init(&builder, G_VARIANT_TYPE("(a(iiiiis))"));\r
+\r
+ g_variant_builder_open(&builder, G_VARIANT_TYPE("a(iiiiis)"));\r
+ m_rsc_mgr->GetScalerState(&builder);\r
+ g_variant_builder_close(&builder);\r
+\r
+ return g_variant_builder_end(&builder);\r
+}\r
+\r
+GVariant *CMessageHandler::GetAppId(GVariant *params)\r
+{\r
+ int result = 0;\r
+ int handle;\r
+ g_variant_get(params, "(i)", &handle);\r
+\r
+ SERVER_INFO("GetAppId(%d)", handle);\r
+\r
+ CConsumer *consumer = CConsumerContainer::getInstance()->findConsumer(handle);\r
+ if (!consumer) {\r
+ SERVER_ERR("consumer(%d) not found", handle);\r
+ result = -1;\r
+ return g_variant_new("(is)", result, "");\r
+ }\r
+\r
+ return g_variant_new("(is)", result, (consumer->GetAppID().empty()) ? consumer->GetCmdName().c_str() : consumer->GetAppID().c_str());\r
+}\r
+\r
+GVariant *CMessageHandler::GetResourceCollectionState(GVariant *params)\r
+{\r
+ int collection;\r
+\r
+ g_variant_get(params, "(i)", &collection);\r
+\r
+ SERVER_INFO("collection (%d)", collection);\r
+\r
+ GVariantBuilder builder;\r
+ g_variant_builder_init(&builder, G_VARIANT_TYPE("(a(isiiis))"));\r
+\r
+ g_variant_builder_open(&builder, G_VARIANT_TYPE("a(isiiis)"));\r
+ m_rsc_mgr->GetResourceCollectionState(collection, &builder);\r
+ g_variant_builder_close(&builder);\r
+\r
+ return g_variant_builder_end(&builder);\r
+}\r
+\r
+GVariant *CMessageHandler::GetActiveAudioOut(GVariant *params)\r
+{\r
+ int cid;\r
+ int active_audio_out;\r
+\r
+ g_variant_get(params, "(i)", &cid);\r
+\r
+ active_audio_out = m_rsc_mgr->GetActiveAudioOut(cid);\r
+ SERVER_INFO("active_audio_out(%d:%d)", cid, active_audio_out);\r
+\r
+ return g_variant_new("(i)", active_audio_out);\r
+}\r
+\r
+void CMessageHandler::ProcessDbusMessage(CMessage *msg)\r
+{\r
+ GDBusMethodInvocation *invoc = msg->GetMethodInvocation();\r
+ std::string method_name(g_dbus_method_invocation_get_method_name(invoc));\r
+\r
+ auto it = m_dbus_handlers.find(method_name);\r
+ if (it == m_dbus_handlers.end()) {\r
+ SERVER_ERR("handler is not found (%s)", method_name.c_str());\r
+ return;\r
+ }\r
+\r
+ GVariant *params = g_dbus_method_invocation_get_parameters(invoc);\r
+ GVariant *result = (this->*(it->second))(params);\r
+\r
+ g_dbus_method_invocation_return_value(invoc, result);\r
+}\r
+\r
+void CMessageHandler::ProcessInternalMessage(CMessage *msg)\r
+{\r
+ auto it = m_internal_msg_handlers.find(msg->GetName());\r
+ if (it == m_internal_msg_handlers.end()) {\r
+ SERVER_ERR("handler is not found (%s)", msg->GetName().c_str());\r
+ return;\r
+ }\r
+\r
+ (this->*(it->second))(NULL);\r
+}\r
+\r
+void CMessageHandler::EmptyPendingQueue(void)\r
+{\r
+ if (async_pending_queue->length() <= 0)\r
+ return;\r
+\r
+ SERVER_WARN("empty pending queue(%d)", async_pending_queue->length());\r
+ async_queue->push(async_pending_queue);\r
+}\r
+\r
+void CMessageHandler::InsertPendingQueue(CMessage *msg)\r
+{\r
+ SERVER_WARN("msg locked");\r
+ msg->PrintInfo();\r
+ async_pending_queue->push(msg);\r
+}\r
+\r
+int CMessageHandler::ProcessMessage(void)\r
+{\r
+ CMessage *msg = (CMessage*) async_queue->pop();\r
+ assert(msg);\r
+\r
+ if ((m_lock_ctr->GetLockCount() > 0) && m_lock_ctr->IsLocked(msg)) {\r
+ InsertPendingQueue(msg);\r
+ return 0;\r
+ }\r
+\r
+ if (msg->IsUnlockMsg()) {\r
+ EmptyPendingQueue();\r
+ delete msg;\r
+ return 0;\r
+ }\r
+\r
+ switch (msg->GetSender()) {\r
+ case MSG_SENDER_MSGQ:\r
+ ProcessMsgQMessage(msg);\r
+ break;\r
+ case MSG_SENDER_DBUS:\r
+ ProcessDbusMessage(msg);\r
+ break;\r
+ case MSG_SENDER_INTERNAL:\r
+ ProcessInternalMessage(msg);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ delete msg;\r
+\r
+ return 0;\r
+}\r
+\r
+bool CMessageHandler::IsAllResourcesReclaimed(rms_consumer_tobe_returned_s *consumer_info)\r
+{\r
+ for (int idx = 0; idx < consumer_info->n_conflicted; idx++) {\r
+ if (!m_rsc_mgr->IsReclaimed(consumer_info->conflicted_resources[idx].device_id, consumer_info->consumer_id)) {\r
+ SERVER_WARN("IsReclaimed is failed");\r
+ return false;\r
+ }\r
+ }\r
+\r
+ SERVER_WARN("all conflicted resources are freed");\r
+\r
+ return true;\r
+}\r
+\r
+void CMessageHandler::ProcessMessage(CAsyncQueue *queue, CMessage *msg, int cid_requester, int cid_releaser)\r
+{\r
+ rms_msg_request *req = msg->GetRequest();\r
+ rms_msg_response resp;\r
+ int handle;\r
+ char cmd[RMS_NAME_BUF_SIZE] = {0,};\r
+\r
+ switch (req->type) {\r
+ case RMS_REQUEST_RELEASE_RESOURCES:\r
+\r
+ rms_requests_device_s requested_resource;\r
+ memset(&requested_resource, 0, sizeof(rms_requests_device_s));\r
+\r
+ m_ConstructResponse(&resp, req->data_type, RMS_RESPONSE_RELEASE_RESOURCES, req->handle, req->pid);\r
+ m_ConstructRequestedDevice(req, &requested_resource);\r
+\r
+ if ((resp.result = m_rsc_mgr->ReleaseResources(req->handle, &requested_resource)) != RMS_OK)\r
+ SERVER_ERR("failed to release resources requested by (%d)", req->handle);\r
+\r
+ SendResponse(&resp);\r
+\r
+ break;\r
+\r
+ case RMS_REQUEST_UNREGISTER:\r
+\r
+ m_ConstructResponse(&resp, req->data_type, RMS_RESPONSE_UNREGISTER, req->handle, req->pid);\r
+\r
+ SERVER_WARN("unregister requested by handle(%d)", req->handle);\r
+\r
+ if (req->handle == cid_requester) {\r
+ SERVER_WARN("unregister request from requester(%d), send to internal queue", req->handle);\r
+\r
+ PushMessage(queue, msg);\r
+ } else {\r
+ if ((resp.result = m_handle_mgr->RemoveHandle(req->handle, req->pid)) == RMS_OK) {\r
+ m_rsc_mgr->UnregisterConsumer(req->handle);\r
+ }\r
+\r
+ SendResponse(&resp);\r
+ }\r
+ break;\r
+\r
+ case RMS_REQUEST_REGISTER:\r
+ handle = m_handle_mgr->GetNewHandle(req->pid, req->main_priority, req->sub_priority, req->app_pid, req->app_id);\r
+\r
+ resp.result = (handle == RMS_HANDLE_NOT_AVAILABLE) ? RMS_ERROR : RMS_OK;\r
+ m_ConstructResponse(&resp, req->data_type, RMS_RESPONSE_REGISTER, handle, req->pid);\r
+\r
+ if (resp.result == RMS_ERROR) {\r
+ SendResponse(&resp);\r
+ break;\r
+ }\r
+\r
+ if (m_rsc_mgr->RegisterConsumer(handle, req->pid, req->app_id, req->main_priority, req->sub_priority) != RMS_OK)\r
+ SERVER_ERR("failed to add consumer to manager. handle[%d]", handle);\r
+\r
+ rms_get_cmd_name(req->pid, cmd, sizeof(cmd));\r
+\r
+ SERVER_INFO("newly assigned handle(%d) date type(%ld)- pid(%d)-(%s)", resp.handle, req->data_type, req->pid, cmd);\r
+ SendResponse(&resp);\r
+ break;\r
+\r
+ default:\r
+ SERVER_ERR("unexpected request(%d) by handle(%d)/pid(%d)", req->type, req->handle, req->pid);\r
+\r
+ if (req->handle == cid_releaser) {\r
+ m_ConstructResponse(&resp, req->data_type, (rms_response_type_e)req->type, req->handle, req->pid);\r
+ resp.result = RMS_ERROR;\r
+\r
+ SendResponse(&resp);\r
+ } else {\r
+ PushMessage(queue, msg);\r
+ }\r
+ break;\r
+ }\r
+}\r
+\r
+int CMessageHandler::ProcessCallbackMessage(rms_consumer_tobe_returned_s *consumer_info, int requester_cid)\r
+{\r
+ CMessage *msg = NULL;\r
+ int result = RMS_OK;\r
+ CAsyncQueue *queue = new CAsyncQueue();\r
+\r
+ unsigned int timeout_ms = CCallback::GetTimeout();\r
+\r
+ while (!IsAllResourcesReclaimed(consumer_info)) {\r
+ msg = (CMessage*) async_queue->pop(timeout_ms);\r
+\r
+ if (!msg) {\r
+ SERVER_ERR("receive cb request timeout! CID[%d]/PID[%ld]", consumer_info->consumer_id, consumer_info->process_id);\r
+ result = RMS_ERROR;\r
+ goto out;\r
+ }\r
+\r
+ if (msg->GetSender() == MSG_SENDER_DBUS) {\r
+ ProcessDbusMessage(msg);\r
+ } else if (msg->GetSender() == MSG_SENDER_MSGQ) {\r
+ SERVER_WARN("[MSG_SENDER_MSGQ] requester cid %d consumer id %d", requester_cid, consumer_info->consumer_id);\r
+ ProcessMessage(queue, msg, requester_cid, consumer_info->consumer_id);\r
+ } else {\r
+ ProcessInternalMessage(msg);\r
+ }\r
+\r
+ delete msg;\r
+ }\r
+\r
+out:\r
+ async_queue->push_front(queue);\r
+\r
+ delete queue;\r
+\r
+ return result;\r
+}\r
+\r
+int *CMessageHandler::m_SerializeCallbackData(const rms_consumer_tobe_returned_s *consumer_info, int reason, int *data_size)\r
+{\r
+ int num_conflicted_resources = consumer_info->n_conflicted;\r
+\r
+ int *callback_data = (int*) calloc(num_conflicted_resources + 4, sizeof(int));\r
+ assert(callback_data);\r
+\r
+ callback_data[0] = CCallback::ConvertCallbackType(reason);\r
+ callback_data[1] = consumer_info->consumer_id;\r
+ callback_data[2] = consumer_info->process_id;\r
+ callback_data[3] = num_conflicted_resources;\r
+\r
+ for (int res = 0; res < num_conflicted_resources; res++) {\r
+ callback_data[(res+4)] = consumer_info->conflicted_resources[res].virtual_id;\r
+ SERVER_DBG("- virtual_id:%d ", consumer_info->conflicted_resources[res].virtual_id);\r
+ }\r
+\r
+ *data_size = (num_conflicted_resources + 4) * sizeof(int);\r
+\r
+ return callback_data;\r
+}\r
+\r
+bool CMessageHandler::IsValidProcess(int pid)\r
+{\r
+ return rm_is_valid_pid(pid);\r
+}\r
+\r
+bool CMessageHandler::IsValidRequest(int req_type)\r
+{\r
+ return (req_type >= RMS_REQUEST_REGISTER && req_type < RMS_REQUEST_MAX);\r
+}\r
+\r
+int CMessageHandler::ReleaseInvalidProcessResources(int pid, int handle)\r
+{\r
+ m_handle_mgr->RemoveHandle(handle, pid);\r
+ CCallback::RemoveFIFOServerToClient(pid, handle);\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+void CMessageHandler::NotifyConflict(consumer_reclaim_s *conflict_info, int zone_id)\r
+{\r
+ if (!conflict_info)\r
+ return;\r
+\r
+ int consumer_id = -1;\r
+ int device_id = -1;\r
+ int category_id = -1;\r
+ int app_zone_id = -1;\r
+ int n_consumer = conflict_info->ret_quantity;\r
+ CConsumer *consumer = NULL;\r
+\r
+ GError *error = NULL;\r
+ GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);\r
+\r
+ if (!connection) {\r
+ SERVER_ERR("failed to get connection (%s)", (error) ? error->message : "unknown");\r
+ goto out;\r
+ }\r
+\r
+ for (int i = 0; i < n_consumer; i++) {\r
+ consumer_id = conflict_info->consumer_info[i].consumer_id;\r
+ consumer = CConsumerContainer::getInstance()->findConsumer(consumer_id);\r
+\r
+ for (int j = 0; j < conflict_info->consumer_info[i].n_conflicted; j++) {\r
+ device_id = conflict_info->consumer_info[i].conflicted_resources[j].device_id;\r
+ app_zone_id = m_rsc_mgr->GetZoneId(device_id);\r
+ category_id = conflict_info->consumer_info[i].conflicted_resources[j].category_id;\r
+ SERVER_INFO("send resource conflict (%d:%d:%d:%s:%d:%d)",\r
+ category_id, device_id, consumer_id, (consumer->GetAppID().empty()) ? consumer->GetCmdName().c_str() : consumer->GetAppID().c_str(), app_zone_id, zone_id);\r
+ if (!g_dbus_connection_emit_signal(connection,\r
+ NULL,\r
+ RM_DBUS_OBJ_PATH,\r
+ RM_DBUS_INTERFACE_NAME,\r
+ "RscConflicted",\r
+ g_variant_new("(iiisii)", category_id, device_id, consumer_id,\r
+ (consumer->GetAppID().empty()) ? consumer->GetCmdName().c_str() : consumer->GetAppID().c_str(), app_zone_id, zone_id),\r
+ &error)) {\r
+ SERVER_ERR("failed to send resource conflict (%d:%d:%d:%s)-%s", category_id, device_id, consumer_id,\r
+ (consumer->GetAppID().empty()) ? consumer->GetCmdName().c_str():consumer->GetAppID().c_str(), (error) ? error->message : "unknown");\r
+ }\r
+ }\r
+ }\r
+out:\r
+ if (error)\r
+ g_error_free(error);\r
+}\r
+\r
+int CMessageHandler::ReclaimResources(int reason, int requester_cid, int requester_zone_id, consumer_reclaim_s *conflict_info, bool *need_response)\r
+{\r
+ int num_consumers = conflict_info->ret_quantity;\r
+ int data_size = 0;\r
+ int *callback_data = NULL;\r
+ char cmd[RMS_NAME_BUF_SIZE] = {0,};\r
+ int err = 0;\r
+ int cid = 0;\r
+ int pid = 0;\r
+\r
+ SERVER_WARN("start to reclaim - retirable consumers : (%d)", num_consumers);\r
+\r
+ if (num_consumers > 0)\r
+ NotifyConflict(conflict_info, requester_zone_id);\r
+\r
+ for (int i = 0; i < num_consumers; i++) {\r
+ pid = (int) conflict_info->consumer_info[i].process_id;\r
+ cid = conflict_info->consumer_info[i].consumer_id;\r
+\r
+ if (!IsValidProcess(pid)) {\r
+ SERVER_ERR("handle(%d)/pid(%d) terminated", cid, pid);\r
+ m_rsc_mgr->ReleaseResourcesOfPid(pid);\r
+ ReleaseInvalidProcessResources(pid, cid);\r
+ continue;\r
+ }\r
+\r
+ SERVER_DBG("[%d]th cid[%d]/rscs[%d]", i+1, cid, conflict_info->consumer_info[i].n_conflicted);\r
+\r
+ callback_data = m_SerializeCallbackData(&conflict_info->consumer_info[i], reason, &data_size);\r
+\r
+ if (CCallback::SendCallbackMessage(cid, pid, (void*) callback_data, data_size, &err) != RMS_OK) {\r
+ if (err == ENXIO) { //ENXIO No such device or address\r
+ SERVER_ERR("Process cannot get callback (CID:%d)/(PID:%d)", cid, pid);\r
+ m_rsc_mgr->ReleaseResourcesOfPid(pid);\r
+ ReleaseInvalidProcessResources(pid, cid);\r
+ free(callback_data);\r
+ continue;\r
+ }\r
+\r
+ if (err == ENOENT && !IsRegisteredHandle(cid)) {\r
+ SERVER_ERR("already unregistred (%d)", cid);\r
+ free(callback_data);\r
+ continue;\r
+ }\r
+\r
+ SERVER_ERR("failed to send callback message to (CID:%d)/(PID:%d), errno(%d)", cid, pid, err);\r
+ free(callback_data);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ SERVER_WARN("[%d]th callback message sent to CID[%d]/PID[%d]/RSCS[%d]", i+1, cid, pid, conflict_info->consumer_info[i].n_conflicted);\r
+\r
+ if (ProcessCallbackMessage(&conflict_info->consumer_info[i], requester_cid) != RMS_OK) {\r
+ if (!IsValidProcess(pid)) {\r
+ SERVER_ERR("handle(%d)/pid(%d) terminated", cid, pid);\r
+ m_rsc_mgr->ReleaseResourcesOfPid(pid);\r
+ ReleaseInvalidProcessResources(pid, cid);\r
+ free(callback_data);\r
+\r
+ if (!IsRegisteredHandle(requester_cid)) {\r
+ SERVER_ERR("requester(%d:%d) terminated as well", pid, requester_cid);\r
+ *need_response = false;\r
+ return RMS_ERROR;\r
+ }\r
+ continue;\r
+ }\r
+\r
+ rms_get_cmd_name(pid, cmd, sizeof(cmd));\r
+ SERVER_ERR("failed to process callback request from : (%s) /(CID:%d)/(PID:%d)", cmd, cid, pid);\r
+\r
+ rms_display_timeout_error_popup(RMS_ALARM_NO_DEALLOCATION, conflict_info->consumer_info[i]);\r
+ int ret = rms_report_emergency(cid, pid, RMS_EMERGENCY_CONSUMER_NOT_RESPONDING);\r
+\r
+ SERVER_ERR("release resources of cosumer(%d) forcely", pid);\r
+ m_rsc_mgr->UnregisterConsumer(cid);\r
+ m_handle_mgr->RemoveHandle(cid, pid);\r
+\r
+ free(callback_data);\r
+ return ret;\r
+ }\r
+\r
+ free(callback_data);\r
+ }\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+int CMessageHandler::SendResponse(rms_msg_response *response)\r
+{\r
+ return msgq_tx->send(response);\r
+}\r
+\r
+int CMessageHandler::PushMessage(CAsyncQueue *queue, CMessage *msg)\r
+{\r
+ CMessage *msg_copy = new CMessage(msg->GetRequest());\r
+ rms_msg_request *req = msg->GetRequest();\r
+ SERVER_INFO("push_front msg type(%d)-pid(%d)-cid(%d)", req->type, req->pid, req->handle);\r
+\r
+ queue->push_front(msg_copy);\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+void CMessageHandler::m_ConstructResponse(rms_msg_response *response, int data_type, rms_response_type_e msg_type, int handle, int pid)\r
+{\r
+ assert(response);\r
+\r
+ response->data_type = data_type;\r
+ response->type = msg_type;\r
+ response->handle = handle;\r
+ response->pid = pid;\r
+}\r
+\r
+void CMessageHandler::NotifyWatchdog(void)\r
+{\r
+ if (!async_queue)\r
+ return;\r
+\r
+ SERVER_INFO("push watchdog msg");\r
+ async_queue->push(new CMessage("NotifyWatchdog"));\r
+}\r
+\r
+GVariant *CMessageHandler::NotifyWatchdog(GVariant *params)\r
+{\r
+ SERVER_INFO("send watchdog notify completed");\r
+ return NULL;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <assert.h>\r
+#include <errno.h>\r
+#include <sys/types.h>\r
+#include <sys/ipc.h>\r
+#include <sys/msg.h>\r
+#include <unistd.h>\r
+\r
+#include <rms_debug.h>\r
+#include <CMessageQueue.h>\r
+\r
+CMessageQueue::CMessageQueue(msgq_type_e type)\r
+{\r
+ msgq_type = type;\r
+\r
+ if (init() != RMS_OK) {\r
+ SERVER_ERR("failed to initialize message queue(%d)", type);\r
+ assert(0 && "failed to initialize message queue");\r
+ }\r
+}\r
+\r
+CMessageQueue::~CMessageQueue(void)\r
+{\r
+}\r
+\r
+int CMessageQueue::init(void)\r
+{\r
+ int key = getKey(msgq_type);\r
+\r
+ msgq_id = msgget((key_t) key, 0666 | IPC_CREAT);\r
+ if (msgq_id == -1) {\r
+ SERVER_ERR("failed to create a message queue (%d), errno(%d)", key, errno);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ struct msqid_ds queue_stat;\r
+ long prev_size = 0;\r
+\r
+ if (msgctl(msgq_id, IPC_STAT, &queue_stat) != 0) {\r
+ SERVER_ERR("failed to get queue info (%d:%d), errno(%d)", key, msgq_id, errno);\r
+ goto out;\r
+ }\r
+\r
+ prev_size = queue_stat.msg_qbytes;\r
+ queue_stat.msg_qbytes = msgq_size;\r
+\r
+ if (msgctl(msgq_id, IPC_SET, &queue_stat) != 0) {\r
+ SERVER_ERR("failed to set queue info (%d:%d), errno(%d)", key, msgq_id, errno);\r
+ goto out;\r
+ }\r
+\r
+ SERVER_INFO("msgq(%d:%d) size changed (%ld) -> (%ld)", key, msgq_id, prev_size, msgq_size);\r
+\r
+out:\r
+ return RMS_OK;\r
+}\r
+\r
+int CMessageQueue::send(rms_msg_response *response)\r
+{\r
+ int retry = 0;\r
+\r
+ while (msgsnd(msgq_id, (void*) response, sizeof(rms_msg_response) - sizeof(long), 0) == -1) {\r
+ SERVER_ERR("failed to send response message (%d), retry(%d) - type(%d)/cid(%d)", errno, retry, response->type, response->handle);\r
+\r
+ if (errno == EIDRM) { // errno 43 : identifier removed\r
+ SERVER_ERR("msgid removed from system");\r
+ if (recover() != RMS_OK)\r
+ return RMS_ERROR;\r
+ } else if ((errno == EINVAL) && (response->data_type > 0)) {\r
+ SERVER_ERR("msgid might be removed from system");\r
+ if (recover() != RMS_OK) {\r
+ return RMS_ERROR;\r
+ }\r
+ }\r
+\r
+ if (retry >= 5) { //timeout\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ usleep(20*1000); // 20ms\r
+ retry++;\r
+ }\r
+\r
+ return RMS_OK;\r
+\r
+}\r
+\r
+int CMessageQueue::receive(rms_msg_request *request, int msg_type)\r
+{\r
+ int ret = -1;\r
+ ret = msgrcv(msgq_id, (void*) request, sizeof(rms_msg_request) - sizeof(long), msg_type, 0);\r
+\r
+ if (ret == -1) {\r
+ SERVER_ERR("failed to receive msg(%d:%d). errno(%d)", msgq_type, msgq_id, errno);\r
+\r
+ if (errno == EIDRM) { // errno 43 : identifier removed\r
+ SERVER_ERR("WARNING! msgq(%d:%d) removed from system", msgq_type, msgq_id);\r
+ recover();\r
+ }\r
+\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+int CMessageQueue::recover(void)\r
+{\r
+ int key = getKey(msgq_type);\r
+\r
+ msgq_id = msgget((key_t) key, 0666 | IPC_CREAT);\r
+\r
+ if (msgq_id == -1) {\r
+ SERVER_ERR("failed to get new msgq_id, key(%d), errno(%d)", key, errno);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ SERVER_ERR("message queue recovered - (%d:%d)", key, msgq_id);\r
+ return RMS_OK;\r
+}\r
+\r
+int CMessageQueue::getKey(msgq_type_e type)\r
+{\r
+ return (type == MSG_QUEUE_RX) ? key_rx : key_tx;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <assert.h>\r
+#include <glib.h>\r
+\r
+#include <rms_debug.h>\r
+#include <CDebugUtils.h>\r
+#include <CQueryHandler.h>\r
+\r
+CQueryHandler::CQueryHandler(CResourceManager *rsc_mgr)\r
+{\r
+ assert(rsc_mgr);\r
+ m_rsc_mgr = rsc_mgr;\r
+}\r
+\r
+CQueryHandler::~CQueryHandler(void)\r
+{\r
+}\r
+\r
+int CQueryHandler::GetAnswer(rms_msg_request *request, int *answer_out)\r
+{\r
+ int result = RMS_OK;\r
+ int answer = 0;\r
+ char process_name[RMS_NAME_BUF_SIZE] = {0,};\r
+\r
+ switch (request->sub_type) {\r
+ case RMS_QUERY_ALLOCATION:\r
+ result = m_rsc_mgr->IsCategoryAvailableToUse(request, &answer);\r
+ *answer_out = answer;\r
+ break;\r
+ case RMS_QUERY_TERMINATE:\r
+ rms_get_cmd_name(request->pid, process_name, RMS_NAME_BUF_SIZE);\r
+ result = RMS_OK;\r
+ *answer_out = process_htable_contains(process_name);\r
+ break;\r
+ case RMS_QUERY_ACTIVE_DECS:\r
+ *answer_out = m_rsc_mgr->GetActiveDecoderNum();\r
+ result = RMS_OK;\r
+ break;\r
+ default:\r
+ SERVER_ERR("not defined query type (%d)", request->sub_type);\r
+ break;\r
+ }\r
+\r
+ return result;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <iostream>\r
+\r
+#include <rms_debug.h>\r
+#include "CSysInfo.h"\r
+#include "CRequester.h"\r
+#include "CRequest.h"\r
+\r
+CRequest::CRequest(CRequester *requester)\r
+:m_requester(requester)\r
+{\r
+ m_device_id = 0;\r
+ m_category_id = 0;\r
+ m_category_option = 0;\r
+ m_category = RMS_CATEGORY_NONE;\r
+ m_result = RMS_ERROR;\r
+ m_candidate_device = RMS_DEVICE_NONE;\r
+ m_allocated_device = RMS_DEVICE_NONE;\r
+ m_virtual_device = RMS_DEVICE_NONE;\r
+}\r
+\r
+CRequest::~CRequest()\r
+{\r
+}\r
+\r
+CRequester *CRequest::getRequester(void)\r
+{\r
+ return m_requester;\r
+}\r
+\r
+int CRequest::ToMultiviewZoneId(int category_option)\r
+{\r
+ const int ZONE_INFO = 0x1E00000;\r
+ int zone_id = ((category_option & ZONE_INFO) >> 21);\r
+ return zone_id;\r
+}\r
+\r
+void CRequest::SetCategory(int category_id, int category_option)\r
+{\r
+ m_category_id = category_id;\r
+ m_category_option = category_option;\r
+ m_category = ToResourceCategory(category_id, category_option);\r
+ m_mixing_mode = ToMixingMode(category_id, category_option);\r
+ m_mv_zone_id = ToMultiviewZoneId(category_option);\r
+}\r
+\r
+void CRequest::SetState(int req_state)\r
+{\r
+ m_state = (rms_requests_resource_state_e) req_state;\r
+}\r
+\r
+void CRequest::SetResult(rms_return_code_e req_result)\r
+{\r
+ m_result = req_result;\r
+}\r
+\r
+rms_return_code_e CRequest::GetResult(void)\r
+{\r
+ return m_result;\r
+}\r
+\r
+rms_rsc_category_e CRequest::GetCategory(void)\r
+{\r
+ return m_category;\r
+}\r
+\r
+bool CRequest::IsMainDeviceRequest(void)\r
+{\r
+ if (m_state == RMS_STATE_EXCLUSIVE_AUTO)\r
+ return false;\r
+\r
+ SERVER_INFO("m_category_id(%d), option(%d)", m_category_id, m_category_option);\r
+\r
+ if (IsSupportedCategory(m_category_option)) {\r
+ if ((m_category_option & RMS_DEVICE_OPT_MAIN) || (m_category_option & RMS_FORCE_TO_MAIN))\r
+ return true;\r
+ }\r
+\r
+ if ((m_category_id == RMS_CATEGORY_VIDEO_DECODER) && (m_category_option != RMS_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED)) {\r
+ return (m_category_option & RMS_DEVICE_OPT_MAIN);\r
+ }\r
+\r
+ if (m_category_id == RMS_CATEGORY_AUDIO_DECODER) {\r
+ if (m_category_option == RMS_CATEGORY_AUDIO_DECODER_NOT_SUPPORTED)\r
+ return false;\r
+ if (m_category_option == RMS_DEVICE_OPT_NONE)\r
+ return true;\r
+\r
+ return (m_category_option & RMS_DEVICE_OPT_MAIN);\r
+ }\r
+\r
+ if (m_category_id == RMS_CATEGORY_MJPEG_DECODER)\r
+ return (m_category_option & RMS_DEVICE_OPT_MAIN);\r
+\r
+ if (m_category == RMS_CATEGORY_SCALER_MULTIVIEW)\r
+ return (m_category_option & RMS_DEVICE_OPT_MAIN);\r
+\r
+ return false;\r
+}\r
+\r
+bool CRequest::IsAIDeviceRequest(void)\r
+{\r
+ if (m_state == RMS_STATE_EXCLUSIVE_AUTO)\r
+ return false;\r
+\r
+ if ((m_category_id == RMS_CATEGORY_VIDEO_DECODER) && (m_category_option != RMS_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED))\r
+ return (m_category_option & RMS_VIDEO_DEC_OPT_AI);\r
+\r
+ return false;\r
+}\r
+\r
+bool CRequest::IsSubDeviceRequest(void)\r
+{\r
+ if (m_state == RMS_STATE_EXCLUSIVE_AUTO)\r
+ return false;\r
+\r
+ //SERVER_DBG("m_category_id(%d), option(%d)", m_category_id, m_category_option);\r
+\r
+ if (IsSupportedCategory(m_category_option)) {\r
+ if ((m_category_option & RMS_DEVICE_OPT_SUB) || (m_category_option & RMS_FORCE_TO_SUB))\r
+ return true;\r
+ }\r
+\r
+ if ((m_category_id == RMS_CATEGORY_VIDEO_DECODER_SUB) && (m_category_option != RMS_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED))\r
+ return (m_category_option & RMS_DEVICE_OPT_SUB);\r
+\r
+ if (m_category_id == RMS_CATEGORY_AUDIO_DECODER_SUB) {\r
+ if (m_category_option == RMS_CATEGORY_AUDIO_DECODER_NOT_SUPPORTED)\r
+ return false;\r
+ if (m_category_option == RMS_DEVICE_OPT_NONE)\r
+ return true;\r
+\r
+ return (m_category_option & RMS_DEVICE_OPT_SUB);\r
+ }\r
+\r
+ if (m_category_id == RMS_CATEGORY_MJPEG_DECODER)\r
+ return (m_category_option & RMS_DEVICE_OPT_SUB);\r
+\r
+ if (m_category == RMS_CATEGORY_SCALER_MULTIVIEW)\r
+ return (m_category_option & RMS_DEVICE_OPT_SUB);\r
+\r
+ return false;\r
+}\r
+\r
+rms_rsc_category_e CRequest::ToVideoDecoderCategory(int category, int category_option, bool force_main, bool force_sub)\r
+{\r
+ rms_rsc_category_e result = RMS_CATEGORY_NONE;\r
+\r
+ if (category_option == RMS_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED) {\r
+ result = RMS_CATEGORY_NONE;\r
+ } else if ((category_option > RMS_CATEGORY_VIDEO_DECODER_OPTION) && (category_option < RMS_CATEGORY_VIDEO_DECODER_OPTION_MAX)) {\r
+ result = (rms_rsc_category_e) category_option;\r
+ } else {\r
+ if (category == RMS_CATEGORY_VIDEO_DECODER) {\r
+ result = (rms_rsc_category_e) ((force_sub) ? RMS_CATEGORY_VIDEO_DECODER_SUB : category);\r
+ } else if (category == RMS_CATEGORY_VIDEO_DECODER_SUB) {\r
+ result = (rms_rsc_category_e) ((force_main) ? (rms_rsc_category_e) RMS_CATEGORY_VIDEO_DECODER : category);\r
+ } else {\r
+ result = (rms_rsc_category_e) category;\r
+ }\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+rms_rsc_category_e CRequest::ToImageDecoderCategory(int category, int category_option)\r
+{\r
+ rms_rsc_category_e result = RMS_CATEGORY_NONE;\r
+\r
+ SERVER_INFO("category(%d)/category_option(%d)", category, category_option);\r
+\r
+ if (category_option == RMS_CATEGORY_IMAGE_DECODER_NOT_SUPPORTED) {\r
+ result = RMS_CATEGORY_NONE;\r
+ } else if ((category_option > RMS_CATEGORY_HEIC_DECODER_OPTION) && (category_option < RMS_CATEGORY_HEIC_DECODER_OPTION_MAX)) {\r
+ result = (rms_rsc_category_e) category_option;\r
+ } else if ((category_option > RMS_CATEGORY_JPEG_DECODER_OPTION) && (category_option < RMS_CATEGORY_JPEG_DECODER_OPTION_MAX)) {\r
+ result = (rms_rsc_category_e) category_option;\r
+ } else {\r
+ result = (rms_rsc_category_e) category;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+rms_rsc_category_e CRequest::ToJpegDecoderCategory(int category, int category_option)\r
+{\r
+ rms_rsc_category_e result = RMS_CATEGORY_NONE;\r
+\r
+ SERVER_INFO("category(%d)/category_option(%d)", category, category_option);\r
+\r
+ if (category_option == RMS_CATEGORY_JPEG_DECODER_NOT_SUPPORTED) {\r
+ result = RMS_CATEGORY_NONE;\r
+ } else if ((category_option > RMS_CATEGORY_JPEG_DECODER_OPTION) && (category_option < RMS_CATEGORY_JPEG_DECODER_OPTION_MAX)) {\r
+ result = (rms_rsc_category_e) category_option;\r
+ } else {\r
+ result = (rms_rsc_category_e) category;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+rms_rsc_category_e CRequest::ToMJpegDecoderCategory(int category, int category_option)\r
+{\r
+ rms_rsc_category_e result = RMS_CATEGORY_NONE;\r
+\r
+ if (category_option == RMS_CATEGORY_MJPEG_DECODER_NOT_SUPPORTED) {\r
+ result = RMS_CATEGORY_NONE;\r
+ } else if ((category_option > RMS_CATEGORY_MJPEG_DECODER_OPTION) && (category_option < RMS_CATEGORY_MJPEG_DECODER_OPTION_MAX)) {\r
+ result = (rms_rsc_category_e) category_option;\r
+ } else {\r
+ result = (rms_rsc_category_e)category;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+rms_rsc_category_e CRequest::ToAudioDecoderCategory(int category, int category_option, bool force_main, bool force_sub)\r
+{\r
+ rms_rsc_category_e result = RMS_CATEGORY_NONE;\r
+ bool support_mixing = CSysInfo::GetInstance()->IsAudioMixingSupported();\r
+\r
+ if (category_option == RMS_CATEGORY_AUDIO_DECODER_NOT_SUPPORTED) {\r
+ result = RMS_CATEGORY_NONE;\r
+ } else if (category_option == RMS_CATEGORY_NOT_PERMITTED) {\r
+ result = RMS_CATEGORY_NOT_PERMITTED;\r
+ } else if (support_mixing && (category_option > RMS_CATEGORY_AUDIO_DECODER_OPTION && category_option < RMS_CATEGORY_AUDIO_DECODER_OPTION_MAX)) {\r
+ result = (rms_rsc_category_e) category_option;\r
+ } else {\r
+ if (category == RMS_CATEGORY_AUDIO_DECODER) {\r
+ result = (rms_rsc_category_e) ((force_sub) ? RMS_CATEGORY_AUDIO_DECODER_SUB : category);\r
+ } else if (category == RMS_CATEGORY_AUDIO_DECODER_SUB) {\r
+ result = (rms_rsc_category_e) ((force_main) ? RMS_CATEGORY_AUDIO_DECODER : category);\r
+ } else {\r
+ result = (rms_rsc_category_e) category;\r
+ }\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+rms_rsc_category_e CRequest::ToScalerCategory(int category, int category_option, bool force_main, bool force_sub)\r
+{\r
+ if (category_option == RMS_CATEGORY_NOT_PERMITTED)\r
+ return (rms_rsc_category_e) category_option;\r
+\r
+ if (force_sub)\r
+ return RMS_CATEGORY_SCALER_SUB;\r
+\r
+ if (force_main)\r
+ return RMS_CATEGORY_SCALER;\r
+\r
+ if (category > RMS_CATEGORY_SCALER_OPTION && category < RMS_CATEGORY_SCALER_OPTION_MAX)\r
+ return (rms_rsc_category_e) category_option;\r
+\r
+ if (category_option > RMS_CATEGORY_SCALER_OPTION && category_option < RMS_CATEGORY_SCALER_OPTION_MAX)\r
+ return (rms_rsc_category_e) category_option;\r
+\r
+ return (rms_rsc_category_e) category;\r
+}\r
+\r
+rms_rsc_category_e CRequest::ToAudioOutCategory(int category, int category_option, bool force_main, bool force_sub)\r
+{\r
+ if (category_option == RMS_CATEGORY_NOT_PERMITTED)\r
+ return (rms_rsc_category_e) category_option;\r
+\r
+ if (force_sub)\r
+ return RMS_CATEGORY_AUDIO_SUB_OUT;\r
+\r
+ if (force_main)\r
+ return RMS_CATEGORY_AUDIO_MAIN_OUT;\r
+\r
+ return (rms_rsc_category_e) category;\r
+}\r
+\r
+bool CRequest::IsSupportedCategory(int category_option)\r
+{\r
+ bool result = true;\r
+\r
+ switch (category_option) {\r
+ case RMS_CATEGORY_IMAGE_DECODER_NOT_SUPPORTED:\r
+ case RMS_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED:\r
+ case RMS_CATEGORY_JPEG_DECODER_NOT_SUPPORTED:\r
+ case RMS_CATEGORY_MJPEG_DECODER_NOT_SUPPORTED:\r
+ case RMS_CATEGORY_NOT_PERMITTED:\r
+ result = false;\r
+ break;\r
+ default:\r
+ result = true;\r
+ break;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+int CRequest::UnmaskMainSubOptions(int category_option)\r
+{\r
+ int result = category_option;\r
+\r
+ result = (result & ~RMS_DEVICE_OPT_MAIN);\r
+ result = (result & ~RMS_DEVICE_OPT_SUB);\r
+\r
+ return result;\r
+}\r
+\r
+int CRequest::UnmaskMixingOptions(int category_option)\r
+{\r
+ int result = category_option;\r
+\r
+ result = (result & ~RMS_MIXING_OPT_DEFAULT);\r
+ result = (result & ~RMS_MIXING_OPT_MULTIVIEW);\r
+ result = (result & ~RMS_MIXING_OPT_INTERACTION_SOUND);\r
+\r
+ return result;\r
+}\r
+\r
+int CRequest::UnmaskForceOptions(int category_option)\r
+{\r
+ int result = category_option;\r
+\r
+ result = (result & ~RMS_FORCE_TO_MAIN);\r
+ result = (result & ~RMS_FORCE_TO_SUB);\r
+\r
+ return result;\r
+}\r
+\r
+int CRequest::UnmaskMVZoneInfo(int category_option)\r
+{\r
+ const int ZONE_INFO = 0x1E00000;\r
+\r
+ return (category_option & ~ZONE_INFO);\r
+}\r
+\r
+rms_rsc_category_e CRequest::ToResourceCategory(int category, int category_option)\r
+{\r
+ rms_rsc_category_e result = RMS_CATEGORY_NONE;\r
+ bool supported = IsSupportedCategory(category_option);\r
+ bool force_main = false;\r
+ bool force_sub = false;\r
+\r
+ if (supported) {\r
+ force_main = (category_option & RMS_FORCE_TO_MAIN);\r
+ force_sub = (category_option & RMS_FORCE_TO_SUB);\r
+ category_option = UnmaskMainSubOptions(category_option);\r
+ }\r
+\r
+ switch (category) {\r
+ case RMS_CATEGORY_VIDEO_DECODER:\r
+ case RMS_CATEGORY_VIDEO_DECODER_SUB:\r
+ if (supported) {\r
+ category_option = UnmaskMVZoneInfo(category_option);\r
+ category_option = (category_option & ~RMS_VIDEO_DEC_OPT_AI);\r
+ category_option = UnmaskForceOptions(category_option);\r
+ }\r
+ result = ToVideoDecoderCategory(category, category_option, force_main, force_sub);\r
+ break;\r
+ case RMS_CATEGORY_JPEG_DECODER:\r
+ result = ToJpegDecoderCategory(category, category_option);\r
+ break;\r
+ case RMS_CATEGORY_MJPEG_DECODER:\r
+ if (supported)\r
+ category_option = UnmaskMVZoneInfo(category_option);\r
+\r
+ result = ToMJpegDecoderCategory(category, category_option);\r
+ break;\r
+ case RMS_CATEGORY_IMAGE_DECODER:\r
+ result = ToImageDecoderCategory(category, category_option);\r
+ break;\r
+ case RMS_CATEGORY_AUDIO_DECODER:\r
+ case RMS_CATEGORY_AUDIO_DECODER_SUB:\r
+ if (supported) {\r
+ category_option = UnmaskMixingOptions(category_option);\r
+ category_option = UnmaskForceOptions(category_option);\r
+ }\r
+\r
+ result = ToAudioDecoderCategory(category, category_option, force_main, force_sub);\r
+ break;\r
+ case RMS_CATEGORY_SCALER:\r
+ case RMS_CATEGORY_SCALER_SUB:\r
+ if (supported)\r
+ category_option = UnmaskMVZoneInfo(category_option);\r
+\r
+ result = ToScalerCategory(category, category_option, force_main, force_sub);\r
+ break;\r
+ case RMS_CATEGORY_AUDIO_MAIN_OUT:\r
+ case RMS_CATEGORY_AUDIO_SUB_OUT:\r
+ result = ToAudioOutCategory(category, category_option, force_main, force_sub);\r
+ break;\r
+ default:\r
+ result = (rms_rsc_category_e) category;\r
+ break;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+rms_mixing_mode_e CRequest::ToMixingMode(int category, int category_option)\r
+{\r
+ if (category != RMS_CATEGORY_AUDIO_DECODER && category != RMS_CATEGORY_AUDIO_DECODER_SUB)\r
+ return RMS_MIXING_MODE_DEFAULT;\r
+\r
+ if (category_option & RMS_MIXING_OPT_MULTIVIEW)\r
+ return RMS_MIXING_MODE_MULTIVIEW;\r
+\r
+ if (category_option & RMS_MIXING_OPT_INTERACTION_SOUND)\r
+ return RMS_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+ return RMS_MIXING_MODE_DEFAULT;\r
+}\r
+\r
+void CRequest::PrintResult(void)\r
+{\r
+ SERVER_WARN("result (%d) - con(%d:%s) / cat(%d) / req(%d:%d) / devId(%d) / vId(%d) / rsn(%d)",\r
+ m_result,\r
+ m_requester->getHandle(),\r
+ m_requester->getAppId().empty() ? m_requester->GetCmdName().c_str() : m_requester->getAppId().c_str(),\r
+ m_category, m_category_id, m_category_option, m_allocated_device, m_virtual_device, m_reason);\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "CDebugUtils.h"\r
+#include "CRequester.h"\r
+\r
+CRequester::CRequester()\r
+{\r
+ m_handle = 0;\r
+ m_pid = 0;\r
+ m_main_priority = 0;\r
+ m_sub_priority = 0;\r
+ m_app_id.assign("");\r
+}\r
+\r
+CRequester::CRequester(rms_msg_request *req)\r
+{\r
+ m_handle = req->handle;\r
+ m_pid = req->pid;\r
+ m_main_priority = req->main_priority;\r
+ m_sub_priority = req->sub_priority;\r
+ m_app_id.assign(req->app_id);\r
+ SetCmdName(req->pid);\r
+}\r
+\r
+CRequester::~CRequester()\r
+{\r
+}\r
+\r
+void CRequester::SetCmdName(int pid)\r
+{\r
+ char cmd_name[512] = {0, };\r
+ std::string delimiter = "/";\r
+\r
+ rms_get_cmd_name(pid, cmd_name, 512);\r
+ m_cmd_name.assign(cmd_name);\r
+ m_cmd_name = m_cmd_name.substr(m_cmd_name.find_last_of(delimiter) + 1, m_cmd_name.length());\r
+}\r
+\r
+int CRequester::getHandle(void)\r
+{\r
+ return m_handle;\r
+}\r
+\r
+int CRequester::getPid(void)\r
+{\r
+ return m_pid;\r
+}\r
+\r
+int CRequester::getMainPriority(void)\r
+{\r
+ return m_main_priority;\r
+}\r
+\r
+int CRequester::getSubPriority(void)\r
+{\r
+ return m_sub_priority;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <glib.h>\r
+#include <vconf.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <iostream>\r
+#include <assert.h>\r
+#include <trace.h>\r
+#include <dlfcn.h>\r
+\r
+#include <CResourceService.h>\r
+#include <CDebugUtils.h>\r
+#include <rms_debug.h>\r
+#include <rms_type.h>\r
+#include <CMessageHandler.h>\r
+#include <CResourceManager.h>\r
+\r
+#define RM_SERVER_SMART_DEADLOCK_WATCHDOG_TIME_90_SEC 90\r
+#define RM_SERVER_WATCHDOG_TIME_10000_MSEC 10000\r
+#define RM_SERVER_INVALID_TABLE_TIME_30000_MSEC 30000\r
+\r
+int CResourceService::Init(GMainLoop *main_loop)\r
+{\r
+ CResourceManager *rsc_mgr = new CResourceManager();\r
+ if (rsc_mgr->RegisterResources() != RMS_OK) {\r
+ SERVER_ERR("RegisterResources is failed");\r
+ g_timeout_add(RM_SERVER_INVALID_TABLE_TIME_30000_MSEC, InvalidResourceTableMsgCallback, NULL);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ m_msg_h = new CMessageHandler(rsc_mgr);\r
+ if (m_msg_h->Run() != RMS_OK) {\r
+ SERVER_ERR("RUN failed");\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ SERVER_INFO("Done");\r
+ return RMS_OK;\r
+}\r
+\r
+int CResourceService::IsFirstLaunch(void)\r
+{\r
+ const char *vconf_key = "memory/rsc_mgr/is_launched_before";\r
+ int is_launched_before = 0;\r
+\r
+ if (vconf_get_int(vconf_key, &is_launched_before) != 0)\r
+ SERVER_ERR("Failed to get %s", vconf_key);\r
+\r
+ if (is_launched_before == 1) {\r
+ SERVER_ERR("!!!!! Resource Manager 2nd Launch !!!!!");\r
+ return 0;\r
+ }\r
+\r
+ if (vconf_set_int(vconf_key, 1) != 0)\r
+ SERVER_ERR("Failed to set %s", vconf_key);\r
+\r
+ return 1;\r
+}\r
+\r
+void CResourceService::RequestColdPowerOff(void)\r
+{\r
+ const char *vconf_request_cold_poweroff = "memory/boot/cold_poweroff_request_pkg";\r
+\r
+ if (vconf_set_str(vconf_request_cold_poweroff, "resource-manager") != 0) {\r
+ SERVER_ERR("Failed to set %s", vconf_request_cold_poweroff);\r
+ }\r
+}\r
+\r
+void CResourceService::CreateWatchDogTimer(void)\r
+{\r
+}\r
+\r
+void CResourceService::SetVIPProcess(void)\r
+{\r
+ void *handle;\r
+ void (*vip_func)(void);\r
+\r
+ handle = dlopen("/lib/libproc-stat.so.5", RTLD_LAZY);\r
+\r
+ if (!handle) {\r
+ SERVER_ERR("failed to open libproc-stat.so (%s)", dlerror());\r
+ return;\r
+ }\r
+\r
+ *(void**)&vip_func = dlsym(handle, "proc_stat_set_vip_process");\r
+\r
+ if (!vip_func) {\r
+ SERVER_ERR("failed to find proc_stat_set_vip_process");\r
+ dlclose(handle);\r
+ return;\r
+ }\r
+\r
+ SERVER_INFO("set vip process");\r
+ vip_func();\r
+ dlclose(handle);\r
+}\r
+\r
+gboolean CResourceService::WatchDogCallback(gpointer data)\r
+{\r
+ return G_SOURCE_CONTINUE;\r
+}\r
+\r
+gboolean CResourceService::InvalidResourceTableMsgCallback(gpointer data)\r
+{\r
+ SERVER_ERR("resource table not loaded!");\r
+ rms_print_model_info();\r
+ return G_SOURCE_CONTINUE;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <iostream>\r
+#include <assert.h>\r
+#include <system_info.h>\r
+#include <rms_debug.h>\r
+#include <CSysInfo.h>\r
+\r
+CSysInfo *CSysInfo::m_instance = NULL;\r
+\r
+CSysInfo *CSysInfo::GetInstance(void)\r
+{\r
+ if (!m_instance) {\r
+ m_instance = new(std::nothrow) CSysInfo;\r
+ assert(m_instance);\r
+ }\r
+\r
+ return m_instance;\r
+}\r
+\r
+bool CSysInfo::IsAudioMixingSupported(void)\r
+{\r
+ static bool init = false;\r
+ bool supported = false;\r
+\r
+ if (init)\r
+ return m_support_audio_mixing;\r
+\r
+ if (system_info_get_custom_bool("com.samsung/featureconf/multiview.dualsound", &supported) != SYSTEM_INFO_ERROR_NONE) {\r
+ SERVER_ERR("failed to get com.samsung/featureconf/multiview.dualsound");\r
+ return m_support_audio_mixing;\r
+ }\r
+\r
+ m_support_audio_mixing = supported;\r
+ init = true;\r
+ SERVER_INFO("multiview.dualsound (%d)", supported);\r
+ return m_support_audio_mixing;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <sys/types.h>\r
+#include <sys/ipc.h>\r
+#include <sys/msg.h>\r
+#include <errno.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <sys/stat.h>\r
+#include <unistd.h>\r
+#include <rms_debug.h>\r
+#include <rms_type.h>\r
+#include <unistd.h>\r
+\r
+#define RM_MSGQ_KEY_TX 8212\r
+#define RM_MSGQ_KEY_RX 8211\r
+\r
+static int _is_symlink_file(const char *path)\r
+{\r
+ struct stat st;\r
+ if (lstat(path, &st) == -1) {\r
+ SERVER_ERR("stat error. file path(%s)", path);\r
+ return 0;\r
+ }\r
+\r
+ return (S_ISLNK(st.st_mode)) ? 1 : 0;\r
+}\r
+\r
+static int _is_realpath(const char *path)\r
+{\r
+ char *rms_realpath = NULL;\r
+ int len_path = 0;\r
+ int len_realpath = 0;\r
+ int result = 1;\r
+\r
+ rms_realpath = realpath(path, NULL);\r
+\r
+ if (!rms_realpath) {\r
+ SERVER_INFO("realpath(%s) is null(%d)", path, errno);\r
+ return 0;\r
+ }\r
+\r
+ len_path = strlen(path);\r
+ len_realpath = strlen(rms_realpath);\r
+\r
+ if (len_path != len_realpath) {\r
+ SERVER_ERR("length mismatch(%d:%d)", len_path, len_realpath);\r
+ result = 0;\r
+ goto out;\r
+ }\r
+\r
+ if (strncmp(path, rms_realpath, len_path)) {\r
+ SERVER_ERR("path mismatch(%s:%s)", path, rms_realpath);\r
+ result = 0;\r
+ goto out;\r
+ }\r
+\r
+out:\r
+ free(rms_realpath);\r
+\r
+ return result;\r
+}\r
+\r
+int main()\r
+{\r
+ int msgq_tx = -1, msgq_rx = -1;\r
+ msgq_tx = msgget((key_t)RM_MSGQ_KEY_TX, 0666 | IPC_CREAT);\r
+ msgq_rx = msgget((key_t)RM_MSGQ_KEY_RX, 0666 | IPC_CREAT);\r
+\r
+ if ((msgq_tx == -1) || (msgq_rx == -1)) {\r
+ SERVER_ERR("NEW MSGQ_CREATE failed to get msgq_id - msgq_tx(%d), msgq_rx(%d)", msgq_tx, msgq_rx);\r
+ return -1;\r
+ }\r
+\r
+ SERVER_INFO("msgq_tx (%d), msgq_rx(%d)", msgq_tx, msgq_rx);\r
+\r
+ FILE *fp = NULL;\r
+ const char *flag_path = "/run/rsc_mgr_ready";\r
+\r
+ fp = fopen(flag_path,"w");\r
+\r
+ if (!fp) {\r
+ SERVER_ERR("NEW_MSGQ_CREATE Failed to create message queue(%s) errno(%d)", flag_path, errno);\r
+ return -1;\r
+ }\r
+\r
+ if (!_is_realpath(flag_path)) {\r
+ SERVER_ERR("%s is not realpath", flag_path);\r
+ fclose(fp);\r
+ return -1;\r
+ }\r
+\r
+ if (_is_symlink_file(flag_path)) {\r
+ SERVER_ERR("%s is symbolic link file", flag_path);\r
+ fclose(fp);\r
+ return -1;\r
+ }\r
+\r
+ SERVER_INFO("NEW_MSGQ_CREATE resource manager message queue(%s) created", flag_path);\r
+\r
+ fflush(fp);\r
+ fsync(fileno(fp));\r
+ fclose(fp);\r
+ return 0;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <CCache.h>\r
+\r
+CCache *CCache::m_instance = NULL;\r
+\r
+CCache *CCache::getInstance(void)\r
+{\r
+ if (!m_instance) {\r
+ m_instance = new(std::nothrow) CCache;\r
+ }\r
+\r
+ return m_instance;\r
+}\r
+\r
+void CCache::SetAppStatus(std::string app_id, int status)\r
+{\r
+ m_visibility.insert(std::pair<std::string, int>(app_id, status));\r
+}\r
+\r
+int CCache::GetAppStatus(std::string app_id)\r
+{\r
+ auto it = m_visibility.find(app_id);\r
+\r
+ return (it == m_visibility.end()) ? -1 : it->second;\r
+}\r
+\r
+void CCache::Drop(void)\r
+{\r
+ m_visibility.clear();\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <trace.h>\r
+#include <stdlib.h>\r
+#include <iostream>\r
+#include <vconf.h>\r
+#include <aul.h>\r
+#include <system_info.h>\r
+#include <unistd.h>\r
+\r
+#include <rms_debug.h>\r
+#include <rms_type.h>\r
+#include <CConsumer.h>\r
+#include <CDebugUtils.h>\r
+#include <CCache.h>\r
+\r
+CConsumer::CConsumer(IN const rms_consumer_s *consumer)\r
+{\r
+ m_consumerID = consumer->consumer_id;\r
+ m_priority = consumer->priority;\r
+ m_pid = consumer->process_id;\r
+ m_app_id.assign(consumer->app_id);\r
+\r
+ SetCmdName(m_pid);\r
+}\r
+\r
+void CConsumer::SetCmdName(long pid)\r
+{\r
+ char cmd_name[RMS_NAME_BUF_SIZE] = {0, };\r
+ std::string delimiter = "/";\r
+\r
+ rms_get_cmd_name(m_pid, cmd_name, RMS_NAME_BUF_SIZE);\r
+ m_cmd_name.assign(cmd_name);\r
+ SERVER_WARN("pid %ld cmd name %s", m_pid, cmd_name);\r
+ m_cmd_name = m_cmd_name.substr(m_cmd_name.find_last_of(delimiter) + 1, m_cmd_name.length());\r
+ SERVER_WARN("m_cmd_name %s", m_cmd_name.c_str());\r
+}\r
+\r
+bool CConsumer::AddResource(IN int device_id)\r
+{\r
+ if (IsUsingResource(device_id)) {\r
+ SERVER_INFO("already registered device id(%d) in Consumer(%d)", device_id, m_consumerID);\r
+ return false;\r
+ }\r
+\r
+ m_resources.insert(device_id);\r
+ return true;\r
+}\r
+\r
+int CConsumer::ReleaseResource(IN int device_id)\r
+{\r
+ if (!IsUsingResource(device_id)) {\r
+ SERVER_WARN("CID[%d] / DevID[%d] the consumer does not use this device", m_consumerID, device_id);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ m_resources.erase(device_id);\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+bool CConsumer::IsUsingResource(IN int device_id)\r
+{\r
+ auto it = m_resources.find(device_id);\r
+\r
+ return (it != m_resources.end());\r
+}\r
+\r
+void CConsumer::SetAppID(IN const char *app_id)\r
+{\r
+ m_app_id.assign(app_id);\r
+}\r
+\r
+std::string CConsumer::GetAppId(int pid)\r
+{\r
+ char app_id[RMS_NAME_BUF_SIZE] ={0, };\r
+ std::string result;\r
+\r
+ if (aul_app_get_appid_bypid(pid, app_id, sizeof(app_id)) != AUL_R_OK) {\r
+ SERVER_ERR("failed to get appid of %d", pid);\r
+ return result;\r
+ }\r
+\r
+ result.assign(app_id);\r
+\r
+ return result;\r
+}\r
+\r
+rms_error_type_e CConsumer::ComparePriority(CConsumer *requester)\r
+{\r
+ std::string app_id = requester->GetAppID();\r
+\r
+ m_app_id = (m_app_id.empty()) ? GetAppId((int) m_pid) : m_app_id;\r
+\r
+ if (!CheckVisibility(app_id)) {\r
+ SERVER_ERR("The application is not visible. cannot take resource");\r
+ return RMS_ERR_TYPE_REQUEST_OF_INVISIBLE_PROCESS;\r
+ }\r
+\r
+ rms_priority_s requester_priority = requester->GetPriority();\r
+\r
+ if (!ComparePriority(requester_priority, m_priority)) {\r
+ char cmd[RMS_NAME_BUF_SIZE] = {0,};\r
+ rms_get_cmd_name(m_pid, cmd, sizeof(cmd));\r
+ SERVER_ERR("rqs_priority(%d/%d) - user_priority(%s-%d/%d)", requester_priority.main, requester_priority.sub, cmd, m_priority.main, m_priority.sub);\r
+ return RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;\r
+ }\r
+\r
+ return RMS_ERR_TYPE_NONE;\r
+}\r
+\r
+bool CConsumer::ComparePriority(IN rms_priority_s priority1, IN rms_priority_s priority2)\r
+{\r
+ if (priority1.main > priority2.main) {\r
+ return true;\r
+ } else if (priority1.main == priority2.main) {\r
+ return priority1.sub >= priority2.sub;\r
+ } else {\r
+ return false;\r
+ }\r
+}\r
+\r
+bool CConsumer::CheckVisibility(IN std::string app_id_requester)\r
+{\r
+ if (app_id_requester.empty()) {\r
+ SERVER_INFO("requester app id : (null)");\r
+ return true;\r
+ }\r
+\r
+ bool visibility_consumer = (m_app_id.empty()) ? true : GetAppVisibility(m_app_id, false);\r
+ bool visibility_requester = GetAppVisibility(app_id_requester, true);\r
+\r
+ if (visibility_requester) {\r
+ SERVER_INFO("requester is visible(%s)", app_id_requester.c_str());\r
+ return true;\r
+ }\r
+\r
+ if (!visibility_consumer) {\r
+ SERVER_INFO("current consumer(%d) is invisible(%s)", m_consumerID, m_app_id.c_str());\r
+ return true;\r
+ }\r
+\r
+ SERVER_ERR("current consumer(%s)- visibility:(%d)", (m_app_id.empty()) ? "null" : m_app_id.c_str(), visibility_consumer);\r
+ SERVER_ERR("requester(%s)- visibility:(%d)", app_id_requester.c_str(), visibility_requester);\r
+\r
+ return false;\r
+}\r
+\r
+int CConsumer::UpdateAppStatus(std::string app_id)\r
+{\r
+ char buf[RMS_NAME_BUF_SIZE];\r
+ int status;\r
+ int n_max = 4;\r
+ snprintf(buf, RMS_NAME_BUF_SIZE, "Get visibility of application '%s'", app_id.c_str());\r
+\r
+ for (int i = 0; i < n_max; i++) {\r
+ usleep(50*1000);\r
+\r
+ trace_begin(buf);\r
+ status = aul_app_get_status(app_id.c_str());\r
+ trace_end();\r
+ SERVER_INFO("app(%s) / status(%d) / (%d)", app_id.c_str(), status, i);\r
+\r
+ if (IsVisibleStatus(status)) {\r
+ SERVER_ERR("status %d", status);\r
+ return status;\r
+ }\r
+ }\r
+ return status;\r
+}\r
+\r
+bool CConsumer::NeedStatusUpdate(std::string app_id)\r
+{\r
+ return false;\r
+}\r
+\r
+bool CConsumer::IsVisibleStatus(int status)\r
+{\r
+ return (status == STATUS_FOCUS || status == STATUS_VISIBLE);\r
+}\r
+\r
+bool CConsumer::GetAppVisibility(std::string app_id, bool requester)\r
+{\r
+ CCache *cache = CCache::getInstance();\r
+ int status = cache->GetAppStatus(app_id);\r
+\r
+ if (status == -1) {\r
+ status = aul_app_get_status(app_id.c_str());\r
+\r
+ if (!IsVisibleStatus(status) && requester && NeedStatusUpdate(app_id))\r
+ status = UpdateAppStatus(app_id);\r
+\r
+ cache->SetAppStatus(app_id, status);\r
+ }\r
+\r
+ return IsVisibleStatus(status);\r
+}\r
+\r
+bool CConsumer::CheckWebAppState(IN std::string app_id_requesting)\r
+{\r
+ if (app_id_requesting.length() == 0)\r
+ return false;\r
+\r
+ std::string webapp_vconf_key = std::string("rtc/memory/WebApp/") + app_id_requesting;\r
+\r
+ char *status = vconf_get_str(webapp_vconf_key.c_str());\r
+ if (!status) {\r
+ SERVER_INFO("%s is not webapp", app_id_requesting.c_str());\r
+ return false;\r
+ }\r
+\r
+ std::string webapp_status(status);\r
+ if (webapp_status.compare("resume")) {\r
+ SERVER_INFO("%s is not in resume status (%s)", app_id_requesting.c_str(), webapp_status.c_str());\r
+ free(status);\r
+ return false;\r
+ }\r
+\r
+ SERVER_INFO("%s is in resume status (%s)", app_id_requesting.c_str(), webapp_status.c_str());\r
+ free(status);\r
+\r
+ return true;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <assert.h>\r
+#include <CConsumer.h>\r
+#include <CConsumerContainer.h>\r
+\r
+CConsumerContainer *CConsumerContainer::m_instance = NULL;\r
+\r
+CConsumerContainer *CConsumerContainer::getInstance(void)\r
+{\r
+ if (!m_instance) {\r
+ m_instance = new(std::nothrow) CConsumerContainer;\r
+ assert(m_instance);\r
+ }\r
+\r
+ return m_instance;\r
+}\r
+\r
+CConsumer *CConsumerContainer::findConsumer(int consumer_id)\r
+{\r
+ std::map<int, CConsumer*>::iterator it = m_consumers.find(consumer_id);\r
+\r
+ return (it == m_consumers.end()) ? NULL : (*it).second;\r
+}\r
+\r
+bool CConsumerContainer::AddConsumer(int consumer_id, CConsumer *consumer)\r
+{\r
+ std::map<int, CConsumer*>::iterator it = m_consumers.find(consumer_id);\r
+\r
+ if (it != m_consumers.end())\r
+ return false;\r
+\r
+ m_consumers.insert(std::pair<int, CConsumer*>(consumer_id, consumer));\r
+ return true;\r
+}\r
+\r
+void CConsumerContainer::RemoveConsumer(int consumer_id)\r
+{\r
+ m_consumers.erase(consumer_id);\r
+}\r
+\r
+std::map<int, CConsumer*> CConsumerContainer::findConsumers(int pid)\r
+{\r
+ std::map<int, CConsumer*> result;\r
+\r
+ for (auto const &it : m_consumers) {\r
+ CConsumer *consumer = it.second;\r
+\r
+ if (consumer->GetPid() != pid)\r
+ continue;\r
+\r
+ result.insert(std::pair<int, CConsumer*>(it.first, it.second));\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+std::map<int, CConsumer*> CConsumerContainer::FindConsumers(std::string app_id)\r
+{\r
+ std::map<int, CConsumer*> result;\r
+ for (auto const &it : m_consumers) {\r
+ CConsumer *consumer = it.second;\r
+ if (app_id.compare(consumer->GetAppID()))\r
+ continue;\r
+\r
+ result.insert(std::pair<int, CConsumer*>(it.first, it.second));\r
+ }\r
+\r
+ return result;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <unistd.h>\r
+#include <sys/stat.h>\r
+#include <fcntl.h>\r
+#include <glib.h>\r
+#include <stdlib.h>\r
+\r
+#include <vconf.h>\r
+#include <stdio.h>\r
+#include <system_info.h>\r
+#include <sys/types.h>\r
+#include <signal.h>\r
+#include <vconf.h>\r
+#include <tzplatform_config.h>\r
+#include <dlfcn.h>\r
+\r
+#include <CDebugUtils.h>\r
+#include <rms_debug.h>\r
+#include <bundle.h>\r
+#include <bundle_internal.h>\r
+#include <syspopup_caller.h>\r
+\r
+\r
+static bool product_type_init = false;\r
+static int product_type = 0; //SYSTEM_INFO_PRODUCT_TYPE_TV;\r
+\r
+// The process list which is killed by resource manager\r
+static GHashTable *process_htable = NULL;\r
+\r
+#define RMS_IS_DEBUG_IMAGE (access("/etc/debug", F_OK) == 0)\r
+\r
+const char *rm_convert_state_enum_to_string(rms_resource_internal_state_e state_enum)\r
+{\r
+ switch (state_enum) {\r
+ case RMS_INTERNAL_STATE_FREE:\r
+ return "FREE";\r
+ case RMS_INTERNAL_STATE_SHARABLE:\r
+ return "SHARABLE";\r
+ case RMS_INTERNAL_STATE_SHARED:\r
+ return "SHARED";\r
+ case RMS_INTERNAL_STATE_EXCLUSIVE:\r
+ return "EXCLUSIVE";\r
+ case RMS_INTERNAL_STATE_ERROR:\r
+ default:\r
+ return "NONE";\r
+ }\r
+}\r
+\r
+const char *rm_convert_requested_state_enum_to_string(rms_requests_resource_state_e state_enum)\r
+{\r
+ switch (state_enum) {\r
+ case RMS_STATE_PASSIVE:\r
+ return "PASSIVE";\r
+ case RMS_STATE_SHARABLE:\r
+ return "SHARABLE";\r
+ case RMS_STATE_EXCLUSIVE:\r
+ return "EXCLUSIVE";\r
+ case RMS_STATE_EXCLUSIVE_CONDITIONAL:\r
+ return "EXCLUSIVE_CONDITIONAL";\r
+ case RMS_STATE_EXCLUSIVE_AUTO:\r
+ return "EXCLUSIVE_AUTO";\r
+ case RMS_STATE_EXCLUSIVE_PREFERENCE:\r
+ return "EXCLUSIVE_PREFERENCE";\r
+ default:\r
+ return "NONE";\r
+ }\r
+}\r
+\r
+const char *rm_convert_category_enum_to_string(rms_rsc_category_e category_enum)\r
+{\r
+ switch (category_enum) {\r
+ case RMS_CATEGORY_NONE:\r
+ return "NONE";\r
+ case RMS_CATEGORY_AUDIO_DECODER:\r
+ return "Audio_Decoder";\r
+ case RMS_CATEGORY_AUDIO_SPDIF_ES_OUTPUT:\r
+ return "Not Defined Yet";\r
+ case RMS_CATEGORY_VIDEO_DECODER:\r
+ return "Video_Decoder";\r
+ case RMS_CATEGORY_DEMUX:\r
+ return "Demux_Main";\r
+ case RMS_CATEGORY_AUDIO_ENCODER:\r
+ return "Audio_Encoder";\r
+ case RMS_CATEGORY_VIDEO_ENCODER:\r
+ return "Video_Encoder";\r
+ case RMS_CATEGORY_SCALER:\r
+ return "Video_Scaler";\r
+ case RMS_CATEGORY_TUNER:\r
+ return "Tuner";\r
+ case RMS_CATEGORY_AUDIO_MAIN_OUT:\r
+ return "Audio_Main_Out";\r
+ case RMS_CATEGORY_AUDIO_REMOTE_OUT:\r
+ return "Audio_Remote_Out";\r
+ case RMS_CATEGORY_AUDIO_SCART_OUT:\r
+ return "Audio_Scart_Out";\r
+ case RMS_CATEGORY_MM_PCM_OUT:\r
+ return "MM_PCM_playback";\r
+ case RMS_CATEGORY_AUDIO_DECODER_SUB:\r
+ return "Audio_Decorder_Sub";\r
+ case RMS_CATEGORY_JPEG_DECODER:\r
+ return "JPEG_Decoder";\r
+ case RMS_CATEGORY_MJPEG_DECODER:\r
+ return "MJPEG_Decoder";\r
+ case RMS_CATEGORY_SCALER_SUB:\r
+ return "Video_Scaler_Sub";\r
+ case RMS_CATEGORY_EXT_VIDEO_SRC:\r
+ return "Ext_Video_Src";\r
+ case RMS_CATEGORY_EXT_AUDIO_SRC:\r
+ return "Ext_Audio_Src";\r
+ case RMS_CATEGORY_EXT_HDMI_SRC:\r
+ return "Ext_HDMI_Src";\r
+ case RMS_CATEGORY_VIDEO_DECODER_SUB:\r
+ return "Video_Decoder_Sub";\r
+ case RMS_CATEGORY_CAMERA:\r
+ return "Camera";\r
+ case RMS_CATEGORY_DEMUX_REC:\r
+ return "Demux_Rec";\r
+ case RMS_CATEGORY_TUNER_SUB:\r
+ return "Tuner_Sub";\r
+ case RMS_CATEGORY_VIDEO_DECODER_UHD:\r
+ return "Video_Decoder UHD";\r
+ case RMS_CATEGORY_INPUT_SRC_DTV:\r
+ return "Input_Src_DTV";\r
+ case RMS_CATEGORY_INPUT_SRC_ATV:\r
+ return "Input_Src_ATV";\r
+ case RMS_CATEGORY_INPUT_SRC_HDMI:\r
+ return "Input_Src_HDMI";\r
+ case RMS_CATEGORY_INPUT_SRC_COMP:\r
+ return "Input_Src_COMP";\r
+ case RMS_CATEGORY_INPUT_SRC_AV:\r
+ return "Input_Src_AV";\r
+ case RMS_CATEGORY_INPUT_SRC_SCART:\r
+ return "Input_Src_SCART";\r
+ case RMS_CATEGORY_MIC:\r
+ return "Mic";\r
+ case RMS_CATEGORY_SW_DECODER:\r
+ return "SWDecoder";\r
+ case RMS_CATEGORY_MMP_MEMORY_CLUSTER:\r
+ return "MMPlayer MemoryCluster";\r
+ case RMS_CATEGORY_JPEG_DECODER_8K:\r
+ return "JPEG_Decoder 8K";\r
+ case RMS_CATEGORY_SCALER_BG:\r
+ return "Video_Scaler_BG";\r
+ default:\r
+ return "";\r
+ }\r
+}\r
+\r
+const char *rm_convert_device_enum_to_string(rms_device_e device_enum)\r
+{\r
+ switch (device_enum) {\r
+ case RMS_DEVICE_NONE:\r
+ return "NONE";\r
+ case RMS_DEVICE_AUDIO_MAIN_OUT:\r
+ return "audio_main_out";\r
+ case RMS_DEVICE_AUDIO_REMOTE_OUT:\r
+ return "audio_remote_out";\r
+ case RMS_DEVICE_AUDIO_SCART_OUT:\r
+ return "audio_scart_out";\r
+ case RMS_DEVICE_MM_PCM_OUT:\r
+ return "mm_pcm_out";\r
+ case RMS_DEVICE_JPEG_DECODER:\r
+ return "jpeg_decoder";\r
+ case RMS_DEVICE_DEMUX0:\r
+ return "demux0";\r
+ case RMS_DEVICE_DEMUX1:\r
+ return "demux1";\r
+ case RMS_DEVICE_DEMUX2:\r
+ return "demux2";\r
+ case RMS_DEVICE_DEMUX3:\r
+ return "demux3";\r
+ case RMS_DEVICE_AUDIO_ENCODER:\r
+ return "audio_encoder";\r
+ case RMS_DEVICE_VIDEO_ENCODER:\r
+ return "video_encoder";\r
+ case RMS_DEVICE_SCALER:\r
+ return "scaler";\r
+ case RMS_DEVICE_EXT_VIDEO_SRC:\r
+ return "ext_video_src";\r
+ case RMS_DEVICE_EXT_AUDIO_SRC:\r
+ return "ext_autio_src";\r
+ case RMS_DEVICE_EXT_HDMI_SRC:\r
+ return "ext_hdmi_src";\r
+ case RMS_DEVICE_CAMERA:\r
+ return "camera";\r
+ case RMS_DEVICE_TUNER:\r
+ return "tuner";\r
+ case RMS_DEVICE_TUNER_SUB:\r
+ return "tuner_sub";\r
+ case RMS_DEVICE_SCALER_SUB:\r
+ return "scaler_sub";\r
+ case RMS_DEVICE_AUDIO_DECODER:\r
+ return "audio_decoder";\r
+ case RMS_DEVICE_AUDIO_DECODER_SUB:\r
+ return "audio_decoder_sub";\r
+ case RMS_DEVICE_VIDEO_DECODER_MAIN:\r
+ return "video_decoder_main";\r
+ case RMS_DEVICE_VIDEO_DECODER_SUB:\r
+ return "video_decoder_sub";\r
+ case RMS_DEVICE_VIDEO_DECODER_UDDEC:\r
+ return "video_decoder_uddec";\r
+ case RMS_DEVICE_VIDEO_DECODER_UDHEVC:\r
+ return "video_decoder_udhevc";\r
+ case RMS_DEVICE_AUDIO_SPDIF_ES_OUTPUT:\r
+ return "audio_spdif_es_output";\r
+ case RMS_DEVICE_MIC:\r
+ return "mic";\r
+ case RMS_DEVICE_EXT_COMP_SRC:\r
+ return "ext_comp_src";\r
+ case RMS_DEVICE_EXT_AV_SRC:\r
+ return "av_src";\r
+ case RMS_DEVICE_MJPEG_DECODER:\r
+ return "mjpeg_decoder";\r
+ case RMS_DEVICE_JPEG_DECODER_UHD:\r
+ return "jpeg_decoder_uhd";\r
+ case RMS_DEVICE_MJPEG_DECODER_UHD:\r
+ return "mjpeg_decoder_uhd";\r
+ case RMS_DEVICE_SW_DECODER:\r
+ return "sw_decoder";\r
+ default:\r
+ return "";\r
+ }\r
+}\r
+\r
+const char *rm_print_allocation_failure_reason(int ret_value)\r
+{\r
+ switch (ret_value) {\r
+ case RMS_OK:\r
+ return "OK";\r
+ case RMS_ERROR:\r
+ return "Cannot Allocate Resources";\r
+ case RMS_ERROR_TAKE_RESOURCE_FROM_OTHER_CONSUMER:\r
+ return "RESOURCE CONFLICT - Other Consumer Is Using";\r
+ case RMS_OK_UHD_RESOURCE_CONFLICT:\r
+ return "UHD RESOURCE CONFLICT - Other Consumer Is Using";\r
+ default:\r
+ return "";\r
+ }\r
+}\r
+void rms_create_popup(const char *title, const char *text)\r
+{\r
+ bundle *(*bundle_create_fp) (void);\r
+ int (*bundle_add_fp)(bundle*, const char*, const char*);\r
+ const char *(*bundle_get_val_fp) (bundle*, const char*);\r
+ int (*bundle_free_fp) (bundle*);\r
+ int (*syspopup_launch_fp) (char*, bundle*);\r
+ void *libsyspopup_handle = NULL;\r
+ void *libbundle_handle = NULL;\r
+ bundle *b = NULL;\r
+ char *error;\r
+\r
+ libsyspopup_handle = dlopen(LIBDIR"/libsyspopup_caller.so.0.1.0", RTLD_LAZY);\r
+ if (!libsyspopup_handle) {\r
+ SERVER_ERR("failed to load syspopup library");\r
+ goto end;\r
+ }\r
+\r
+ libbundle_handle = dlopen(LIBDIR"/libbundle.so.0", RTLD_LAZY);\r
+\r
+ if (!libbundle_handle) {\r
+ SERVER_ERR("failed to load bundle library");\r
+ goto end;\r
+ }\r
+\r
+ error = NULL;\r
+\r
+ bundle_create_fp = (bundle *(*)(void)) dlsym(libbundle_handle, "bundle_create");\r
+\r
+ if ((error = dlerror()) != NULL) {\r
+ SERVER_ERR("failed to find bundle_create");\r
+ goto end;\r
+\r
+ }\r
+\r
+ bundle_add_fp = (int (*)(bundle*, const char*, const char*)) dlsym(libbundle_handle, "bundle_add");\r
+\r
+ if ((error = dlerror()) != NULL) {\r
+ SERVER_ERR("failed to find bundle_add");\r
+ goto end;\r
+ }\r
+\r
+ bundle_get_val_fp = (const char *(*)(bundle*, const char*)) dlsym(libbundle_handle, "bundle_get_val");\r
+\r
+ if ((error = dlerror()) != NULL) {\r
+ SERVER_ERR("failed to find bundle_get_val");\r
+ goto end;\r
+ }\r
+\r
+ bundle_free_fp = (int (*)(bundle*)) dlsym(libbundle_handle, "bundle_free");\r
+\r
+ if ((error = dlerror()) != NULL) {\r
+ SERVER_ERR("failed to find bundle_free");\r
+ goto end;\r
+ }\r
+\r
+ syspopup_launch_fp = (int (*)(char*, bundle*)) dlsym(libsyspopup_handle, "syspopup_launch");\r
+\r
+ if ((error = dlerror()) != NULL) {\r
+ SERVER_ERR("failed to find alert-syspopup");\r
+ goto end;\r
+ }\r
+\r
+ b = bundle_create_fp();\r
+ if (!b) {\r
+ SERVER_ERR("failed to create bundle");\r
+ goto end;\r
+ }\r
+\r
+ bundle_add_fp(b, "type", "title_message_1button");\r
+ bundle_add_fp(b, "title", title);\r
+ bundle_add_fp(b, "text", text);\r
+\r
+ bundle_get_val_fp(b, "type");\r
+ bundle_get_val_fp(b, "title");\r
+ bundle_get_val_fp(b, "text");\r
+\r
+ syspopup_launch_fp((char*)"alert-syspopup", b);\r
+ bundle_free_fp(b);\r
+\r
+end:\r
+ if (libsyspopup_handle)\r
+ dlclose(libsyspopup_handle);\r
+\r
+ if (libbundle_handle)\r
+ dlclose(libbundle_handle);\r
+}\r
+\r
+int rms_get_cmd_name(pid_t pid, char *name_out, int size)\r
+{\r
+ char name[RMS_NAME_BUF_SIZE] = {0,};\r
+ FILE *f;\r
+ size_t sz;\r
+\r
+ snprintf(name, sizeof(name), "/proc/%d/cmdline", pid);\r
+ f = fopen(name, "r");\r
+ if (!f) {\r
+ SERVER_ERR("failed to open cmdline(%s) : %d", name, errno);\r
+ return RMS_ERROR;\r
+ } else {\r
+ sz = fread(name, sizeof(char), sizeof(name)-1, f);\r
+ name[sz] = '\0';\r
+ fclose(f);\r
+ }\r
+\r
+ snprintf(name_out, size, "%s", name);\r
+ return RMS_OK;\r
+}\r
+\r
+void rms_print_log_console(char *buf)\r
+{\r
+ int fd, ret;\r
+ char output[RMS_CONSOLE_BUF_SIZE] ={0,};\r
+\r
+ struct timespec tnow;\r
+\r
+ fd = open("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);\r
+\r
+ if (fd < 0) {\r
+ SERVER_ERR("console device open fail");\r
+ return;\r
+ }\r
+\r
+ if (is_symlink_file("/dev/console")) {\r
+ SERVER_ERR("%s is symbolic link file", "/dev/console");\r
+ close(fd);\r
+ return;\r
+ }\r
+\r
+ ret = clock_gettime(CLOCK_MONOTONIC, &tnow);\r
+ snprintf(output, RMS_CONSOLE_BUF_SIZE, "[RMS][%ld.%6ld] %s\n", tnow.tv_sec, tnow.tv_nsec/1000, buf);\r
+ ret = write(fd, output, strlen(output));\r
+\r
+ if (ret < 0) {\r
+ SERVER_ERR("Fail to write on console directly");\r
+ }\r
+\r
+ close(fd);\r
+}\r
+\r
+int rm_get_product_type(void)\r
+{\r
+ if (product_type_init)\r
+ return product_type;\r
+\r
+ int type = 0; /* SYSTEM_INFO_PRODUCT_TYPE_TV */\r
+\r
+ if (system_info_get_custom_int("com.samsung/featureconf/product.product_type", &type) != SYSTEM_INFO_ERROR_NONE) {\r
+ SERVER_ERR("Failed to get com.samsung/featureconf/product.product_type");\r
+ }\r
+\r
+ product_type_init = true;\r
+ product_type = type;\r
+\r
+ return product_type;\r
+}\r
+\r
+int rm_is_valid_pid(int pid)\r
+{\r
+ if (kill((pid_t) pid, 0) == 0) {\r
+ SERVER_INFO("pid(%d) is alive", pid);\r
+ return 1;\r
+ }\r
+\r
+ SERVER_ERR("pid(%d)/errno(%d)", pid, errno);\r
+\r
+ return (errno == ESRCH) ? 0 : 1;\r
+}\r
+\r
+static void process_htable_destory_key(gpointer key)\r
+{\r
+ if (key)\r
+ free(key);\r
+}\r
+\r
+static void process_htable_create(void)\r
+{\r
+ if (process_htable) {\r
+ SERVER_ERR("hash table already created");\r
+ return;\r
+ }\r
+\r
+ process_htable = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)process_htable_destory_key, NULL);\r
+\r
+ SERVER_INFO("process hash table created");\r
+}\r
+\r
+static void process_htable_clear(void)\r
+{\r
+ SERVER_INFO("clear process hash table");\r
+\r
+ if (!process_htable)\r
+ return;\r
+\r
+ g_hash_table_remove_all(process_htable);\r
+}\r
+\r
+static void process_htable_insert(const char *name)\r
+{\r
+ const int PROCESS_DATA_LIMIT = 100; // The maxinum size is (RMS_NAME_BUF_SIZE * PROCESS_DATA_LIMIT)\r
+\r
+ if (!process_htable)\r
+ process_htable_create();\r
+\r
+ if (g_hash_table_contains(process_htable, name))\r
+ return;\r
+\r
+ if (g_hash_table_size(process_htable) >= PROCESS_DATA_LIMIT)\r
+ process_htable_clear();\r
+\r
+ char *key_name = (char*) strndup(name, strlen(name));\r
+\r
+ g_hash_table_insert(process_htable, key_name, (gpointer) 1);\r
+\r
+ SERVER_ERR("process info (%s) inserted to hash table (%d)", name, g_hash_table_size(process_htable));\r
+}\r
+\r
+\r
+bool process_htable_contains(const char *name)\r
+{\r
+ bool result = false;\r
+\r
+ if (!process_htable) {\r
+ SERVER_INFO("(%s) - no table", name);\r
+ return false;\r
+ }\r
+\r
+ if (g_hash_table_size(process_htable) == 0) {\r
+ SERVER_INFO("(%s) - empty", name);\r
+ return false;\r
+ }\r
+\r
+ result = g_hash_table_contains(process_htable, name);\r
+\r
+ SERVER_INFO("(%s) - result(%d)", name, result);\r
+\r
+ // resource manager is supposed to clear data once it's checked by application\r
+ process_htable_clear();\r
+\r
+ return result;\r
+}\r
+\r
+int rms_report_emergency(IN int cid, IN int pid, IN int requester)\r
+{\r
+ const char *vconf_request_cold_poweroff = "memory/boot/cold_poweroff_request_pkg";\r
+ int retry = 25; // 20ms * 25 times => 500ms\r
+ int ret = 0;\r
+\r
+ SERVER_ERR("consumer is not responding....CID[%d]/PID[%d]/Requester(%d) - set cold power off mode", cid, pid, requester);\r
+\r
+ if (vconf_set_str(vconf_request_cold_poweroff, "resource-manager") != 0) {\r
+ SERVER_ERR("Failed to set request cold power off");\r
+ } else {\r
+ SERVER_ERR("memory/boot/cold_poweroff_request_pkg set as resource-manager");\r
+ }\r
+\r
+ char process_name[RMS_NAME_BUF_SIZE] = {0,};\r
+\r
+ if (rms_get_cmd_name(pid, process_name, RMS_NAME_BUF_SIZE) == RMS_OK) {\r
+ process_htable_insert(process_name);\r
+ }\r
+\r
+ SERVER_ERR("kill PID(%d)", pid);\r
+\r
+ int signal = SIGKILL;\r
+\r
+ if (RMS_IS_DEBUG_IMAGE) {\r
+ signal = SIGABRT;\r
+ retry = 250; // 20ms * 250 times => 5 sec\r
+ }\r
+\r
+ ret = kill(pid, signal);\r
+\r
+ if (ret!=0) {\r
+ SERVER_ERR("Failed to kill(%d), errno(%d)", pid, errno);\r
+ }\r
+\r
+ // wait until process is really terminated for 500ms\r
+ while (retry > 0 && rm_is_valid_pid(pid)) {\r
+ retry--;\r
+ SERVER_ERR("pid(%d) still alive(%d)", pid, retry);\r
+ usleep(20*1000);\r
+ continue;\r
+ }\r
+\r
+ if (RMS_IS_DEBUG_IMAGE && retry <= 0) {\r
+ //process didn't get terminated for 5 seconds\r
+ SERVER_ERR("pid(%d) is not terminated.", pid);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+void rms_display_timeout_error_popup(rms_alarm_reason_e reason, rms_consumer_tobe_returned_s info)\r
+{\r
+ const char *title = "Resource Allocation Failure";\r
+ const char *style_notification_msg = "<font_size=30 color=#00FF00>";\r
+ const char *style_process_name = "<font_size=25 color=#C90000>";\r
+ const char *indent = " ";\r
+ const char *notification_msg = "Please contact the owner(s) of process(es) below<br>";\r
+ const char *reason0 = " Resource allocation failed because there is no callback response from below process(es)<br> ";\r
+ const char *reason1 = " Resource allocation failed because below process(es) did not request deallocation<br> ";\r
+\r
+ char name[RMS_NAME_BUF_SIZE] = {0,};\r
+ GString *gstr;\r
+\r
+ if (!RMS_IS_DEBUG_IMAGE) {\r
+ SERVER_ERR("Not debug mode. Timeout alarm popup is not shown. reason(%d)", (int)reason);\r
+ return;\r
+ }\r
+\r
+ SERVER_ERR("timeout alarm");\r
+\r
+ gstr = g_string_new("");\r
+\r
+ if (!gstr) {\r
+ SERVER_ERR("Failed to create debug popup command");\r
+ return;\r
+ }\r
+\r
+ g_string_append_printf(gstr, "%s", style_notification_msg);\r
+\r
+ switch (reason) {\r
+ case RMS_ALARM_NO_CALLBACK_RESPONSE:\r
+ g_string_append_printf(gstr, "%s%s", indent, reason0);\r
+ break;\r
+ case RMS_ALARM_NO_DEALLOCATION:\r
+ g_string_append_printf(gstr, "%s%s", indent, reason1);\r
+ break;\r
+ default :\r
+ break;\r
+ }\r
+\r
+ g_string_append_printf(gstr, "%s%s%s", indent, notification_msg, style_process_name);\r
+\r
+ rms_get_cmd_name(info.process_id, name, sizeof(name));\r
+ g_string_append_printf(gstr, "%s%s : %d - %s%s", indent, "pid", (int)(info.process_id), name, " <br>");\r
+\r
+ for (int i = 0; i < info.n_conflicted; i++) {\r
+ g_string_append_printf(gstr, "%s [%d] %s%s", indent, i+1, rm_convert_category_enum_to_string(info.conflicted_resources[i].category_id), " <br>");\r
+ }\r
+ rms_create_popup(title, gstr->str);\r
+ SERVER_ERR("Command: %s", gstr->str);\r
+ g_string_free(gstr, true);\r
+}\r
+\r
+static bool rms_read_index(int *data)\r
+{\r
+ FILE *fp = NULL;\r
+ char str[10] = {0,};\r
+ size_t str_size;\r
+ const char *filename = "/proc/device-tree/rm_tbl_idx";\r
+\r
+ if (!data) {\r
+ SERVER_ERR("invalid input : null data");\r
+ return false;\r
+ }\r
+\r
+ fp = fopen(filename, "rb");\r
+\r
+ if (!fp) {\r
+ SERVER_ERR("failed to open (%s) - errno(%d)", filename, errno);\r
+ return false;\r
+ }\r
+\r
+ str_size = fread(str, sizeof(char), sizeof(str)-1, fp);\r
+\r
+ str[str_size] = '\0';\r
+\r
+ if (str_size == 0) {\r
+ fclose(fp);\r
+ return false;\r
+ }\r
+\r
+ *data = atoi(str);\r
+\r
+ fclose(fp);\r
+ fp = NULL;\r
+\r
+ return true;\r
+}\r
+\r
+void rms_display_resource_table_error_popup(void)\r
+{\r
+ const char *title = "FATAL ERROR!!!";\r
+ const char *reason = " Resource Manager can't find a resource table for this board<br> ";\r
+ const char *style_notification_msg = "<font_size=30 color=#FF0000>";\r
+ const char *indent = " ";\r
+ const char *notification_msg = "<br>";\r
+\r
+ GString *gstr = g_string_new("");\r
+ char *chipset_info;\r
+ int model_index = -1;\r
+\r
+ if (!gstr) {\r
+ SERVER_ERR("Failed to create debug popup command");\r
+ return;\r
+ }\r
+\r
+ g_string_append_printf(gstr, "%s%s", indent, reason);\r
+ g_string_append_printf(gstr, "%s%s%s", indent, notification_msg, style_notification_msg);\r
+ g_string_append_printf(gstr, "%sProduct type : %d%s", indent, rm_get_product_type(), " <br>");\r
+\r
+ if (system_info_get_custom_string("com.samsung/featureconf/product.chipset", &chipset_info)!= SYSTEM_INFO_ERROR_NONE) {\r
+ SERVER_ERR("Failed to get chipset from system-info\n");\r
+ goto end;\r
+ }\r
+\r
+ g_string_append_printf(gstr, "%sChipset : %s%s", indent, chipset_info, " <br>");\r
+\r
+ if (!rms_read_index(&model_index)) {\r
+ SERVER_ERR("failed to read model index");\r
+ }\r
+\r
+ g_string_append_printf(gstr, "%sIndex : %d%s", indent, model_index, " <br>");\r
+\r
+ rms_create_popup(title,gstr->str);\r
+\r
+ if (chipset_info) {\r
+ free(chipset_info);\r
+ }\r
+\r
+end:\r
+ g_string_free(gstr, true);\r
+ return;\r
+}\r
+\r
+void rms_print_model_info(void)\r
+{\r
+ static char *chipset_info = NULL;\r
+ static int rm_index = -1;\r
+\r
+ if (!chipset_info) {\r
+ if (system_info_get_custom_string("com.samsung/featureconf/product.chipset", &chipset_info)!= SYSTEM_INFO_ERROR_NONE)\r
+ SERVER_ERR("Failed to get chipset");\r
+ }\r
+\r
+ if (rm_index == -1) {\r
+ if (!rms_read_index(&rm_index))\r
+ SERVER_ERR("failed to read rm index");\r
+ }\r
+\r
+ SERVER_ERR("> chipset(%s)/product_type(%d)/rm_index(%d)", chipset_info? chipset_info:"", rm_get_product_type(), rm_index);\r
+\r
+ char buf[512];\r
+ snprintf(buf, 512, "resource table not loaded! > chipset(%s)/product_type(%d)/rm_index(%d)", chipset_info? chipset_info:"", rm_get_product_type(), rm_index);\r
+ rms_print_log_console(buf);\r
+}\r
+\r
+int is_symlink_file(const char *path)\r
+{\r
+ struct stat st;\r
+ if (lstat(path, &st) == -1) {\r
+ SERVER_ERR("stat error. file path(%s)", path);\r
+ return 0;\r
+ }\r
+\r
+ return (S_ISLNK(st.st_mode)) ? 1 : 0;\r
+}\r
+\r
+const char *rm_convert_error_type_to_string(rms_error_type_e error_type)\r
+{\r
+ switch (error_type) {\r
+ case RMS_ERR_TYPE_NONE:\r
+ return "None";\r
+ case RMS_ERR_TYPE_REQUEST_OF_INVISIBLE_PROCESS:\r
+ return "Request of invisible process";\r
+ case RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS:\r
+ return "Request of low priority process";\r
+ case RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE:\r
+ return "Not available resource";\r
+ case RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST:\r
+ return "Requested resource does not exist";\r
+ case RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER:\r
+ return "Take resource from other consumer";\r
+ default:\r
+ return "";\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <mutex>\r
+#include <CLockController.h>\r
+\r
+std::mutex m;\r
+CLockController *CLockController::m_instance = nullptr;\r
+\r
+CLockController *CLockController::GetInstance(void)\r
+{\r
+ if (m_instance == nullptr)\r
+ {\r
+ m_instance = new(std::nothrow) CLockController();\r
+ }\r
+\r
+ return m_instance;\r
+}\r
+\r
+void CLockController::Lock(ResourceType rsc_type)\r
+{\r
+ std::unique_lock<std::mutex> lock(m);\r
+ unsigned int count = 0;\r
+ auto it = m_locks.find(rsc_type);\r
+\r
+ count = (it == m_locks.end()) ? 1 : ++it->second;\r
+\r
+ m_locks.insert(std::pair<ResourceType, unsigned int>(rsc_type, count));\r
+}\r
+\r
+void CLockController::Unlock(ResourceType rsc_type)\r
+{\r
+ std::unique_lock<std::mutex> lock(m);\r
+\r
+ auto it = m_locks.find(rsc_type);\r
+ if (it == m_locks.end())\r
+ return;\r
+\r
+ if (it->second == 0)\r
+ return;\r
+\r
+ m_locks.at(rsc_type) = --it->second;\r
+\r
+ if (m_locks.at(rsc_type) == 0)\r
+ NotifyUnlock();\r
+}\r
+\r
+unsigned int CLockController::GetLockCount(void)\r
+{\r
+ std::unique_lock<std::mutex> lock(m);\r
+ unsigned int count = 0;\r
+\r
+ for (auto &it : m_locks)\r
+ count += it.second;\r
+\r
+ return count;\r
+}\r
+\r
+void CLockController::NotifyUnlock(void)\r
+{\r
+ CMessage *msg = new CMessage("NotifyUnlock");\r
+ m_msg_q->push(msg);\r
+}\r
+\r
+bool CLockController::IsLocked(CMessage *msg)\r
+{\r
+ if ((m_locks.at(ResourceType::VIDEO_SCALER) > 0) && msg->IsMsgFor(ResourceType::VIDEO_SCALER))\r
+ return true;\r
+\r
+ return false;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <rms_type.h>\r
+#include <rms_debug.h>\r
+#include <CResource.h>\r
+#include <CConsumer.h>\r
+#include <CResourceDB.h>\r
+#include <CConsumerContainer.h>\r
+#include <CPriority.h>\r
+\r
+int CPriority::compare(int cur_consumer_id, int consumer_id)\r
+{\r
+ CConsumerContainer *c_container = CConsumerContainer::getInstance();\r
+ CConsumer *cur_consumer = c_container->findConsumer(cur_consumer_id);\r
+ if (!cur_consumer)\r
+ return HIGH_PRIORITY;\r
+\r
+ CConsumer *consumer = c_container->findConsumer(consumer_id);\r
+ if (!consumer)\r
+ return LOW_PRIORITY;\r
+\r
+ return (cur_consumer->ComparePriority(consumer) == RMS_ERR_TYPE_NONE) ? HIGH_PRIORITY : LOW_PRIORITY;\r
+}\r
+\r
+int CPriority::compareCurConsumers(int device_id, int consumer_id)\r
+{\r
+ CConsumerContainer *c_container = CConsumerContainer::getInstance();\r
+\r
+ CConsumer *consumer = c_container->findConsumer(consumer_id);\r
+ if (!consumer)\r
+ return LOW_PRIORITY;\r
+\r
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
+ if (!resource)\r
+ return HIGH_PRIORITY;\r
+\r
+ std::set<int> rsc_consumers = resource->GetConsumers();\r
+\r
+ for (auto const &it : rsc_consumers) {\r
+ CConsumer *rsc_consumer = c_container->findConsumer(it);\r
+\r
+ if (!rsc_consumer)\r
+ continue;\r
+\r
+ if (rsc_consumer->GetId() == consumer_id) {\r
+ SERVER_WARN("consumer(%d) is already using (%d)", consumer_id, device_id);\r
+ return SAME_PRIORITY;\r
+ }\r
+\r
+ if (rsc_consumer->ComparePriority(consumer) != RMS_ERR_TYPE_NONE) {\r
+ SERVER_WARN("LOW PRORITY consumer (%d) device (%d)", consumer_id, device_id);\r
+ return LOW_PRIORITY;\r
+ }\r
+ }\r
+\r
+ return HIGH_PRIORITY;\r
+}\r
+\r
+int CPriority::getReclaimableConsumersShare(int device_id, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)\r
+{\r
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
+ CConsumer *requester = CConsumerContainer::getInstance()->findConsumer(consumer_id);\r
+\r
+ if (!resource || !requester)\r
+ return RMS_ERROR;\r
+\r
+ if (resource->IsSharableState())\r
+ return RMS_ERROR;\r
+\r
+ std::set<int> consumers = resource->GetConsumers();\r
+\r
+ for (auto const &it : consumers) {\r
+ int cid = it;\r
+\r
+ if (isReclaimableConsumer(cid , consumer_id, err_type)) {\r
+ reclaimables->insert(std::pair<int, int>(device_id, cid));\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (reclaimables->empty()) {\r
+ SERVER_ERR("high priority consumer is using device(%d)", device_id);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+bool CPriority::isReclaimableConsumer(int consumer_id, int requester_id, rms_error_type_e *err_type)\r
+{\r
+ CConsumerContainer *c_container = CConsumerContainer::getInstance();\r
+ CConsumer *consumer = c_container->findConsumer(consumer_id);\r
+ CConsumer *requester = c_container->findConsumer(requester_id);\r
+\r
+ if (!consumer || !requester)\r
+ return false;\r
+\r
+ if (consumer_id == requester_id)\r
+ return false;\r
+\r
+ rms_error_type_e error_type = consumer->ComparePriority(requester);\r
+\r
+ if (error_type != RMS_ERR_TYPE_NONE) {\r
+ if (err_type)\r
+ *err_type = error_type;\r
+\r
+ return false;\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+int CPriority::getReclaimableConsumers(int device_id, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)\r
+{\r
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
+ CConsumer *requester = CConsumerContainer::getInstance()->findConsumer(consumer_id);\r
+\r
+ if (!resource || !requester)\r
+ return RMS_ERROR;\r
+\r
+ if (resource->IsFreeState())\r
+ return RMS_ERROR;\r
+\r
+ std::set<int> consumers = resource->GetConsumers();\r
+\r
+ for (auto const &it : consumers) {\r
+ int cid = it;\r
+\r
+ if (!isReclaimableConsumer(cid , consumer_id, err_type))\r
+ continue;\r
+\r
+ reclaimables->insert(std::pair<int, int>(device_id, cid));\r
+ }\r
+\r
+ if (reclaimables->empty())\r
+ {\r
+ SERVER_ERR("high priority consumer is using device(%d)", device_id);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ return RMS_OK;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <iostream>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <algorithm>\r
+#include <time.h>\r
+\r
+#include <trace.h>\r
+#include <vconf.h>\r
+\r
+#include <CDebugUtils.h>\r
+#include <rms_debug.h>\r
+#include <rms_type.h>\r
+#include <ri-common-type.h>\r
+#include <ri-module-api.h>\r
+\r
+#include <CResourceObserver.h>\r
+#include <CResource.h>\r
+\r
+#define RMS_SUBSCALER_FLAG "memory/rsc_mgr/subscaler_status"\r
+\r
+using namespace std;\r
+void CResource::m_SetSubScalerFlag(int next_state)\r
+{\r
+ if (next_state == RMS_INTERNAL_STATE_ERROR)\r
+ return;\r
+ int value = 0;\r
+ switch (next_state) {\r
+ case RMS_INTERNAL_STATE_FREE:\r
+ value = 0;\r
+ break;\r
+ case RMS_INTERNAL_STATE_SHARABLE:\r
+ case RMS_INTERNAL_STATE_SHARED:\r
+ case RMS_INTERNAL_STATE_EXCLUSIVE:\r
+ value = 1;\r
+ break;\r
+ }\r
+ if (vconf_set_int(RMS_SUBSCALER_FLAG,value) != 0) {\r
+ SERVER_ERR("Failed to Set vconf key - %s",RMS_SUBSCALER_FLAG);\r
+ return;\r
+ }\r
+ SERVER_INFO("Subscaler flag set to - %d", value);\r
+}\r
+\r
+CResource::CResource(const int device_id, const rms_rsc_category_e category_type, const char *name, const char *path,\r
+ std::set<unsigned int> mem_cluster, int is_main_device, const char *audio_codec, int sharable_count)\r
+:m_id(device_id), m_device_name(name), m_device_path(path), m_is_main_device(is_main_device), m_sharable_count(sharable_count)\r
+{\r
+ m_state = RMS_INTERNAL_STATE_FREE;\r
+ m_occupied_bw = 0;\r
+ m_default_bw = 0;\r
+ m_is_reserved = false;\r
+ m_reserved_consumer_id = 0;\r
+ m_mixing_mode = RMS_MIXING_MODE_DEFAULT;\r
+ m_mem_clusters = mem_cluster;\r
+ m_virtual_id = 0;\r
+ m_mv_zone_id = -1;\r
+\r
+ if (audio_codec)\r
+ m_audio_codec.assign(audio_codec);\r
+\r
+ m_category_type = category_type;\r
+ m_cur_category = category_type;\r
+ m_is_scaler = IsScaler(category_type);\r
+}\r
+\r
+CResource::~CResource()\r
+{\r
+}\r
+\r
+bool CResource::IsScaler(rms_rsc_category_e category)\r
+{\r
+ bool result = false;\r
+\r
+ switch (category) {\r
+ case RMS_CATEGORY_SCALER:\r
+ case RMS_CATEGORY_SCALER_BG:\r
+ case RMS_CATEGORY_SCALER_SUB:\r
+ case RMS_CATEGORY_SCALER_SUB2:\r
+ case RMS_CATEGORY_SCALER_SUB3:\r
+ result = true;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+void CResource::UpdateProperties(std::set<unsigned int> mem_clusters, int bw, int category, int category_class, int vrsc_id)\r
+{\r
+ m_mem_clusters = mem_clusters;\r
+ m_occupied_bw = bw;\r
+ m_cur_category = category;\r
+ m_category_class = category_class;\r
+ m_vrsc_id = vrsc_id;\r
+}\r
+\r
+int CResource::ReserveExclusive(int consumer_id)\r
+{\r
+ if (m_is_reserved && (consumer_id != m_reserved_consumer_id)) {\r
+ SERVER_ERR("rsc(%d) already reserved by(%d)", m_id, m_reserved_consumer_id);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ m_reserved_consumer_id = consumer_id;\r
+ m_is_reserved = true;\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+int CResource::ReserveShared(int consumer_id)\r
+{\r
+ if (m_is_reserved) {\r
+ SERVER_ERR("rsc(%d) already reserved by (%d) with exclusive mode", m_id, m_reserved_consumer_id);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ m_reserved_count++;\r
+\r
+ if ( (m_shared_count + m_reserved_count) > m_sharable_count) {\r
+ SERVER_ERR("can't reserve(%d) shared(%d), reserved(%d), max(%d)", m_id, m_shared_count, m_reserved_count, m_sharable_count);\r
+ m_reserved_count--;\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ SERVER_INFO("reserve share(%d) shared(%d), reserved(%d), max(%d)", m_id, m_shared_count, m_reserved_count, m_sharable_count);\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+int CResource::Reserve(int consumer_id, rms_requests_resource_state_e state)\r
+{\r
+ return (state == RMS_STATE_SHARABLE) ? ReserveShared(consumer_id):ReserveExclusive(consumer_id);\r
+}\r
+\r
+void CResource::CancelReservation(rms_requests_resource_state_e state)\r
+{\r
+ if (state == RMS_STATE_SHARABLE)\r
+ m_reserved_count = (--m_reserved_count < 0) ? 0 : m_reserved_count;\r
+ else\r
+ m_is_reserved = false;\r
+}\r
+\r
+void CResource::AddConsumer(IN const int consumer_id, IN rms_requests_resource_state_e state)\r
+{\r
+ if (IsRegisteredConsumer(consumer_id)) {\r
+ IncreaseRefCount(consumer_id);\r
+ m_shared_count++;\r
+ SERVER_INFO("[rsc(%d)]increase ref count of (%d), shared(%d) by consumers(%zu)", m_id, consumer_id, m_shared_count, m_shared_consumers.size());\r
+ return;\r
+ }\r
+\r
+ m_consumers.insert(std::pair<int, int>(consumer_id, 1));\r
+ m_consumer_ids.insert(consumer_id);\r
+\r
+ if (state == RMS_STATE_SHARABLE) {\r
+ m_shared_consumers.insert(consumer_id);\r
+ m_shared_count++;\r
+ SERVER_INFO("[rsc(%d)] consumer(%d) shares resource, shared(%d) by consumers(%zu)", m_id, consumer_id, m_shared_count, m_shared_consumers.size());\r
+ }\r
+\r
+ return;\r
+}\r
+\r
+void CResource::ResetConsumer(std::set<int> new_consumers)\r
+{\r
+ m_consumers.clear();\r
+ m_consumer_ids.clear();\r
+ m_shared_consumers.clear();\r
+ m_shared_count = 0;\r
+\r
+ for (auto &it : new_consumers) {\r
+ AddConsumer(it, RMS_STATE_EXCLUSIVE);\r
+ }\r
+}\r
+\r
+bool CResource::IsRegisteredConsumer(int consumer_id)\r
+{\r
+ std::map<int, int>::iterator it = m_consumers.find(consumer_id);\r
+\r
+ return (it != m_consumers.end());\r
+}\r
+\r
+int CResource::IncreaseRefCount(int consumer_id)\r
+{\r
+ int ref_count = 0;\r
+ std::map<int, int>::iterator it = m_consumers.find(consumer_id);\r
+\r
+ if (it == m_consumers.end())\r
+ return 0;\r
+\r
+ ref_count = it->second;\r
+ m_consumers[consumer_id] = ++ref_count;\r
+\r
+ return ref_count;\r
+}\r
+\r
+int CResource::DecreaseRefCount(int consumer_id)\r
+{\r
+ int ref_count = 0;\r
+ std::map<int, int>::iterator it = m_consumers.find(consumer_id);\r
+\r
+ if (it == m_consumers.end())\r
+ return 0;\r
+\r
+ ref_count = it->second;\r
+ --ref_count;\r
+ ref_count = (ref_count < 0) ? 0 : ref_count;\r
+ m_consumers[consumer_id] = ref_count;\r
+\r
+ return ref_count;\r
+}\r
+\r
+int CResource::RemoveConsumer(IN int consumer_id, IN bool force)\r
+{\r
+ if (!IsRegisteredConsumer(consumer_id)) {\r
+ SERVER_ERR("[rsc(%d)] consumer(%d) is not found in list", m_id, consumer_id);\r
+ return 0;\r
+ }\r
+\r
+ int ref_count = DecreaseRefCount(consumer_id);\r
+\r
+ if (m_state == RMS_INTERNAL_STATE_SHARABLE || m_state == RMS_INTERNAL_STATE_SHARED) {\r
+ m_shared_count = (--m_shared_count < 0) ? 0 : m_shared_count;\r
+\r
+ if (force)\r
+ m_shared_count = ((m_shared_count -= ref_count) < 0) ? 0 : m_shared_count;\r
+ }\r
+\r
+ if (ref_count > 0 && !force) {\r
+ SERVER_INFO("consumer(%d) is still sharing resource(%d), ref(%d)", consumer_id, m_id, ref_count);\r
+ return ref_count;\r
+ }\r
+\r
+ m_consumer_ids.erase(consumer_id);\r
+ m_consumers.erase(consumer_id);\r
+ ChangeStateByRelease(consumer_id);\r
+\r
+ return 0;\r
+}\r
+\r
+void CResource::ChangeState(rms_resource_internal_state_e next_state)\r
+{\r
+ if (m_state == next_state)\r
+ return;\r
+\r
+ SERVER_INFO("state changed (%s : %s) - (%s -> %s)",\r
+ rm_convert_category_enum_to_string(m_category_type),\r
+ m_device_name,\r
+ rm_convert_state_enum_to_string(m_state),\r
+ rm_convert_state_enum_to_string(next_state));\r
+\r
+ m_state = next_state;\r
+\r
+ if (m_category_type == RMS_CATEGORY_SCALER_SUB)\r
+ m_SetSubScalerFlag(next_state);\r
+}\r
+\r
+bool CResource::ChangeStateByAllocation(IN rms_requests_resource_state_e requested_state, const int consumer_id, int mv_zone_id)\r
+{\r
+ if (requested_state == RMS_STATE_EXCLUSIVE_CONDITIONAL || requested_state == RMS_STATE_EXCLUSIVE_AUTO || requested_state == RMS_STATE_EXCLUSIVE_PREFERENCE)\r
+ requested_state = RMS_STATE_EXCLUSIVE;\r
+\r
+ rms_resource_internal_state_e allocation_resource_state_matrix[4][3] =\r
+ {{RMS_INTERNAL_STATE_ERROR, RMS_INTERNAL_STATE_SHARABLE, RMS_INTERNAL_STATE_EXCLUSIVE},\r
+ {RMS_INTERNAL_STATE_SHARABLE, RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_ERROR},\r
+ {RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_ERROR},\r
+ {RMS_INTERNAL_STATE_EXCLUSIVE, RMS_INTERNAL_STATE_ERROR, RMS_INTERNAL_STATE_ERROR}};\r
+\r
+ bool need_notify_by_alloc_matrix[4][3] = {{false, true, true},\r
+ {false, true, false},\r
+ {false, true, false},\r
+ {false, false, true}};\r
+\r
+ rms_resource_internal_state_e next_state = allocation_resource_state_matrix[m_state][requested_state];\r
+ SERVER_INFO("m_state %d requested_state %d next_state %d", m_state, requested_state, next_state);\r
+\r
+ bool need_notify = need_notify_by_alloc_matrix[m_state][requested_state];\r
+\r
+ m_is_reserved = false;\r
+ m_reserved_consumer_id = 0;\r
+\r
+ if (next_state == RMS_INTERNAL_STATE_ERROR) {\r
+ SERVER_ERR("state change error! device(%d) (%s) to (%s)", m_id, rm_convert_state_enum_to_string(m_state), rm_convert_state_enum_to_string(next_state));\r
+ return false;\r
+ }\r
+\r
+ m_state = next_state;\r
+\r
+ if (m_category_type == RMS_CATEGORY_SCALER_SUB)\r
+ m_SetSubScalerFlag(next_state);\r
+\r
+ if (mv_zone_id > 0) {\r
+ m_mv_zone_id = mv_zone_id;\r
+ SERVER_INFO("(%d) > zone_id(%d)", m_id, m_mv_zone_id);\r
+ }\r
+\r
+ if (need_notify)\r
+ NotifyObservers(UPDATED_BY_ALLOC, consumer_id);\r
+\r
+ return true;\r
+}\r
+\r
+bool CResource::ChangeStateByRelease(int consumer_id)\r
+{\r
+ rms_resource_internal_state_e current_state = m_state;\r
+ rms_resource_internal_state_e next_state = RMS_INTERNAL_STATE_ERROR;\r
+\r
+ bool need_notify = false;\r
+\r
+ SERVER_INFO("current_state %d m_shared_count %d", current_state, m_shared_count);\r
+\r
+ switch (current_state) {\r
+ case RMS_INTERNAL_STATE_SHARED:\r
+ m_shared_consumers.erase(consumer_id);\r
+ need_notify = true;\r
+\r
+ if (m_shared_count > 1) {\r
+ next_state = RMS_INTERNAL_STATE_SHARED;\r
+ } else if (m_shared_count == 1) {\r
+ next_state = RMS_INTERNAL_STATE_SHARABLE;\r
+ } else {\r
+ next_state = RMS_INTERNAL_STATE_FREE;\r
+ }\r
+ break;\r
+ case RMS_INTERNAL_STATE_EXCLUSIVE:\r
+ case RMS_INTERNAL_STATE_SHARABLE:\r
+ next_state = RMS_INTERNAL_STATE_FREE;\r
+ need_notify = true;\r
+ break;\r
+ case RMS_INTERNAL_STATE_FREE:\r
+ default:\r
+ SERVER_ERR("unexpected resource state (%d)", current_state);\r
+ next_state = RMS_INTERNAL_STATE_FREE;\r
+ break;\r
+ }\r
+\r
+ m_state = next_state;\r
+ SERVER_INFO("m_state %d need notify %d", m_state, need_notify);\r
+\r
+ if (m_category_type == RMS_CATEGORY_SCALER_SUB)\r
+ m_SetSubScalerFlag(next_state);\r
+\r
+ if (need_notify) {\r
+ m_mv_zone_id = -1;\r
+ NotifyObservers(UPDATED_BY_RELEASE, consumer_id);\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+bool CResource::IsAllocatableState(IN rms_requests_resource_state_e requested_state)\r
+{\r
+ bool can_allocation_matrix[4][6] =\r
+ /*requested_state*/ /* PASSIVE */ /*SHARABLE*/ /*EXCLUSIVE*/ /* EXCLUSIVE CON */ /* EXCLUSIVE AUTO */ /* EXCLUSIVE PREFERENCE */\r
+ /* m_state */ /* FREE */{ {false, true, true, true, true, true },\r
+ /* SHARABLE */ { true, true, false, false, false, false },\r
+ /* SHARED */ { true, true, false, false, false, false },\r
+ /* EXCLUSIVE */ { true, false, false, false, false, false } };\r
+\r
+ SERVER_INFO("Status - DevID[%d:%s] / CatID[%d] / CurState[%s] / ReqState[%s]",\r
+ m_id, m_device_name, m_category_type, rm_convert_state_enum_to_string(m_state), rm_convert_requested_state_enum_to_string(requested_state));\r
+\r
+ /* check requested_state is valid */\r
+ if ((requested_state < RMS_STATE_PASSIVE) || (requested_state > RMS_STATE_EXCLUSIVE_PREFERENCE)) {\r
+ SERVER_ERR("rquested state is invalid");\r
+ return false;\r
+ }\r
+\r
+ return can_allocation_matrix[m_state][requested_state];\r
+}\r
+\r
+void CResource::SetDefaultBW(unsigned int bw)\r
+{\r
+ m_default_bw = bw;\r
+ m_occupied_bw = bw;\r
+}\r
+void CResource::SetAllocatedTime(void)\r
+{\r
+ struct timespec t;\r
+ clock_gettime(CLOCK_MONOTONIC, &t);\r
+ unsigned long sec = t.tv_sec * 1000;\r
+ unsigned long nsec = t.tv_nsec / 1000000;\r
+ m_allocated_time = sec + nsec;\r
+}\r
+\r
+void CResource::RegisterObserver(CResourceObserver *observer)\r
+{\r
+ if (!observer) {\r
+ SERVER_ERR("observer NULL");\r
+ return;\r
+ }\r
+\r
+ m_observers.push_back(observer);\r
+}\r
+\r
+void CResource::UnregisterObserver(CResourceObserver *observer)\r
+{\r
+ auto it = std::find(m_observers.begin(), m_observers.end(), observer);\r
+\r
+ if (it == m_observers.end()) {\r
+ SERVER_ERR("not registered observer");\r
+ return;\r
+ }\r
+\r
+ m_observers.erase(it);\r
+\r
+ SERVER_INFO("observer removed");\r
+}\r
+\r
+void CResource::NotifyObservers(resource_update_type_e type, const int consumer_id)\r
+{\r
+ for (CResourceObserver *observer : m_observers) {\r
+ observer->Update(type, m_id, consumer_id);\r
+ }\r
+}\r
+\r
+bool CResource::Allocate(const int consumer_id, rms_requests_resource_state_e state, int mv_zone_id)\r
+{\r
+ if (!ChangeStateByAllocation(state, consumer_id, mv_zone_id))\r
+ return false;\r
+\r
+ AddConsumer(consumer_id, state);\r
+ return true;\r
+}\r
+\r
+void CResource::SetZoneId(int zone_id)\r
+{\r
+ SERVER_INFO("(%d) > zone_id(%d)", m_id, zone_id);\r
+ m_mv_zone_id = zone_id;\r
+}\r
+\r
+void CResource::UpdateAudioCodec(std::string codec_name)\r
+{\r
+ m_audio_codec = codec_name;\r
+}\r
+\r
+bool CResource::IsAudioDevice(void)\r
+{\r
+ if (m_category_type == RMS_CATEGORY_AUDIO_DECODER)\r
+ return true;\r
+ if (m_category_type == RMS_CATEGORY_AUDIO_DECODER_SUB)\r
+ return true;\r
+ if (m_category_type == RMS_CATEGORY_AUDIO_DECODER_PRIMARY)\r
+ return true;\r
+ if ((m_category_type > RMS_CATEGORY_AUDIO_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_AUDIO_DECODER_OPTION_MAX))\r
+ return true;\r
+\r
+ return false;\r
+}\r
+\r
+bool CResource::IsVideoDecoder(void)\r
+{\r
+ if (m_category_type == RMS_CATEGORY_VIDEO_DECODER)\r
+ return true;\r
+ if (m_category_type == RMS_CATEGORY_VIDEO_DECODER_SUB)\r
+ return true;\r
+ if ((m_category_type > RMS_CATEGORY_VIDEO_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_VIDEO_DECODER_OPTION_MAX))\r
+ return true;\r
+ if (m_category_type == RMS_CATEGORY_MJPEG_DECODER)\r
+ return true;\r
+ if ((m_category_type > RMS_CATEGORY_MJPEG_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_MJPEG_DECODER_OPTION_MAX))\r
+ return true;\r
+\r
+ return false;\r
+}\r
+\r
+int CResource::GetFirstConsumer(void)\r
+{\r
+ if (m_consumer_ids.empty())\r
+ return -1;\r
+\r
+ auto it = m_consumer_ids.begin();\r
+ return *it;\r
+}\r
+\r
+int CResource::GetVirtualDeviceId(void)\r
+{\r
+ return (m_virtual_id < RI_VIRTUAL_ID_SCALER) ? m_id : m_virtual_id;\r
+}\r
+\r
+bool CResource::IsJpegDecoder(void)\r
+{\r
+ if (m_category_type == RMS_CATEGORY_JPEG_DECODER)\r
+ return true;\r
+ if ((m_category_type > RMS_CATEGORY_JPEG_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_JPEG_DECODER_OPTION_MAX))\r
+ return true;\r
+\r
+ return false;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <iostream>\r
+\r
+#include <CResourceCategory.h>\r
+#include <CBandwidth.h>\r
+#include <CRequest.h>\r
+#include <CVirtualResource.h>\r
+#include <CDebugUtils.h>\r
+#include <CDependencyController.h>\r
+#include <CAllocateStrategy.h>\r
+#include <CAllocateStrategyProvider.h>\r
+#include <rms_debug.h>\r
+#include <rms_type.h>\r
+\r
+CResourceCategory::CResourceCategory(IN rms_rsc_category_e resource_category_id, IN int category_class)\r
+:m_categoryID(resource_category_id)\r
+{\r
+ m_alloc_strategy = CAllocateStrategyProvider::getInstance()->GetStrategy(resource_category_id, category_class);\r
+ assert(m_alloc_strategy);\r
+}\r
+\r
+void CResourceCategory::AddVirtualResource(IN int device_id, IN CVirtualResource *vresource)\r
+{\r
+ std::map<int, CVirtualResource *>::iterator it = m_device_id_to_vresource_map.find(device_id);\r
+\r
+ if (it != m_device_id_to_vresource_map.end())\r
+ return;\r
+\r
+ m_device_id_to_vresource_map.insert(std::pair<int, CVirtualResource *>(device_id, vresource));\r
+}\r
+\r
+CResource *CResourceCategory::ReserveCandidate(CRequest *req, bool apply_promotion)\r
+{\r
+ CVirtualResource *vrsc = m_alloc_strategy->findCandidate(m_device_id_to_vresource_map, req);\r
+\r
+ if (!vrsc)\r
+ return NULL;\r
+\r
+ if (m_alloc_strategy->reserveResource(vrsc, req) != RMS_OK) {\r
+ SERVER_INFO("can't find candidate (%d)", m_categoryID);\r
+ return NULL;\r
+ }\r
+\r
+ SERVER_INFO("candidate found (%d:%d)", m_categoryID, vrsc->GetResource()->GetDeviceID());\r
+\r
+ req->SetResult(RMS_OK);\r
+ req->SetReason(RMS_ERR_TYPE_NONE);\r
+\r
+ return vrsc->GetResource();\r
+}\r
+\r
+bool CResourceCategory::hasFreeStateResource(void)\r
+{\r
+ for (auto& it : m_device_id_to_vresource_map) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (resource->IsFreeState())\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+void CResourceCategory::MakeResourceMapSortedByAllocTime(std::multimap<unsigned long, CVirtualResource *> *resource_map)\r
+{\r
+ for (auto& it : m_device_id_to_vresource_map) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *rsc = vresource->GetResource();\r
+\r
+ resource_map->insert(std::pair<unsigned long, CVirtualResource *>(rsc->GetAllocatedTime(), vresource));\r
+ }\r
+}\r
+\r
+void CResourceCategory::GetRetirableConsumers(CRequest *req,\r
+ std::multimap<int, int>* return_ids_in_category,\r
+ rms_error_type_e *err_type)\r
+{\r
+ assert(return_ids_in_category);\r
+\r
+ std::multimap<unsigned long, CVirtualResource *> sorted_resource_map;\r
+ MakeResourceMapSortedByAllocTime(&sorted_resource_map);\r
+ m_alloc_strategy->GetRetirableConsumers(sorted_resource_map, req, return_ids_in_category, err_type);\r
+}\r
+\r
+bool CResourceCategory::IsAvailableToUse(rms_requests_resource_state_e request_state)\r
+{\r
+ CResource *resource;\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+ CBandwidth *bandwidth = CBandwidth::GetInstance();\r
+\r
+ for (auto& it : m_device_id_to_vresource_map) {\r
+ CVirtualResource *vresource = it.second;\r
+ resource = vresource->GetResource();\r
+\r
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters())) {\r
+ SERVER_ERR("Not available: Mem Cluster is occupied.");\r
+ continue;\r
+ }\r
+\r
+ if (vresource->GetBW() > bandwidth->GetAvail()) {\r
+ SERVER_ERR("Not available: BW is insufficient!!");\r
+ continue;\r
+ }\r
+\r
+ if ((request_state == RMS_STATE_SHARABLE) && (!resource->IsSharableDevice())) {\r
+ SERVER_ERR("Not available: resource(%d) cannot be shared", resource->GetDeviceID());\r
+ continue;\r
+ }\r
+\r
+ if (resource->IsAllocatableState(request_state))\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+void CResourceCategory::GetResources(std::map<int, CResource*> *resource_map)\r
+{\r
+ int i = 0;\r
+ for (auto& it : m_device_id_to_vresource_map) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+ resource_map->insert(std::pair<int, CResource*>(i++, resource));\r
+ }\r
+}\r
+\r
+CResource *CResourceCategory::FindMainResource(void)\r
+{\r
+ for (auto& it : m_device_id_to_vresource_map) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (resource->IsMainDevice())\r
+ return resource;\r
+ }\r
+\r
+ return NULL;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <iostream>\r
+#include <assert.h>\r
+#include <stdlib.h>\r
+#include <glib.h>\r
+#include <gio/gio.h>\r
+\r
+#include <ri-module-api.h>\r
+#include <vconf.h>\r
+\r
+#include <rms_debug.h>\r
+#include <rms_type.h>\r
+\r
+#include <CDebugUtils.h>\r
+#include <CAudioCodecCollection.h>\r
+#include <CBandwidth.h>\r
+#include <CVirtualResource.h>\r
+#include <CConsumer.h>\r
+#include <CConsumerContainer.h>\r
+#include <CDependencyController.h>\r
+#include <CResourceDB.h>\r
+#include <CVideoController.h>\r
+#include <CResourceState.h>\r
+\r
+CResourceDB *CResourceDB::m_instance = NULL;\r
+\r
+CResourceDB *CResourceDB::getInstance(void)\r
+{\r
+ if (!m_instance) {\r
+ m_instance = new(std::nothrow) CResourceDB;\r
+ assert(m_instance);\r
+ }\r
+\r
+ return m_instance;\r
+}\r
+\r
+CResourceCategory *CResourceDB::FindResourceCategory(IN rms_rsc_category_e category_id)\r
+{\r
+ std::map<rms_rsc_category_e, CResourceCategory*>::iterator it = m_resourceCategoryMap.find(category_id);\r
+\r
+ if (it == m_resourceCategoryMap.end())\r
+ return NULL;\r
+\r
+ return (*it).second;\r
+}\r
+\r
+CResource *CResourceDB::FindResource(IN const int device_id)\r
+{\r
+ std::map<int, CResource*>::iterator it = m_deviceid_to_rsc.find(device_id);\r
+\r
+ if (it == m_deviceid_to_rsc.end()) {\r
+ SERVER_ERR("no device id(%d) in DB", device_id);\r
+ return NULL;\r
+ }\r
+\r
+ return (*it).second;\r
+}\r
+\r
+CVirtualResource *CResourceDB::FindVirtualResource(const int vid)\r
+{\r
+ auto it = m_v_deviceid_to_rsc.find(vid);\r
+\r
+ return (it == m_v_deviceid_to_rsc.end()) ? nullptr : it->second;\r
+}\r
+\r
+void CResourceDB::AddVirtualDeviceID(IN CVirtualResource *vresource)\r
+{\r
+ int vrsc_id = vresource->GetVResourceID();\r
+\r
+ std::map<int, CVirtualResource *>::iterator it = m_v_deviceid_to_rsc.find(vrsc_id);\r
+\r
+ if (it != m_v_deviceid_to_rsc.end())\r
+ return;\r
+\r
+ m_v_deviceid_to_rsc.insert(std::pair<int, CVirtualResource *>(vrsc_id, vresource));\r
+}\r
+\r
+void CResourceDB::AddDeviceID(IN int device_id, IN CResource *resource)\r
+{\r
+ std::map<int, CResource*>::iterator it = m_deviceid_to_rsc.find(device_id);\r
+ \r
+ if (it != m_deviceid_to_rsc.end())\r
+ return;\r
+\r
+ m_deviceid_to_rsc.insert(std::pair<int, CResource*>(device_id, resource));\r
+}\r
+\r
+void CResourceDB::AddDeviceName(IN const char *device_name, IN CResource *resource)\r
+{\r
+ auto it = m_devicename_to_rsc.find(std::string(device_name));\r
+ \r
+ if (it != m_devicename_to_rsc.end()) {\r
+ SERVER_DBG("already registered device name(%s) in DB", device_name);\r
+ return;\r
+ }\r
+\r
+ m_devicename_to_rsc.insert(std::pair<std::string, CResource*>(std::string(device_name), resource));\r
+}\r
+\r
+void CResourceDB::AddResourceCategory(IN rms_rsc_category_e category_id, IN CResourceCategory *resource_category)\r
+{\r
+ std::map<rms_rsc_category_e, CResourceCategory*>::iterator it = m_resourceCategoryMap.find(category_id);\r
+\r
+ if (it != m_resourceCategoryMap.end())\r
+ return;\r
+\r
+ m_resourceCategoryMap.insert(std::pair<rms_rsc_category_e, CResourceCategory*>(category_id, resource_category));\r
+}\r
+\r
+CResource *CResourceDB::FindResource(const char *device_name)\r
+{\r
+ auto it = m_devicename_to_rsc.find(std::string(device_name));\r
+\r
+ return (it == m_devicename_to_rsc.end()) ? NULL : it->second;\r
+}\r
+\r
+void CResourceDB::AddVirtualResource(IN CVirtualResource *vrsc,\r
+ IN rms_rsc_category_e resource_category_id,\r
+ IN const char *name,\r
+ IN const char *path,\r
+ IN std::set<unsigned int> mem_cluster_info,\r
+ IN unsigned int device_id_unique,\r
+ IN int is_main_device,\r
+ IN const char *audio_codec,\r
+ IN int sharable_count,\r
+ IN int mixing_count,\r
+ IN CResourceObserver *observer)\r
+{\r
+ assert(name);\r
+ assert(path);\r
+\r
+ CResource *rsc = FindResource(name);\r
+\r
+ if (!rsc) {\r
+ rsc = new CResource(device_id_unique, resource_category_id, name, path, mem_cluster_info, is_main_device, audio_codec, sharable_count);\r
+\r
+ AddDeviceName(name, rsc);\r
+ AddDeviceID(device_id_unique, rsc);\r
+\r
+ rsc->RegisterObserver(this);\r
+ rsc->RegisterObserver(observer);\r
+ }\r
+\r
+ vrsc->SetResource(rsc);\r
+\r
+ CAudioCodecCollection::getInstance()->registerAudioCodec(audio_codec, mixing_count);\r
+\r
+ if (rsc->GetDefaultBW() == 0)\r
+ rsc->SetDefaultBW(vrsc->GetBW());\r
+\r
+ AddVirtualDeviceID(vrsc);\r
+}\r
+\r
+void CResourceDB::UpdateBWbyRelease(CResource *rsc)\r
+{\r
+ if (!rsc)\r
+ return;\r
+\r
+ if (rsc->GetBW() == 0)\r
+ return;\r
+\r
+ CBandwidth *bw = CBandwidth::GetInstance();\r
+ bw->RemoveConsumer(rsc->GetDeviceID(), rsc->GetCurCategory(), rsc->GetCategoryClass());\r
+ bw->Increase(rsc->GetBW(), rsc->GetCurCategory(), rsc->GetCategoryClass(), rsc->GetDeviceID());\r
+\r
+ return;\r
+}\r
+\r
+void CResourceDB::UpdateByRelease(CResource *resource, const int device_id, const int consumer_id)\r
+{\r
+ UpdateBWbyRelease(resource);\r
+\r
+ if (resource->IsVideoDecoder())\r
+ RemoveActiveVideoDecoder(device_id, resource->GetCategoryClass());\r
+\r
+ if (resource->IsJpegDecoder())\r
+ RemoveActiveJpegDecoder(device_id);\r
+\r
+ RemoveResourceHasZoneId(resource->GetDeviceID());\r
+}\r
+\r
+void CResourceDB::UpdateBWbyAllocation(const unsigned int bandwidth, CResource *rsc)\r
+{\r
+ CBandwidth *bw = CBandwidth::GetInstance();\r
+ bw->Decrease(bandwidth, rsc->GetCurCategory(), rsc->GetCategoryClass(), rsc->GetDeviceID());\r
+\r
+ //SERVER_INFO("bw updated avail(%d)/max(%d)", bw->GetAvail(), bw->GetMax());\r
+}\r
+\r
+void CResourceDB::UpdateByAllocation(CResource *resource, const int device_id, const int consumer_id)\r
+{\r
+ unsigned int bw = resource->GetBW();\r
+\r
+ if (bw > 0) {\r
+ UpdateBWbyAllocation(bw, resource);\r
+ CBandwidth::GetInstance()->AddConsumer(device_id, consumer_id, resource->GetCurCategory(), resource->GetCategoryClass());\r
+ }\r
+\r
+ if (resource->IsVideoDecoder())\r
+ AddActiveVideoDecoder(device_id, consumer_id, resource->GetCategoryClass());\r
+\r
+ if (resource->IsScaler())\r
+ SetVirtualScalerId(resource);\r
+\r
+ if (resource->IsJpegDecoder())\r
+ AddActiveJpegDecoder(device_id, consumer_id);\r
+\r
+ if (resource->GetZoneId() > 0)\r
+ InsertResourceHasZoneId(resource);\r
+}\r
+\r
+void CResourceDB::SetVirtualScalerId(CResource *resource)\r
+{\r
+ int scaler_id = GetVirtualScalerId(resource);\r
+\r
+ SERVER_INFO("map scaler (%d:%d)", scaler_id, resource->GetDeviceID());\r
+\r
+ resource->SetVirtualDeviceId(scaler_id);\r
+ InsertVirtualScaler(scaler_id, resource);\r
+}\r
+\r
+void CResourceDB::PrintVirtualScalerMap(void)\r
+{\r
+ for (auto &it : m_scaler_map) {\r
+ if (it.second == nullptr) {\r
+ //SERVER_INFO("[%d : %d (%s)]", it.first, 0, "null");\r
+ continue;\r
+ }\r
+ //SERVER_INFO("[%d : %d (%s)/(%d)]", it.first, it.second->GetDeviceID(), it.second->GetName().c_str(), it.second->GetVirtualDeviceId());\r
+ }\r
+}\r
+\r
+int CResourceDB::GetVirtualScalerId(CResource *resource)\r
+{\r
+ CResource *rsc = nullptr;\r
+\r
+ for (auto &it : m_scaler_map) {\r
+ rsc = it.second;\r
+ if (rsc == nullptr)\r
+ continue;\r
+ if (rsc->GetDeviceID() == resource->GetDeviceID())\r
+ return it.first;\r
+ }\r
+\r
+ return resource->GetDedicatedVirtualDeviceId();\r
+}\r
+\r
+void CResourceDB::AddActiveVideoDecoder(const int device_id, const int consumer_id, const int category_class)\r
+{\r
+ m_active_vdecs.insert(std::pair<int, int>(device_id, consumer_id));\r
+\r
+ if (category_class == RMS_CATEGORY_CLASS_N_DECODING)\r
+ m_active_nvdecs.insert(std::pair<int, int>(device_id, consumer_id));\r
+}\r
+\r
+void CResourceDB::RemoveActiveVideoDecoder(const int device_id, const int category_class)\r
+{\r
+ m_active_vdecs.erase(device_id);\r
+\r
+ if (category_class == RMS_CATEGORY_CLASS_N_DECODING)\r
+ m_active_nvdecs.erase(device_id);\r
+}\r
+\r
+void CResourceDB::AddActiveJpegDecoder(const int device_id, const int consumer_id)\r
+{\r
+ m_active_jdecs.insert(std::pair<int, int>(device_id, consumer_id));\r
+}\r
+\r
+void CResourceDB::RemoveActiveJpegDecoder(const int device_id)\r
+{\r
+ m_active_jdecs.erase(device_id);\r
+}\r
+\r
+int CResourceDB::GetActiveDecoderNum(void)\r
+{\r
+ int num = 0;\r
+\r
+ num += m_active_vdecs.size();\r
+ num += m_active_jdecs.size();\r
+\r
+ return num;\r
+}\r
+\r
+void CResourceDB::PrintVideoDecoderConsumers(void)\r
+{\r
+ for (auto const &it : m_active_vdecs) {\r
+ SERVER_INFO("dev(%d) by (%d)", it.first, it.second);\r
+ }\r
+}\r
+\r
+bool CResourceDB::HasAvailableDecoder(void)\r
+{\r
+ int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;\r
+ int active_vdecs = m_active_vdecs.size();\r
+ int active_ndecs = m_active_nvdecs.size();\r
+\r
+ SERVER_INFO("active(%d) / n_dec(%d) / max(%d / %d)", active_vdecs, active_ndecs, max_vdecs, m_max_vdecs);\r
+\r
+ if (active_ndecs > 0)\r
+ active_vdecs = active_vdecs + (1 - active_ndecs);\r
+\r
+ if (active_vdecs >= max_vdecs)\r
+ PrintVideoDecoderConsumers();\r
+\r
+ return (active_vdecs < max_vdecs);\r
+}\r
+\r
+bool CResourceDB::HasAvailableDecoderNDecoding(void)\r
+{\r
+ int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;\r
+ int active_vdecs = m_active_vdecs.size();\r
+ int active_ndecs = m_active_nvdecs.size();\r
+\r
+ SERVER_INFO("active(%d) / n_dec(%d) / max(%d %d)", active_vdecs, active_ndecs, max_vdecs, m_max_vdecs);\r
+\r
+ if (active_ndecs > 0) {\r
+ active_vdecs = active_vdecs + (1 - active_ndecs);\r
+ return true;\r
+ }\r
+\r
+ if (active_vdecs >= max_vdecs)\r
+ PrintVideoDecoderConsumers();\r
+\r
+ return (active_vdecs < max_vdecs);\r
+}\r
+\r
+bool CResourceDB::HasAvailableDecoder(std::multimap<int, int> retirables)\r
+{\r
+ int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;\r
+ std::map<int, int> retirables_vdecs;\r
+\r
+ SERVER_INFO("max(%d %d)", max_vdecs, m_max_vdecs);\r
+\r
+ for (auto &it : retirables) {\r
+ CResource *rsc = FindResource(it.first);\r
+ if (!rsc)\r
+ continue;\r
+\r
+ if (rsc->IsVideoDecoder())\r
+ retirables_vdecs.insert(std::pair<int, int>(it.first, it.second));\r
+ }\r
+\r
+ int active_vdecs = m_active_vdecs.size();\r
+ int active_ndecs = m_active_nvdecs.size();\r
+ int retirable_vdecs = retirables_vdecs.size();\r
+ int retirable_ndecs = CountNDecoders(retirables_vdecs);\r
+\r
+ int remain = 0;\r
+\r
+ if ((active_ndecs - retirable_ndecs) > 0)\r
+ remain = (active_vdecs - retirable_vdecs) + (1 - (active_ndecs - retirable_ndecs));\r
+ else\r
+ remain = active_vdecs - retirable_vdecs;\r
+\r
+ SERVER_INFO("remain(%d)/max(%d), av(%d)/an(%d)/rv(%d)/rn(%d)", remain, max_vdecs, active_vdecs, active_ndecs, retirable_vdecs, retirable_ndecs);\r
+\r
+ if (remain >= max_vdecs)\r
+ PrintVideoDecoderConsumers();\r
+\r
+ return (remain < max_vdecs);\r
+}\r
+\r
+bool CResourceDB::HasAvailableDecoderNDecoding(std::multimap<int, int> retirables)\r
+{\r
+ int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;\r
+ std::map<int, int> retirables_vdecs;\r
+\r
+ SERVER_INFO("max(%d %d)", max_vdecs, m_max_vdecs);\r
+\r
+ for (auto &it : retirables) {\r
+ CResource *rsc = FindResource(it.first);\r
+ if (!rsc)\r
+ continue;\r
+\r
+ if (rsc->IsVideoDecoder())\r
+ retirables_vdecs.insert(std::pair<int, int>(it.first, it.second));\r
+ }\r
+\r
+ int active_vdecs = m_active_vdecs.size();\r
+ int active_ndecs = m_active_nvdecs.size();\r
+ int retirable_vdecs = retirables_vdecs.size();\r
+ int retirable_ndecs = CountNDecoders(retirables_vdecs);\r
+\r
+ int remain = 0;\r
+\r
+ if ((active_ndecs - retirable_ndecs) > 0)\r
+ remain = (active_vdecs - retirable_vdecs) + (1 - (active_ndecs - retirable_ndecs));\r
+ else\r
+ remain = active_vdecs - retirable_vdecs;\r
+\r
+ SERVER_INFO("remain(%d)/max(%d), av(%d)/an(%d)/rv(%d)/rn(%d)", remain, max_vdecs, active_vdecs, active_ndecs, retirable_vdecs, retirable_ndecs);\r
+\r
+ if (active_ndecs > 0 && retirable_ndecs > 0)\r
+ return true;\r
+\r
+ if (remain >= max_vdecs)\r
+ PrintVideoDecoderConsumers();\r
+\r
+ return (remain < max_vdecs);\r
+}\r
+\r
+int CResourceDB::CountNDecoders(std::map<int, int> retirables_vdecs)\r
+{\r
+ int ndecs = 0;\r
+ for (auto &it_rsc : retirables_vdecs) {\r
+ auto it_ndec = m_active_nvdecs.find(it_rsc.first);\r
+\r
+ if (it_ndec != m_active_nvdecs.end())\r
+ ndecs++;\r
+ }\r
+\r
+ SERVER_INFO("ndecs(%d) in retirables(%zu)", ndecs, retirables_vdecs.size());\r
+ return ndecs;\r
+}\r
+\r
+void CResourceDB::Update(resource_update_type_e type, const int device_id, const int consumer_id)\r
+{\r
+ CResource *resource = FindResource(device_id);\r
+\r
+ if (!resource)\r
+ return;\r
+\r
+ switch (type) {\r
+ case UPDATED_BY_ALLOC:\r
+ SERVER_WARN("UPDATED_BY_ALLOC");\r
+ UpdateByAllocation(resource, device_id, consumer_id);\r
+ break;\r
+ case UPDATED_BY_RELEASE:\r
+ SERVER_WARN("UPDATED_BY_RELEASE");\r
+ UpdateByRelease(resource, device_id, consumer_id);\r
+ break;\r
+ default:\r
+ SERVER_ERR("unexpected update type (%d)", type);\r
+ break;\r
+ }\r
+\r
+ NotifyResourceStateUpdatedAsync(resource, consumer_id);\r
+}\r
+\r
+void CResourceDB::AddReclaimResources(consumer_reclaim_s *consumers)\r
+{\r
+ for (int i = 0; i < consumers->ret_quantity; i++) {\r
+ for (int j = 0; j < consumers->consumer_info[i].n_conflicted; j++) {\r
+ SERVER_INFO("add reclaim rsc (%d)", consumers->consumer_info[i].conflicted_resources[j].device_id);\r
+ m_reclaim_rscs.insert(consumers->consumer_info[i].conflicted_resources[j].device_id);\r
+ }\r
+ }\r
+}\r
+\r
+void CResourceDB::ClearReclaimResources(void)\r
+{\r
+ m_reclaim_rscs.clear();\r
+}\r
+\r
+gboolean CResourceDB::NotifyResourceStateUpdated(gpointer data)\r
+{\r
+ if (!data) {\r
+ SERVER_ERR("invalid data");\r
+ return G_SOURCE_REMOVE;\r
+ }\r
+\r
+ CResourceState *state = (CResourceState*) data;\r
+\r
+ GError *error = NULL;\r
+ GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);\r
+\r
+ if (!connection) {\r
+ SERVER_ERR("failed to get connection (%s)", (error) ? error->message : "unknown");\r
+ goto out;\r
+ }\r
+\r
+ SERVER_INFO("notify state changed (device id %d( type %d) : state %d)", state->GetDeviceId(), state->GetCategoryType(), state->GetState());\r
+\r
+ if (!g_dbus_connection_emit_signal(connection,\r
+ NULL,\r
+ RM_DBUS_OBJ_PATH,\r
+ RM_DBUS_INTERFACE_NAME,\r
+ "RscStateChanged",\r
+ g_variant_new("(iiiis)", state->GetDeviceId(), state->GetCategoryType(), state->GetState(), state->GetConsumerId(), state->GetAppId().c_str()),\r
+ &error))\r
+ SERVER_ERR("failed to send state changed (%d:%s)", state->GetDeviceId(), (error) ? error->message : "unknown");\r
+\r
+out:\r
+ if (error)\r
+ g_error_free(error);\r
+\r
+ delete state;\r
+ return G_SOURCE_REMOVE;\r
+}\r
+\r
+void CResourceDB::NotifyResourceStateUpdatedAsync(CResource *resource, int consumer_id)\r
+{\r
+ int device_id = resource->GetDeviceID();\r
+ CConsumer *consumer = CConsumerContainer::getInstance()->findConsumer(consumer_id);\r
+ std::string app_id = consumer->GetAppID();\r
+\r
+ if (app_id.empty())\r
+ app_id = consumer->GetCmdName();\r
+\r
+ SERVER_INFO("device id (%d) consumer id (%d)", device_id, consumer_id);\r
+\r
+ if (m_reclaim_rscs.find(device_id) != m_reclaim_rscs.end()) {\r
+ SERVER_DBG("skip to notify state updated (%d)", device_id);\r
+ return;\r
+ }\r
+\r
+ CResourceState *state = new CResourceState(resource->GetDeviceID(), resource->GetCategoryType(), consumer_id, resource->GetState(), app_id);\r
+ g_idle_add(&CResourceDB::NotifyResourceStateUpdated, state);\r
+}\r
+\r
+CResource *CResourceDB::FindMainResource(rms_rsc_category_e category_id)\r
+{\r
+ CResourceCategory *category = FindResourceCategory(category_id);\r
+ if (!category) {\r
+ SERVER_ERR("category(%d) not found", category_id);\r
+ return NULL;\r
+ }\r
+\r
+ return category->FindMainResource();\r
+}\r
+\r
+void CResourceDB::FindMainResources(IN std::map<int, CResource*> *resource_map)\r
+{\r
+ rms_rsc_category_e categories[5] = {RMS_CATEGORY_VIDEO_DECODER, RMS_CATEGORY_VIDEO_DECODER_UHD, RMS_CATEGORY_SCALER, RMS_CATEGORY_AUDIO_DECODER, RMS_CATEGORY_AUDIO_MAIN_OUT};\r
+ CResource *resource = NULL;\r
+\r
+ for (int i = 0; i < 6; i++) {\r
+ resource = FindMainResource(categories[i]);\r
+ if (!resource) {\r
+ SERVER_INFO("no main resource for (%d)", categories[i]);\r
+ continue;\r
+ }\r
+\r
+ resource_map->insert(std::pair<int, CResource*>(resource->GetDeviceID(), resource));\r
+ }\r
+}\r
+\r
+void CResourceDB::FindActiveVideoDecoders(IN std::map<int, CResource*> *resource_map)\r
+{\r
+ CResource *rsc = nullptr;\r
+ for (auto const &it : m_active_vdecs) {\r
+ rsc = FindResource(it.first);\r
+ if (!rsc)\r
+ continue;\r
+ resource_map->insert(std::pair<int, CResource*>(it.first, rsc));\r
+ }\r
+}\r
+\r
+void CResourceDB::GetScalerList(std::map<int, CResource*> *scalers)\r
+{\r
+ CResource *rsc = nullptr;\r
+ for (auto &it : m_deviceid_to_rsc) {\r
+ rsc = it.second;\r
+ if (!rsc->IsScaler())\r
+ continue;\r
+\r
+ scalers->insert(std::pair<int, CResource*>(rsc->GetDeviceID(), rsc));\r
+ }\r
+}\r
+\r
+void CResourceDB::InitScalerTable(void)\r
+{\r
+ CResource *rsc = nullptr;\r
+ int sub_scaler_count = 0;\r
+ int vid = 0;\r
+\r
+ std::map<int, CResource*> scalers;\r
+ GetScalerList(&scalers);\r
+\r
+ for (auto &it : scalers) {\r
+ rsc = it.second;\r
+\r
+ if (!rsc->IsMainDevice())\r
+ sub_scaler_count++;\r
+\r
+ vid = (rsc->IsMainDevice()) ? RI_VIRTUAL_ID_SCALER : (RI_VIRTUAL_ID_SCALER + sub_scaler_count);\r
+ rsc->SetDedicatedVirtualDeviceId(vid);\r
+ rsc->SetVirtualDeviceId(vid);\r
+ //SERVER_INFO("insert scaler (%d:%d)", vid, rsc->GetDeviceID());\r
+ m_scaler_map.insert(std::pair<int, CResource*>(vid, rsc));\r
+ }\r
+}\r
+\r
+int CResourceDB::FindRealDeviceId(int virtual_id)\r
+{\r
+ auto it = m_scaler_map.find(virtual_id);\r
+\r
+ if (it == m_scaler_map.end())\r
+ return virtual_id;\r
+\r
+ CResource *rsc = it->second;\r
+\r
+ return (rsc == nullptr) ? virtual_id : rsc->GetDeviceID();\r
+}\r
+\r
+CResource *CResourceDB::FindScaler(int virtual_id)\r
+{\r
+ auto it = m_scaler_map.find(virtual_id);\r
+ if (it == m_scaler_map.end())\r
+ return nullptr;\r
+\r
+ return it->second;\r
+}\r
+\r
+int CResourceDB::ToScalerId(int device_id)\r
+{\r
+ const int SCALER_ID_MAIN = 0;\r
+ const int SCALER_ID_SUB = 1;\r
+ const int SCALER_ID_SUB2 = 2;\r
+ const int SCALER_ID_SUB3 = 3;\r
+ const int SCALER_ID_UNKNOWN = 99;\r
+ int source_id = SCALER_ID_UNKNOWN;\r
+\r
+ switch (device_id) {\r
+ case RMS_DEVICE_SCALER:\r
+ source_id = SCALER_ID_MAIN;\r
+ break;\r
+ case RMS_DEVICE_SCALER_SUB:\r
+ source_id = SCALER_ID_SUB;\r
+ break;\r
+ case RMS_DEVICE_SCALER_SUB2:\r
+ source_id = SCALER_ID_SUB2;\r
+ break;\r
+ case RMS_DEVICE_SCALER_SUB3:\r
+ source_id = SCALER_ID_SUB3;\r
+ break;\r
+ default:\r
+ SERVER_ERR("unexpected device_id(%d)", device_id);\r
+ break;\r
+ }\r
+\r
+ return source_id;\r
+}\r
+\r
+void CResourceDB::UpdateVirtualScalerIds(void)\r
+{\r
+ std::map<int, int> scaler_map;\r
+ for (auto &it : m_scaler_map) {\r
+ if (it.second == nullptr) {\r
+ SERVER_INFO("[%d : %d (%s)]", it.first, 0, "null");\r
+ continue;\r
+ }\r
+\r
+ scaler_map.insert(std::pair<int, int>(it.first, ToScalerId(it.second->GetDeviceID())));\r
+ SERVER_INFO("[%d : %d (%s)/(%d)]", it.first, it.second->GetDeviceID(), it.second->GetName().c_str(), it.second->GetVirtualDeviceId());\r
+ }\r
+\r
+ CVideoController::GetInstance()->UpdateVirtualScalerIds(scaler_map);\r
+}\r
+\r
+void CResourceDB::InsertVirtualScaler(int virtual_id, CResource *resource)\r
+{\r
+ m_scaler_map.erase(virtual_id);\r
+ m_scaler_map.insert(std::pair<int, CResource*>(virtual_id, resource));\r
+ PrintVirtualScalerMap();\r
+}\r
+\r
+int CResourceDB::SwapScaler(int id_a, int id_b)\r
+{\r
+ CResource *rsc_a = FindScaler(id_a);\r
+ CResource *rsc_b = FindScaler(id_b);\r
+\r
+ SERVER_INFO("scaler swap (%d <-> %d)", id_a, id_b);\r
+\r
+ if (!rsc_a || !rsc_b) {\r
+ SERVER_ERR("invalid scaler id_a(%d)/id_b(%d)", id_a, id_b);\r
+ return -1;\r
+ }\r
+\r
+ std::set<int> consumers_a = rsc_a->GetConsumers();\r
+ std::set<int> consumers_b = rsc_b->GetConsumers();\r
+\r
+ int zone_a = rsc_a->GetZoneId();\r
+ int zone_b = rsc_b->GetZoneId();\r
+\r
+ rsc_a->SetZoneId(zone_b);\r
+ rsc_b->SetZoneId(zone_a);\r
+\r
+ rms_resource_internal_state_e state_a = (rms_resource_internal_state_e) rsc_a->GetState();\r
+ rms_resource_internal_state_e state_b = (rms_resource_internal_state_e) rsc_b->GetState();\r
+ rsc_a->ChangeState(state_b);\r
+ rsc_b->ChangeState(state_a);\r
+\r
+ UpdateConsumerInfoOfResource(rsc_a, consumers_b, id_b);\r
+ UpdateConsumerInfoOfResource(rsc_b, consumers_a, id_a);\r
+\r
+ // update resource info of each consumer\r
+ SwapResource(consumers_a, rsc_a->GetDeviceID(), rsc_b->GetDeviceID());\r
+ SwapResource(consumers_b, rsc_b->GetDeviceID(), rsc_a->GetDeviceID());\r
+\r
+ // update memcluster owners\r
+ CDependencyController::getInstance()->SwapConsumers(rsc_a->GetDeviceID(), consumers_a, rsc_b->GetDeviceID(), consumers_b);\r
+\r
+ // update virtual scaler table\r
+ InsertVirtualScaler(id_a, rsc_b);\r
+ InsertVirtualScaler(id_b, rsc_a);\r
+ return 0;\r
+}\r
+\r
+void CResourceDB::UpdateConsumerInfoOfResource(CResource *resource, std::set<int> new_consumers, int new_virtual_id)\r
+{\r
+ resource->ResetConsumer(new_consumers);\r
+ resource->SetVirtualDeviceId(new_virtual_id);\r
+}\r
+\r
+void CResourceDB::SwapResource(std::set<int> consumers, int cur_device_id, int new_device_id)\r
+{\r
+ CConsumer *consumer;\r
+ for (auto &it : consumers) {\r
+ consumer = CConsumerContainer::getInstance()->findConsumer(it);\r
+ if (!consumer) {\r
+ SERVER_ERR("invalid consumer (%d)", it);\r
+ continue;\r
+ }\r
+\r
+ SERVER_INFO("swap resource (%d):(%d>%d)", it, cur_device_id, new_device_id);\r
+\r
+ if (consumer->IsUsingResource(new_device_id)) {\r
+ SERVER_INFO("no need to swap (%d:%d)", it, new_device_id);\r
+ continue;\r
+ }\r
+ consumer->ReleaseResource(cur_device_id);\r
+ consumer->AddResource(new_device_id);\r
+ }\r
+}\r
+\r
+void CResourceDB::InsertResourceHasZoneId(CResource *rsc)\r
+{\r
+ int device_id = rsc->GetDeviceID();\r
+ auto it = m_rscs_has_zone_id.find(device_id);\r
+\r
+ if (it != m_rscs_has_zone_id.end())\r
+ return;\r
+\r
+ m_rscs_has_zone_id.insert(std::pair<int, CResource*>(device_id, rsc));\r
+ SERVER_INFO("inserted (%d:%d:%zu)", device_id, rsc->GetZoneId(), m_rscs_has_zone_id.size());\r
+}\r
+\r
+void CResourceDB::RemoveResourceHasZoneId(int device_id)\r
+{\r
+ if (m_rscs_has_zone_id.empty())\r
+ return;\r
+\r
+ auto it = m_rscs_has_zone_id.find(device_id);\r
+ if (it != m_rscs_has_zone_id.end())\r
+ return;\r
+\r
+ m_rscs_has_zone_id.erase(device_id);\r
+ SERVER_INFO("removed (%d:%zu)", device_id, m_rscs_has_zone_id.size());\r
+}\r
+\r
+void CResourceDB::ResetZoneIds(void)\r
+{\r
+ CResource *rsc = nullptr;\r
+ SERVER_INFO("Reset zone ids");\r
+\r
+ for (auto &it : m_rscs_has_zone_id) {\r
+ rsc = it.second;\r
+ if (!rsc)\r
+ continue;\r
+ rsc->SetZoneId(-1);\r
+ }\r
+ m_rscs_has_zone_id.clear();\r
+}\r
--- /dev/null
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <iostream>
+#include <assert.h>
+#include <vector>
+#include <set>
+#include <map>
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+#include <algorithm>
+
+#include <ri-common-type.h>
+#include <ri-module-api.h>
+#include <ri-category-type.h>
+#include <rms_debug.h>
+
+#include <CResourceManager.h>
+#include <CResource.h>
+#include <CResourceDB.h>
+#include <CVirtualResource.h>
+#include <CResourceCategory.h>
+#include <CDebugUtils.h>
+#include <CConsumer.h>
+#include <CConsumerContainer.h>
+#include <CRequester.h>
+#include <CBandwidth.h>
+#include <CDependencyController.h>
+#include <CAllocateModeStrategy.h>
+#include <CAllocateModeStrategyProvider.h>
+
+void allocateCandidate(CRequest *req)
+{
+ if (req->GetResult() != RMS_OK)
+ return;
+
+ CResource *rsc = CResourceDB::getInstance()->FindResource(req->GetCandidateDevice());
+ CRequester *requester = req->getRequester();
+ CConsumer *consumer = CConsumerContainer::getInstance()->findConsumer(requester->getHandle());
+
+ if (!consumer) {
+ SERVER_ERR("unregister consumer (%d)", requester->getHandle());
+ return;
+ }
+
+ req->ResetResult();
+
+ if (!rsc->Allocate(consumer->GetId(), (rms_requests_resource_state_e) req->GetState(), req->GetMultiviewZoneId())) {
+ SERVER_ERR("can't allocate a resource(%d:%d) for %d", req->GetCategory(), req->GetState(), requester->getHandle());
+ return;
+ }
+
+ req->SetResult(RMS_OK);
+ req->SetAllocatedDevice(rsc->GetDeviceID());
+ req->SetAllocatedVirtualDevice(rsc->GetVirtualDeviceId());
+
+ consumer->AddResource(rsc->GetDeviceID());
+}
+
+CResourceManager::CResourceManager(void)
+{
+ m_is_db_created = 0;
+ m_error_type = RMS_ERR_TYPE_NONE;
+ m_consumers = CConsumerContainer::getInstance();
+ m_db = CResourceDB::getInstance();
+}
+
+void CResourceManager::MakeRequests(CRequester *requester, rms_msg_request *reqs, std::vector<CRequest *> *requests)
+{
+ for (int i = 0; i < reqs->request_num; i++) {
+ CRequest *request = new CRequest(requester);
+ request->SetCategory(reqs->resource[i], reqs->resource_option[i]);
+ request->SetState(reqs->state[i]);
+
+ requests->push_back(request);
+ }
+}
+
+int CResourceManager::AllocateResources(rms_msg_request *req, rms_return_device_s *allocated_devices)
+{
+ CRequester *requester = new CRequester(req);
+ std::vector<CRequest *> requests;
+ rms_allocate_result_s alloc_result;
+
+ MakeRequests(requester, req, &requests);
+
+ CAllocateModeStrategy *strategy = CAllocateModeStrategyProvider::getInstance()->GetStrategy(req);
+
+ if (!strategy->CanAllocateResources(requests, &alloc_result))
+ goto out;
+
+ AllocateCandidates(requests);
+
+out:
+ strategy->WriteAllocResult(&alloc_result, requests, allocated_devices);
+
+ std::for_each(requests.begin(), requests.end(), [](CRequest *request) { request->PrintResult(); delete request; });
+
+ delete requester;
+ delete strategy;
+
+ //SERVER_INFO("cid(%d)/pid(%d)/requested(%d), result(%d)-reason(%d)", req->handle, req->pid, req->request_num, alloc_result.result, alloc_result.reason);
+
+ return alloc_result.result;
+
+}
+
+void CResourceManager::AllocateCandidates(std::vector<CRequest *> requests)
+{
+ std::for_each(requests.begin(), requests.end(), allocateCandidate);
+}
+
+int CResourceManager::RegisterResources(void)
+{
+ if (m_is_db_created) {
+ SERVER_ERR("Resource manager DB exists");
+ return RMS_OK;
+ }
+
+ m_db->SetMaxVideoDecoders(ri_get_max_video_decoder_num());
+
+ CBandwidth *bandwidth = CBandwidth::GetInstance();
+ bandwidth->SetMax((unsigned int) ri_get_system_bw());
+
+ int num_of_device = 0;
+ ri_device_common_attr_s *rm_device_list = NULL;
+
+ if (ri_get_device_list(&num_of_device, &rm_device_list) != RI_OK) {
+ if (rm_device_list != NULL)
+ free(rm_device_list);
+
+ SERVER_ERR("failed to get device list");
+ return RMS_ERROR;
+ }
+
+ //SERVER_INFO("system bw(%d), num of device(%d)", bandwidth->GetMax(), num_of_device);
+
+ CDependencyController *dc = CDependencyController::getInstance();
+ CResourceObserver *observer = dc;
+
+ for (int i = 0; i < num_of_device; i++) {
+ ri_device_common_attr_s dev = rm_device_list[i];
+
+ std::set<unsigned int> mem_clusters;
+ for (unsigned int j = 0; j < dev.n_mem_clusters; j++) {
+ mem_clusters.insert(dev.mem_clusters[j]);
+ dc->RegisterMemCluster(dev.mem_clusters[j]);
+ }
+
+ int category_class = ri_get_category_class(dev.category);
+ CVirtualResource *vrsc = new CVirtualResource((int) dev.id, (rms_rsc_category_e)(dev.category), dev.bw, mem_clusters, dev.is_main_device, dev.audio_codec, category_class);
+
+ m_db->AddVirtualResource(vrsc, (rms_rsc_category_e) dev.category_main, dev.name,
+ dev.path, mem_clusters, dev.id_unique,
+ dev.is_main_device, dev.audio_codec, dev.sharable_count,
+ dev.mixing_count, observer);
+
+ CResourceCategory *category = m_db->FindResourceCategory((rms_rsc_category_e) dev.category);
+
+ if (!category) {
+ category = new CResourceCategory((rms_rsc_category_e) dev.category, category_class);
+ }
+
+ category->AddVirtualResource(vrsc->GetVResourceID(), vrsc);
+ m_db->AddResourceCategory((rms_rsc_category_e) dev.category, category);
+ }
+
+ if (rm_device_list != NULL)
+ free(rm_device_list);
+
+ m_db->InitScalerTable();
+
+ m_is_db_created = 1;
+
+ return RMS_OK;
+}
+
+int CResourceManager::ReleaseResourcesOfPid(IN const int pid)
+{
+ std::map<int, CConsumer*> consumers = m_consumers->findConsumers(pid);
+
+ for (auto const &it : consumers) {
+ CConsumer *consumer = it.second;
+
+ SERVER_INFO("release resources of pid(%d)/cid(%d)", pid, consumer->GetId());
+
+ ReleaseResources(consumer->GetId());
+
+ m_consumers->RemoveConsumer(it.first);
+ delete consumer;
+ }
+
+ return RMS_OK;
+}
+
+int CResourceManager::UnregisterConsumer(IN const int consumer_id)
+{
+ CConsumer *consumer = m_consumers->findConsumer(consumer_id);
+
+ if (!consumer) {
+ SERVER_INFO("not existing consumer(%d)", consumer_id);
+ return RMS_ERROR;
+ }
+
+ ReleaseResources(consumer_id);
+
+ m_consumers->RemoveConsumer(consumer_id);
+ delete consumer;
+
+ SERVER_INFO("consumer(%d) removed", consumer_id);
+
+ return RMS_OK;
+}
+
+void CResourceManager::ReleaseResources(const int consumer_id)
+{
+ CConsumer *consumer = m_consumers->findConsumer(consumer_id);
+ if (!consumer) {
+ SERVER_ERR("Request for Deallocation - cid[%d] : Failed (Not registered consumer)", consumer_id);
+ return;
+ }
+
+ std::set<int> resources = consumer->GetResources();
+ CResource *rsc = nullptr;
+
+ for (auto const &it : resources) {
+ consumer->ReleaseResource(it);
+ SERVER_INFO("result (0) - con(%d:%s)/devId(%d)", consumer->GetId(), consumer->GetAppID().empty() ? consumer->GetCmdName().c_str() : consumer->GetAppID().c_str(), it);
+
+ if (!(rsc = m_db->FindResource(it)))
+ continue;
+ rsc->RemoveConsumer(consumer->GetId(), true);
+ }
+}
+
+int CResourceManager::ReleaseResources(IN const int consumer_id, IN const rms_requests_device_s *req)
+{
+ SERVER_INFO("Request for Deallocation - cid[%d] / requested[%d]", consumer_id, req->resources_num);
+ int device_id = 0;
+ CConsumer *consumer = m_consumers->findConsumer(consumer_id);
+
+ if (!consumer) {
+ SERVER_ERR("Request for Deallocation - cid[%d] : Failed (Not registered consumer)", consumer_id);
+ return RMS_ERROR;
+ }
+
+ for (int i = 0; i < req->resources_num; i++) {
+ device_id = m_db->FindRealDeviceId(req->devices[i].device_id);
+
+ if (consumer->ReleaseResource(device_id) != RMS_OK) {
+ SERVER_WARN("Request for Deallocation - cid[%d]/DevID[%d] / RealDevID[%d] Req State[%d] : Failed (Invalid device id)",
+ consumer_id, req->devices[i].device_id, req->devices[i].requested_state, device_id);
+ return RMS_ERROR;
+ }
+
+ CResource *rsc = m_db->FindResource(device_id);
+
+ if (!rsc)
+ continue;
+
+ rsc->RemoveConsumer(consumer_id, false);
+ rsc->ResetBW();
+ SERVER_INFO("result (0) - con(%d:%s) / devId(%d) / rId(%d)",
+ consumer_id, consumer->GetAppID().empty() ? consumer->GetCmdName().c_str():consumer->GetAppID().c_str(), req->devices[i].device_id, device_id);
+ }
+
+ SERVER_WARN("Request for Deallocation - cid[%d] / requested #[%d] / REMAINING[%d] : SUCCESS", consumer_id, req->resources_num, consumer->GetResourceNum());
+ return RMS_OK;
+}
+
+bool CResourceManager::IsReclaimed(IN const int device_id, IN const int consumer_id)
+{
+ CResource *rsc = m_db->FindResource(device_id);
+
+ if (!rsc) {
+ SERVER_ERR("invalid device_id (%d)", device_id);
+ return true;
+ }
+
+ if (rsc->IsFreeState()) {
+ SERVER_INFO("FreeState [device id %d consumer id %d]", device_id, consumer_id);
+ return true;
+ }
+
+ if (rsc->IsSharableState()) {
+ SERVER_INFO("ShareState [device id %d consumer id %d]", device_id, consumer_id);
+ return true;
+ }
+
+ CConsumer *consumer = m_consumers->findConsumer(consumer_id);
+
+ if (!consumer) {
+ SERVER_INFO("not existing consumer(%d). maybe unregistered", consumer_id);
+ return true;
+ }
+
+ if (rsc->IsSharableState() && !consumer->IsUsingResource(device_id))
+ return true;
+
+ SERVER_WARN("device_id %d consumer_id %d state %d", device_id, consumer_id, rsc->GetState());
+
+ return false;
+}
+
+void CResourceManager::MakeResourceMapPerConsumer(std::multimap<int, int> *device_id_to_consumer_id_map, std::map<int, std::set<int> > *consumer_id_to_resource_set_map)
+{
+ assert(device_id_to_consumer_id_map);
+ assert(consumer_id_to_resource_set_map);
+
+ for (auto const &it_ret : *device_id_to_consumer_id_map) {
+ int device_id = it_ret.first;
+ int consumer_id = it_ret.second;
+
+ auto it_count = consumer_id_to_resource_set_map->find(consumer_id);
+
+ if (it_count != consumer_id_to_resource_set_map->end()) { // Already consumer id exists in the map, just add device id into it
+ std::set<int> rsc_count = (*it_count).second;
+ rsc_count.insert(device_id);
+
+ consumer_id_to_resource_set_map->operator[](consumer_id) = rsc_count;
+ } else {
+ std::set<int> rsc_count;
+ rsc_count.insert(device_id);
+ consumer_id_to_resource_set_map->insert(std::pair< int, std::set<int> >(consumer_id, rsc_count));
+ }
+ }
+}
+
+void CResourceManager::MakeConsumerInfoToBeReturned(consumer_reclaim_s *return_consumer, std::map<int, std::set<int> > *consumer_id_to_resource_set_map)
+{
+ assert(return_consumer);
+ assert(consumer_id_to_resource_set_map);
+
+ return_consumer->ret_quantity = consumer_id_to_resource_set_map->size();
+ return_consumer->consumer_info = (rms_consumer_tobe_returned_s*) calloc(1, sizeof(rms_consumer_tobe_returned_s) * return_consumer->ret_quantity);
+
+ assert(return_consumer->consumer_info);
+
+ int consumer_idx = 0;
+
+ for (std::map< int, std::set<int> >::iterator it = consumer_id_to_resource_set_map->begin(); it != consumer_id_to_resource_set_map->end(); it++, consumer_idx++) {
+ int consumer_id = (*it).first;
+ std::set<int> resource_set = (*it).second;
+
+ CConsumer *consumer = m_consumers->findConsumer(consumer_id);
+ assert(consumer);
+
+ int process_id = consumer->GetPid();
+ int resources_num = consumer->GetResourceNum();
+
+ return_consumer->consumer_info[consumer_idx].consumer_id = consumer_id;
+ return_consumer->consumer_info[consumer_idx].process_id = process_id;
+ return_consumer->consumer_info[consumer_idx].n_conflicted = resource_set.size();
+ return_consumer->consumer_info[consumer_idx].resources_num = resources_num;
+ return_consumer->consumer_info[consumer_idx].conflicted_resources = (rms_conflicted_resource_info_s*) calloc(1, sizeof(rms_conflicted_resource_info_s) * resource_set.size());
+
+ assert(return_consumer->consumer_info[consumer_idx].conflicted_resources);
+
+ int resource_idx = 0;
+
+ for (std::set<int>::iterator it_rsc = resource_set.begin(); it_rsc != resource_set.end(); it_rsc++, resource_idx++) {
+ int rsc_id = *it_rsc;
+ CResource *rsc = m_db->FindResource(rsc_id);
+ assert(rsc);
+ return_consumer->consumer_info[consumer_idx].conflicted_resources[resource_idx].virtual_id = rsc->GetVirtualDeviceId();
+ return_consumer->consumer_info[consumer_idx].conflicted_resources[resource_idx].device_id = rsc_id;
+ return_consumer->consumer_info[consumer_idx].conflicted_resources[resource_idx].category_id = rsc->GetCategoryType();;
+ }
+ }
+}
+
+void CResourceManager::PrintConsumerInfoToBeReturned(consumer_reclaim_s *consumer_info)
+{
+ char name[RMS_NAME_BUF_SIZE] = {0,};
+
+ for (int i = 0; i < consumer_info->ret_quantity; i++) {
+ rms_get_cmd_name(consumer_info->consumer_info[i].process_id, name, sizeof(name));
+
+ SERVER_WARN("(%d) Retirable cid[%d]/pid[%ld:%s] - conflicted [%d] of requested[%d]",
+ i + 1,
+ consumer_info->consumer_info[i].consumer_id,
+ consumer_info->consumer_info[i].process_id,
+ name,
+ consumer_info->consumer_info[i].n_conflicted,
+ consumer_info->consumer_info[i].resources_num);
+
+ for (int rsc_cnt = 0; rsc_cnt < consumer_info->consumer_info[i].n_conflicted; rsc_cnt++) {
+ SERVER_WARN("(%d) conflicted - DevID[%d] / VID[%d] / catid[%d:%s]", rsc_cnt+1, consumer_info->consumer_info[i].conflicted_resources[rsc_cnt].device_id,
+ consumer_info->consumer_info[i].conflicted_resources[rsc_cnt].virtual_id,
+ consumer_info->consumer_info[i].conflicted_resources[rsc_cnt].category_id,
+ rm_convert_category_enum_to_string(consumer_info->consumer_info[i].conflicted_resources[rsc_cnt].category_id));
+ }
+ }
+}
+
+int CResourceManager::FindReclaimableConsumers(rms_msg_request *req, consumer_reclaim_s *return_consumer, int *zone_id)
+{
+ assert(return_consumer);
+
+ CRequester *requester = new CRequester(req);
+ std::vector<CRequest *> requests;
+ MakeRequests(requester, req, &requests);
+
+ std::multimap<int, int> retirable_device_to_consumer; //device id, consumer id
+
+ for (auto const &it : requests) {
+ CRequest *request = it;
+ CResourceCategory *category = m_db->FindResourceCategory(request->GetCategory());
+
+ if (!category) {
+ SERVER_ERR("not existing category(%d)", request->GetCategory());
+ continue;
+ }
+
+ category->GetRetirableConsumers(request, &retirable_device_to_consumer, &m_error_type);
+
+ if (request->GetMultiviewZoneId() > 0)
+ *zone_id = request->GetMultiviewZoneId();
+ }
+
+ std::map< int, std::set<int> > consumer_id_resource; //consumer id, rsc set
+
+ MakeResourceMapPerConsumer(&retirable_device_to_consumer, &consumer_id_resource);
+ MakeConsumerInfoToBeReturned(return_consumer, &consumer_id_resource);
+ PrintConsumerInfoToBeReturned(return_consumer);
+
+ std::for_each(requests.begin(), requests.end(), [](CRequest *request) { delete request; });
+ delete requester;
+
+ return RMS_OK;
+}
+
+void categoryAvailableToUse(CRequest *request)
+{
+ CResourceCategory *category = CResourceDB::getInstance()->FindResourceCategory(request->GetCategory());
+
+ if (!category) {
+ request->SetResult(RMS_ERROR);
+ SERVER_ERR("not existing category (%d)", request->GetCategory());
+ return;
+ }
+
+ rms_rsc_category_e category_id = request->GetCategory();
+
+ if (!category->hasFreeStateResource()) {
+ request->SetResult(RMS_ERROR);
+ SERVER_ERR("all resources of category (%d) are being used", category_id);
+ return;
+ }
+
+ if (!category->IsAvailableToUse((rms_requests_resource_state_e) request->GetState())) {
+ request->SetResult(RMS_ERROR);
+ SERVER_ERR("category (%d) is NOT available (HW constraint condition)", category_id);
+ return;
+ }
+
+ request->SetResult(RMS_OK);
+
+ SERVER_INFO("category (%d) is available", category_id);
+}
+
+int CResourceManager::IsCategoryAvailableToUse(rms_msg_request *req, int *is_available)
+{
+ assert(req);
+ assert(is_available);
+
+ CRequester *requester = new CRequester(req);
+ std::vector<CRequest *> requests;
+ MakeRequests(requester, req, &requests);
+
+ *is_available = 1;
+
+ std::for_each(requests.begin(), requests.end(), categoryAvailableToUse);
+ std::for_each(requests.begin(), requests.end(),
+ [is_available](CRequest *request) { if (request->GetResult() != RMS_OK) *is_available = 0; });
+
+ std::for_each(requests.begin(), requests.end(), [](CRequest *request) { delete request; });
+ delete requester;
+
+ return RMS_OK;
+}
+
+int CResourceManager::SetAppId(int consumer_id, const char *app_id)
+{
+ CConsumer *consumer = m_consumers->findConsumer(consumer_id);
+
+ if (!consumer) {
+ SERVER_ERR("Failed to set app_id : not existing consumer (%d)", consumer_id);
+ return RMS_ERROR;
+ }
+
+ consumer->SetAppID(app_id);
+
+ return RMS_OK;
+}
+
+int CResourceManager::RegisterConsumer(int consumer_id, int process_id, const char *app_id, int main_priority, int sub_priority)
+{
+ CConsumer *consumer = m_consumers->findConsumer(consumer_id);
+
+ if (consumer) {
+ SERVER_ERR("already registered consumer(%d)", consumer_id);
+ return RMS_ERROR;
+ }
+
+ rms_consumer_s consumer_info;
+ consumer_info.consumer_id = consumer_id;
+ consumer_info.app_pid = 0;
+ consumer_info.priority.main = main_priority;
+ consumer_info.priority.sub = sub_priority;
+ consumer_info.process_id = process_id;
+
+ snprintf(consumer_info.app_id, RMS_APPID_LENGTH, "%s", (app_id == NULL) ? "" : app_id);
+
+ consumer = new CConsumer(&consumer_info);
+
+ return (m_consumers->AddConsumer(consumer_id, consumer)) ? RMS_OK : RMS_ERROR;
+}
+
+int CResourceManager::GetResourceState(int device_id)
+{
+ CResource *rsc = m_db->FindResource(device_id);
+
+ if (!rsc) {
+ SERVER_ERR("device not found(%d)", device_id);
+ return -1;
+ }
+
+ return (int) rsc->GetState();
+}
+
+int CResourceManager::FindDeviceId(int virtual_id)
+{
+ return m_db->FindRealDeviceId(virtual_id);
+}
+
+int CResourceManager::SwapResources(int device_id_a, int device_id_b)
+{
+ CResource *rsc_a = m_db->FindResource(device_id_a);
+ CResource *rsc_b = m_db->FindResource(device_id_b);
+
+ if (!rsc_a || !rsc_b) {
+ SERVER_ERR("resource not found (%d:%d)", device_id_a, device_id_b);
+ return -1;
+ }
+
+ if (!rsc_a->IsScaler() || !rsc_b->IsScaler()) {
+ SERVER_ERR("swap not supported for (%d:%d)", device_id_a, device_id_b);
+ return -1;
+ }
+
+ int result = m_db->SwapScaler(rsc_a->GetVirtualDeviceId(), rsc_b->GetVirtualDeviceId());
+ if (result == 0)
+ m_db->UpdateVirtualScalerIds();
+
+ return result;
+}
+
+int CResourceManager::RestoreResources(int category_id)
+{
+ int scaler_ids[4] = {RMS_DEVICE_SCALER, RMS_DEVICE_SCALER_SUB, RMS_DEVICE_SCALER_SUB2, RMS_DEVICE_SCALER_SUB3};
+ bool swapped = false;
+
+ if (category_id != RMS_CATEGORY_SCALER && category_id != RMS_CATEGORY_SCALER_MULTIVIEW) {
+ SERVER_ERR("restore not supported (%d)", category_id);
+ return -1;
+ }
+
+ for (int i = 0; i < 4; i++) {
+ CResource *scaler = m_db->FindResource(scaler_ids[i]);
+ if (!scaler) {
+ SERVER_ERR("not existing scaler(%d)", scaler_ids[i]);
+ continue;
+ }
+
+ SERVER_INFO("(%d) vid(%d)/dedicated(%d)", scaler_ids[i], scaler->GetVirtualDeviceId(), scaler->GetDedicatedVirtualDeviceId());
+ if (scaler->GetVirtualDeviceId() != scaler->GetDedicatedVirtualDeviceId()) {
+ if (m_db->SwapScaler(scaler->GetDedicatedVirtualDeviceId(), scaler->GetVirtualDeviceId()) == 0)
+ swapped = true;
+ }
+ }
+
+ if (swapped)
+ m_db->UpdateVirtualScalerIds();
+
+ return 0;
+}
+
+int CResourceManager::GetResourceList(int category_id, GVariantBuilder *builder)
+{
+ CResourceCategory *category = m_db->FindResourceCategory((rms_rsc_category_e) category_id);
+
+ if (!category) {
+ SERVER_ERR("not existing category (%d)", category_id);
+ return -1;
+ }
+
+ std::map<int, CResource*> resource_map;
+ category->GetResources(&resource_map);
+
+ SERVER_INFO("category(%d), n_rsc(%zu)", category_id, resource_map.size());
+
+ for (auto &it : resource_map) {
+ CResource *rsc = it.second;
+ CConsumer *consumer = CConsumerContainer::getInstance()->findConsumer(rsc->GetFirstConsumer());
+ g_variant_builder_add(builder, "(iissi)", rsc->GetDeviceID(), rsc->GetState(), rsc->GetDevicePath(), consumer? consumer->GetAppID().c_str() : "", consumer ? consumer->GetId() : 0);
+ }
+
+ return 0;
+}
+
+int CResourceManager::GetScalerState(int category_id, GVariantBuilder *builder)
+{
+ CResourceCategory *category = m_db->FindResourceCategory((rms_rsc_category_e) category_id);
+ if (!category) {
+ SERVER_ERR("not existing category (%d)", category_id);
+ return -1;
+ }
+
+ int cid = -1;
+ std::string app_id;
+ CConsumer *consumer;
+ std::map<int, CResource*> resource_map;
+ category->GetResources(&resource_map);
+
+ for (auto &it : resource_map) {
+ CResource *rsc = it.second;
+ cid = rsc->GetFirstConsumer();
+
+ consumer = CConsumerContainer::getInstance()->findConsumer(cid);
+ if (consumer)
+ app_id = (consumer->GetAppID().empty()) ? consumer->GetCmdName():consumer->GetAppID();
+
+ SERVER_INFO("(%d:%d:%d:%d:%d:%d:%s)", category_id, rsc->GetCurCategory(), rsc->GetDeviceID(), rsc->GetState(), cid, rsc->GetZoneId(), (app_id.empty() ? "" : app_id.c_str()));
+
+ g_variant_builder_add(builder, "(iiiiis)", category_id, rsc->GetDeviceID(), rsc->GetState(), cid, rsc->GetZoneId(), (app_id.empty() ? "" : app_id.c_str()));
+
+ app_id.erase();
+ }
+
+ return 0;
+}
+
+int CResourceManager::GetScalerState(GVariantBuilder *builder)
+{
+ GetScalerState(RMS_CATEGORY_SCALER, builder);
+ GetScalerState(RMS_CATEGORY_SCALER_SUB, builder);
+ GetScalerState(RMS_CATEGORY_SCALER_SUB2, builder);
+ GetScalerState(RMS_CATEGORY_SCALER_SUB3, builder);
+ return 0;
+}
+
+int CResourceManager::GetResourceCollectionState(int collection, GVariantBuilder *builder)
+{
+ CConsumer *consumer;
+ int cid = -1;
+ std::string app_id("");
+ std::map<int, CResource*> resource_map;
+
+ if (collection == RMS_RSC_COLLECTION_ACTIVE_VIDEO_DECODER)
+ m_db->FindActiveVideoDecoders(&resource_map);
+ else
+ m_db->FindMainResources(&resource_map);
+
+ //SERVER_INFO("collection(%d), n_rsc(%d)", collection, resource_map.size());
+
+ for (auto &it : resource_map) {
+ CResource *rsc = it.second;
+ cid = rsc->GetFirstConsumer();
+ consumer = CConsumerContainer::getInstance()->findConsumer(cid);
+
+ if (consumer)
+ app_id = (consumer->GetAppID().empty()) ? consumer->GetCmdName() : consumer->GetAppID();
+
+ g_variant_builder_add(builder, "(isiiis)", rsc->GetDeviceID(), rsc->GetDevicePath(), rsc->GetState(), rsc->GetCurCategory(), cid, app_id.c_str());
+
+ app_id.clear();
+ }
+
+ return 0;
+}
+
+int CResourceManager::GetActiveDecoderNum(void)
+{
+ return CResourceDB::getInstance()->GetActiveDecoderNum();
+}
+
+int CResourceManager::GetActiveAudioOut(int consumer_id)
+{
+ int result = RMS_AUDIO_OUT_NONE;
+ CConsumer *consumer = CConsumerContainer::getInstance()->findConsumer(consumer_id);
+ if (!consumer) {
+ SERVER_INFO("not existing consumer (%d)", consumer_id);
+ return RMS_AUDIO_OUT_NONE;
+ }
+
+ std::set<int> rscs = consumer->GetResources();
+ for (auto &it : rscs) {
+ if (it == RMS_DEVICE_AUDIO_MAIN_OUT)
+ result = (result | RMS_AUDIO_OUT_MAIN);
+ if (it == RMS_DEVICE_AUDIO_SUB_OUT)
+ result = (result | RMS_AUDIO_OUT_SUB);
+ }
+
+ return result;
+}
+
+int CResourceManager::GetScalerHWId(int zone_id)
+{
+ CResource *rsc;
+ CResourceDB *db = CResourceDB::getInstance();
+ std::map<int, CResource*> scalers;
+ db->GetScalerList(&scalers);
+
+ for (auto &it: scalers) {
+ rsc = it.second;
+
+ if (rsc->GetZoneId() == zone_id)
+ return db->ToScalerId(rsc->GetDeviceID());
+ }
+
+ SERVER_ERR("scaler not found at zone(%d)", zone_id);
+ return -1;
+}
+
+int CResourceManager::GetZoneId(int device_id)
+{
+ CResource *rsc = m_db->FindResource(device_id);
+ if (!rsc) {
+ SERVER_ERR("device not found(%d)", device_id);
+ return -1;
+ }
+
+ return rsc->GetZoneId();
+}
+
+void CResourceManager::ResetZoneIds(void)
+{
+ CResourceDB::getInstance()->ResetZoneIds();
+}
+
+void CResourceManager::UpdateZoneIds(std::string app_id, int zone_id)
+{
+ std::map<int, CConsumer *> consumers = CConsumerContainer::getInstance()->FindConsumers(app_id);
+ if (consumers.empty()) {
+ SERVER_INFO("consumer(%s) not found", app_id.c_str());
+ return;
+ }
+
+ CConsumer *consumer;
+ CResource *rsc;
+ CResourceDB *db = CResourceDB::getInstance();
+ std::set<int> rscs;
+
+ for (auto &it : consumers) {
+ consumer = it.second;
+ rscs = consumer->GetResources();
+ //SERVER_INFO("update zone ids (%s:%d:%d)", app_id.c_str(), consumer->GetId(), zone_id);
+ if (rscs.empty())
+ continue;
+ for (auto &it_rsc : rscs) {
+ rsc = db->FindResource(it_rsc);
+ if (!rsc)
+ continue;
+ rsc->SetZoneId(zone_id);
+ }
+ rscs.clear();
+ }
+}
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <iostream>\r
+#include <CResourceState.h>\r
+\r
+CResourceState::CResourceState(int device_id, int category_type, int consumer_id, int state, std::string app_id)\r
+{\r
+ m_device_id = device_id;\r
+ m_category_type = category_type;\r
+ m_consumer_id = consumer_id;\r
+ m_state = state;\r
+ m_app_id = app_id;\r
+}
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <new>\r
+#include <assert.h>\r
+#include <unistd.h>\r
+#include <trace.h>\r
+#include <rms_debug.h>\r
+#include <CVideoController.h>\r
+\r
+#define LWIPC_WM_READY "/tmp/.wm_ready"\r
+#define LWIPC_TIMEOUT_MS 10000\r
+#define LWIPC_SWAP_DONE "/tmp/.scaler_swap_done"\r
+#define LWIPC_SWAP_DONE_TIMEOUT_MS 3000\r
+#define LWIPC_SWAP_DONE_TIMEOUT_DBG_MS 4000\r
+#define RMS_IS_DEBUG_IMAGE (access("/etc/debug", F_OK) == 0)\r
+\r
+CVideoController *CVideoController::m_instance = nullptr;\r
+\r
+static void registry_handle_global(void *data, struct wl_registry *wl_registry, uint32_t id, const char *interface, uint32_t version)\r
+{\r
+ void **tizen_video_rsc = (void**)data;\r
+\r
+ if (strncmp(interface, "tizen_video_rsc", sizeof("tizen_video_rsc")))\r
+ return;\r
+\r
+ SERVER_INFO("%p : %s", tizen_video_rsc, interface);\r
+ //*tizen_video_rsc = wl_registry_bind(wl_registry, id, &tizen_video_rsc_interface, 1);\r
+}\r
+\r
+static void registry_handle_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name)\r
+{\r
+\r
+}\r
+\r
+void CVideoController::WaylandDisplayCreate(void)\r
+{\r
+ SERVER_INFO("Create Start");\r
+\r
+ SERVER_INFO("%s is created", LWIPC_WM_READY);\r
+ m_wl_display = wl_display_connect(nullptr);\r
+\r
+ if (!m_wl_display) {\r
+ SERVER_ERR("Failed to connect to the wayland display");\r
+ return;\r
+ }\r
+\r
+ m_wl_registry = wl_display_get_registry(m_wl_display);\r
+ wl_registry_add_listener(m_wl_registry, &m_registry_listener, &m_tizen_video_rsc);\r
+ SERVER_INFO("Add listener : %p", &m_tizen_video_rsc);\r
+\r
+ wl_display_roundtrip(m_wl_display);\r
+\r
+ if (!m_tizen_video_rsc)\r
+ SERVER_ERR("Failed to get tizen_video_rsc");\r
+\r
+ SERVER_INFO("Create Done");\r
+}\r
+\r
+void CVideoController::WaylandDisplayDestroy(void)\r
+{\r
+ if (m_tizen_video_rsc) {\r
+ //tizen_video_rsc_destroy(m_tizen_video_rsc);\r
+ m_tizen_video_rsc = nullptr;\r
+ }\r
+\r
+ if (m_wl_registry) {\r
+ wl_registry_destroy(m_wl_registry);\r
+ m_wl_registry = nullptr;\r
+ }\r
+\r
+ SERVER_INFO("Display disconnect");\r
+\r
+ if (m_wl_display) {\r
+ wl_display_roundtrip(m_wl_display);\r
+ wl_display_disconnect(m_wl_display);\r
+ m_wl_display = nullptr;\r
+ }\r
+\r
+ SERVER_INFO("Destroy Done");\r
+}\r
+\r
+CVideoController::CVideoController(void) : m_wl_display(nullptr), m_wl_registry(nullptr), m_tizen_video_rsc(nullptr), m_waiting_thread(nullptr)\r
+{\r
+ m_registry_listener.global = registry_handle_global;\r
+ m_registry_listener.global_remove = registry_handle_global_remove;\r
+ WaylandDisplayCreate();\r
+ m_lock_ctr = CLockController::GetInstance();\r
+\r
+ SERVER_INFO("Initialize Done");\r
+}\r
+\r
+CVideoController::~CVideoController(void)\r
+{\r
+ WaylandDisplayDestroy();\r
+ SERVER_INFO("Finalize Done");\r
+}\r
+\r
+CVideoController *CVideoController::GetInstance(void)\r
+{\r
+ if (m_instance == nullptr)\r
+ {\r
+ m_instance = new(std::nothrow) CVideoController();\r
+ assert(m_instance);\r
+ }\r
+\r
+ return m_instance;\r
+}\r
+\r
+void CVideoController::UpdateVirtualScalerIds(std::map<int, int> scaler_id_map)\r
+{\r
+ struct wl_array mapping_list;\r
+ scaler_id_pair_t *scaler_id_pair = NULL;\r
+\r
+ wl_array_init(&mapping_list);\r
+ SERVER_ERR("Update virtual scaler ids");\r
+\r
+ for (auto it = scaler_id_map.begin(); it != scaler_id_map.end(); it++) {\r
+ scaler_id_pair = (scaler_id_pair_t*)wl_array_add(&mapping_list, sizeof(scaler_id_pair_t));\r
+ scaler_id_pair->virtual_scaler_id = it->first;\r
+ scaler_id_pair->scaler_id = it->second;\r
+ SERVER_ERR("scaler(%d:%d)", it->first, it->second);\r
+ }\r
+\r
+ //tizen_video_rsc_map_scaler_id(m_tizen_video_rsc, &mapping_list);\r
+\r
+ wl_display_roundtrip(m_wl_display);\r
+ wl_array_release(&mapping_list);\r
+\r
+ RunWaitingThread();\r
+}\r
+\r
+gpointer CVideoController::WaitingThread(gpointer data)\r
+{\r
+ assert(data);\r
+ CVideoController *ctr = (CVideoController*) data;\r
+\r
+ ctr->m_lock_ctr->Unlock(ResourceType::VIDEO_SCALER);\r
+ ctr->m_waiting_thread = nullptr;\r
+ return 0;\r
+}\r
+\r
+void CVideoController::RunWaitingThread(void)\r
+{\r
+ if (m_waiting_thread)\r
+ {\r
+ SERVER_ERR("already created");\r
+ return;\r
+ }\r
+\r
+ m_lock_ctr->Lock(ResourceType::VIDEO_SCALER);\r
+\r
+ m_waiting_thread = g_thread_new("waiting_swap_done", WaitingThread, this);\r
+ if (m_waiting_thread == nullptr) {\r
+ m_lock_ctr->Unlock(ResourceType::VIDEO_SCALER);\r
+ SERVER_ERR("failed to create waiting_swap_done thread");\r
+ return;\r
+ }\r
+\r
+ SERVER_ERR("waiting_swap_done thread created");\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <CVirtualResource.h>\r
+#include <rms_debug.h>\r
+#include <CResource.h>\r
+\r
+CVirtualResource::CVirtualResource(const int virtual_device_id, const rms_rsc_category_e category_type, unsigned int bw, std::set<unsigned int> dependent, bool is_main_device, const char *audio_codec, int category_class)\r
+:m_vir_rsc_id(virtual_device_id), m_category_type(category_type), m_vir_rsc_bw(bw), m_is_main_device(is_main_device), m_category_class(category_class)\r
+{\r
+ m_mem_clusters = dependent;\r
+\r
+ if (audio_codec)\r
+ m_audio_codec.assign(audio_codec);\r
+}\r
+\r
+void CVirtualResource::SetResource(CResource *resource)\r
+{\r
+ m_rsc = resource;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <rms_debug.h>\r
+#include <CAudioCodec.h>\r
+\r
+CAudioCodec::CAudioCodec(const char * name)\r
+:m_ref_count(0), m_ref_count_max(0)\r
+{\r
+ m_name.assign(name);\r
+}\r
+\r
+CAudioCodec::~CAudioCodec()\r
+{\r
+}\r
+\r
+void CAudioCodec::increaseRef(int device_id, int consumer_id)\r
+{\r
+ if (m_ref_count_max == 0)\r
+ return;\r
+\r
+ if (m_ref_count >= m_ref_count_max) {\r
+ SERVER_ERR("(%s) can't increase ref count (%d, %d) by %d", m_name.c_str(), m_ref_count, m_ref_count_max, consumer_id);\r
+ return;\r
+ }\r
+\r
+ m_ref_count++;\r
+\r
+ auto it = m_consumers.find(consumer_id);\r
+\r
+ m_resources.insert(std::pair<int, int>(device_id, consumer_id));\r
+\r
+ if (it == m_consumers.end()) {\r
+ m_consumers.insert(std::pair<int, int>(consumer_id, 1));\r
+ return;\r
+ }\r
+\r
+ (*it).second = ++it->second ;\r
+}\r
+\r
+void CAudioCodec::decreaseRef(int device_id, int consumer_id)\r
+{\r
+ if (m_ref_count_max == 0)\r
+ return;\r
+\r
+ if (m_ref_count <= 0) {\r
+ SERVER_ERR("(%s) can't decrease ref count (%d, %d) by %d", m_name.c_str(), m_ref_count, m_ref_count_max, consumer_id);\r
+ return;\r
+ }\r
+\r
+ auto it = m_consumers.find(consumer_id);\r
+\r
+ if (it == m_consumers.end()) {\r
+ SERVER_ERR("not registered consumer(%d)", consumer_id);\r
+ return;\r
+ }\r
+\r
+ m_resources.erase(device_id);\r
+\r
+ m_ref_count--;\r
+\r
+ if (it->second <= 1) {\r
+ m_consumers.erase(consumer_id);\r
+ return;\r
+ }\r
+\r
+ (*it).second = --it->second;\r
+}\r
+\r
+void CAudioCodec::increaseMaxRef(void)\r
+{\r
+ m_ref_count_max++;\r
+}\r
+\r
+bool CAudioCodec::isAvailableToUse(void)\r
+{\r
+ if (isUnknownCodec())\r
+ return true;\r
+\r
+ SERVER_INFO("%s > cur(%d), max(%d)", m_name.c_str(), m_ref_count, m_ref_count_max);\r
+\r
+ return (m_ref_count < m_ref_count_max);\r
+}\r
+\r
+std::set<int> CAudioCodec::getResourcesOfConsumer(int consumer_id)\r
+{\r
+ std::set<int> resources;\r
+\r
+ for (auto const &it : m_resources) {\r
+ if (it.second == consumer_id)\r
+ resources.insert(it.first);\r
+ }\r
+\r
+ return resources;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <stdlib.h>\r
+\r
+#include <CAudioCodec.h>\r
+#include <CAudioCodecCollection.h>\r
+\r
+CAudioCodecCollection *CAudioCodecCollection::m_instance = NULL;\r
+\r
+CAudioCodecCollection::CAudioCodecCollection()\r
+{\r
+\r
+}\r
+\r
+CAudioCodecCollection *CAudioCodecCollection::getInstance(void)\r
+{\r
+ if (!m_instance)\r
+ m_instance = new CAudioCodecCollection();\r
+\r
+ return m_instance;\r
+}\r
+\r
+CAudioCodecCollection::~CAudioCodecCollection()\r
+{\r
+}\r
+\r
+CAudioCodec *CAudioCodecCollection::findAudioCodec(std::string name)\r
+{\r
+ auto it = m_audio_codecs.find(name);\r
+\r
+ return (it == m_audio_codecs.end()) ? NULL : it->second;\r
+}\r
+\r
+void CAudioCodecCollection::registerAudioCodec(const char *name, int count)\r
+{\r
+ if (!name)\r
+ return;\r
+\r
+ CAudioCodec *audio_codec = findAudioCodec(name);\r
+\r
+ if (!audio_codec) {\r
+ audio_codec = new CAudioCodec(name);\r
+ m_audio_codecs.insert(std::pair<std::string, CAudioCodec*>(std::string(name), audio_codec));\r
+ }\r
+\r
+ if (count > 0)\r
+ audio_codec->increaseMaxRef();\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <rms_debug.h>\r
+#include <rms_type.h>\r
+#include <CResourceDB.h>\r
+#include <CResource.h>\r
+#include <CVirtualResource.h>\r
+#include <CBandwidth.h>\r
+\r
+CBandwidth *CBandwidth::m_instance = NULL;\r
+\r
+CBandwidth *CBandwidth::GetInstance(void)\r
+{\r
+ if (!m_instance)\r
+ {\r
+ m_instance = new CBandwidth();\r
+ }\r
+\r
+ return m_instance;\r
+}\r
+\r
+void CBandwidth::AddConsumerNDec(int device_id, int consumer_id, int category_id)\r
+{\r
+ auto it = m_ndec_consumers.find(category_id);\r
+ if (it == m_ndec_consumers.end())\r
+ {\r
+ std::map<int, int> consumers;\r
+ consumers.insert(std::pair<int, int>(device_id, consumer_id));\r
+ m_ndec_consumers.insert(std::pair<int, std::map<int, int>>(category_id, consumers));\r
+ }\r
+ else\r
+ {\r
+ std::map<int, int> *consumers = &it->second;\r
+ consumers->insert(std::pair<int, int>(device_id, consumer_id));\r
+ }\r
+}\r
+\r
+void CBandwidth::RemoveConsumerNDec(int device_id, int category_id)\r
+{\r
+ auto it = m_ndec_consumers.find(category_id);\r
+ if (it == m_ndec_consumers.end())\r
+ return;\r
+\r
+ it->second.erase(device_id);\r
+}\r
+\r
+void CBandwidth::GetConsumersNDec(int category_id, std::map<int, int> *consumers)\r
+{\r
+ auto it = m_ndec_consumers.find(category_id);\r
+ if (it == m_ndec_consumers.end())\r
+ return;\r
+\r
+ consumers->insert(it->second.begin(), it->second.end());\r
+}\r
+\r
+void CBandwidth::AddConsumer(int device_id, int consumer_id, int category_id, int category_class)\r
+{\r
+ m_consumers.insert(std::pair<int, int>(device_id, consumer_id));\r
+\r
+ if (category_class == RMS_CATEGORY_CLASS_N_DECODING)\r
+ AddConsumerNDec(device_id, consumer_id, category_id);\r
+}\r
+\r
+void CBandwidth::RemoveConsumer(int device_id, int category_id, int category_class)\r
+{\r
+ auto it = m_consumers.find(device_id);\r
+ if (it == m_consumers.end())\r
+ return;\r
+\r
+ m_consumers.erase(device_id);\r
+\r
+ if (category_class == RMS_CATEGORY_CLASS_N_DECODING)\r
+ RemoveConsumerNDec(device_id, category_id);\r
+}\r
+\r
+int CBandwidth::GetNConsumersNDec(int category_id)\r
+{\r
+ auto it = m_ndec_consumers.find(category_id);\r
+ if (it == m_ndec_consumers.end())\r
+ return 0;\r
+\r
+ return it->second.size();\r
+}\r
+\r
+void CBandwidth::Increase(unsigned int bw, int category_id, int category_class, int device_id)\r
+{\r
+ if ((category_class == RMS_CATEGORY_CLASS_N_DECODING) && IncludeSameDeviceGroup(category_id, device_id))\r
+ return;\r
+\r
+ m_avail += bw;\r
+ m_avail = (m_avail > m_max) ? m_max : m_avail;\r
+}\r
+\r
+void CBandwidth::Decrease(unsigned int bw, int category_id, int category_class, int device_id)\r
+{\r
+ if (category_class == RMS_CATEGORY_CLASS_N_DECODING && IncludeSameDeviceGroup(category_id, device_id))\r
+ return;\r
+\r
+ m_avail -= bw;\r
+}\r
+\r
+bool CBandwidth::IncludeSameDeviceGroup(int category_id, int device_id)\r
+{\r
+ if (GetNConsumersNDec(category_id) == 0)\r
+ return false;\r
+\r
+ CResource *c_rsc;\r
+ CVirtualResource *c_vrsc;\r
+ std::set<unsigned int> c_mc;\r
+\r
+ CResourceDB *db = CResourceDB::getInstance();\r
+ CResource *u_rsc = db->FindResource(device_id);\r
+ CVirtualResource *u_vrsc = db->FindVirtualResource(u_rsc->GetVirtualResourceID());\r
+\r
+ std::set<unsigned int> u_mc = u_vrsc->GetMemClusters();\r
+\r
+ std::map<int, int> consumers; // device_id, consumer_id\r
+ GetConsumersNDec(category_id, &consumers);\r
+\r
+ for (auto const &it : consumers)\r
+ {\r
+ c_rsc = db->FindResource(it.first);\r
+ c_vrsc = db->FindVirtualResource(c_rsc->GetVirtualResourceID());\r
+ c_mc = c_vrsc->GetMemClusters();\r
+\r
+ if (c_rsc->GetDeviceID() == u_rsc->GetDeviceID())\r
+ continue;\r
+\r
+ if (IsSameMemClusters(c_mc, u_mc))\r
+ {\r
+ SERVER_INFO("same mc (%d = %d) found", device_id, it.first);\r
+ return true;\r
+ }\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+bool CBandwidth::IsSameMemClusters(std::set<unsigned int> c_mc, std::set<unsigned int> u_mc)\r
+{\r
+ if (c_mc.size() != u_mc.size())\r
+ return false;\r
+\r
+ for (auto const &it : u_mc)\r
+ {\r
+ if (c_mc.find(it) == c_mc.end())\r
+ return false;\r
+ }\r
+ return true;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <stdio.h>\r
+\r
+#include <rms_debug.h>\r
+#include <rms_type.h>\r
+#include <CResourceDB.h>\r
+#include <CMemCluster.h>\r
+#include <CMixingMode.h>\r
+#include <CAudioCodec.h>\r
+#include <CAudioCodecCollection.h>\r
+#include <CPriority.h>\r
+#include <CResourceCategory.h>\r
+#include <CResourceObserver.h>\r
+#include <CDependencyController.h>\r
+#include <CConsumer.h>\r
+#include <CConsumerContainer.h>\r
+\r
+#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))\r
+\r
+static rms_mixing_mode_e supported_mixing_modes[] =\r
+{\r
+ RMS_MIXING_MODE_DEFAULT,\r
+ RMS_MIXING_MODE_MULTIVIEW,\r
+ RMS_MIXING_MODE_INTERACTION_SOUND\r
+};\r
+\r
+CDependencyController *CDependencyController::m_instance = NULL;\r
+\r
+CDependencyController::CDependencyController()\r
+{\r
+ registerMixingModes();\r
+ m_cur_mixing_mode = NULL;\r
+}\r
+\r
+CDependencyController *CDependencyController::getInstance(void)\r
+{\r
+ if (!m_instance)\r
+ m_instance = new CDependencyController();\r
+\r
+ return m_instance;\r
+}\r
+\r
+CDependencyController::~CDependencyController()\r
+{\r
+}\r
+\r
+void CDependencyController::registerMixingModes(void)\r
+{\r
+ for (unsigned int i = 0; i < ARRAY_SIZE(supported_mixing_modes); i++) {\r
+ CMixingMode *mixing_mode = new CMixingMode(supported_mixing_modes[i]);\r
+ m_mixing_modes.insert(std::pair<rms_mixing_mode_e, CMixingMode*>(supported_mixing_modes[i], mixing_mode));\r
+ }\r
+}\r
+\r
+bool CDependencyController::IsRegisteredMemCluster(unsigned int id)\r
+{\r
+ auto it = m_mem_clusters.find(id);\r
+ return (it != m_mem_clusters.end());\r
+}\r
+\r
+CMemCluster *CDependencyController::findMemCluster(unsigned int id)\r
+{\r
+ auto it = m_mem_clusters.find(id);\r
+\r
+ if (it == m_mem_clusters.end())\r
+ {\r
+ SERVER_ERR("not existing mem cluster(%d)", id);\r
+ return NULL;\r
+ }\r
+\r
+ return it->second;\r
+}\r
+\r
+void CDependencyController::RegisterMemCluster(unsigned int id)\r
+{\r
+ if (IsRegisteredMemCluster(id))\r
+ return;\r
+\r
+ CMemCluster *mc = new CMemCluster(id);\r
+ SERVER_INFO("register mem cluster (%d)", id);\r
+ m_mem_clusters.insert(std::pair<unsigned int, CMemCluster*>(id, mc));\r
+}\r
+\r
+bool CDependencyController::isAvailableMemClusters(std::set<unsigned int> mc_ids)\r
+{\r
+ CMemCluster *mc = NULL;\r
+\r
+ for (auto it : mc_ids) {\r
+ mc = findMemCluster(it);\r
+ if (!mc) {\r
+ SERVER_INFO("mem cluster NULL");\r
+ return false;\r
+ }\r
+\r
+ if (mc->IsUsed()) {\r
+ SERVER_INFO("mem cluster (%d) is being used", mc->GetId());\r
+ return false;\r
+ }\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+bool CDependencyController::isAvailableMemClusters(std::set<unsigned int> mc_ids, std::string app_id)\r
+{\r
+ CMemCluster *mc = NULL;\r
+\r
+ for (auto it : mc_ids) {\r
+ mc = findMemCluster(it);\r
+ if (!mc) {\r
+ SERVER_INFO("mem cluster NULL");\r
+ return false;\r
+ }\r
+\r
+ if (mc->IsUsed() && !mc->IsUsedBy(app_id)) {\r
+ SERVER_INFO("mem cluster (%d) is being used", mc->GetId());\r
+ return false;\r
+ }\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+bool CDependencyController::isAvailableMemClusters(std::set<unsigned int> mc_ids, int category_class, int category_id)\r
+{\r
+ CMemCluster *mc = NULL;\r
+\r
+ for (auto it : mc_ids) {\r
+ mc = findMemCluster(it);\r
+ if (!mc) {\r
+ SERVER_INFO("mem cluster NULL");\r
+ return false;\r
+ }\r
+\r
+ if (!mc->IsUsed())\r
+ continue;\r
+\r
+ if (mc->GetCategoryClass() != category_class) {\r
+ SERVER_INFO("mem cluster (%d) is in use, mc_class(%d)/category(%d)", mc->GetId(), mc->GetCategoryClass(), category_class);\r
+ return false;\r
+ }\r
+\r
+ if (mc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING && (mc->GetCategoryId() != category_id)) {\r
+ SERVER_INFO("mem cluster (%d) is in use, mc_category(%d)/category(%d)", mc->GetId(), mc->GetCategoryId(), category_id);\r
+ return false;\r
+ }\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+bool CDependencyController::isSharableMemClusters(std::set<unsigned int> mc_ids, int device_id)\r
+{\r
+ CMemCluster *mc = NULL;\r
+\r
+ for (auto it : mc_ids) {\r
+ mc = findMemCluster(it);\r
+ if (!mc) {\r
+ SERVER_INFO("mem cluster NULL");\r
+ return false;\r
+ }\r
+\r
+ if (!mc->IsSharable(device_id)) {\r
+ SERVER_INFO("mem cluster (%d) is not sharable", mc->GetId());\r
+ return false;\r
+ }\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+\r
+bool CDependencyController::canReclaimMemClusters(std::set<unsigned int> mc_ids, int consumer_id)\r
+{\r
+ CMemCluster *mc = NULL;\r
+\r
+ for (auto const &it : mc_ids) {\r
+ mc = findMemCluster(it);\r
+ if (!mc) {\r
+ SERVER_INFO("mem cluster NULL");\r
+ return false;\r
+ }\r
+\r
+ std::set<int> consumers = mc->GetConsumers();\r
+\r
+ for (auto const &it_consumer : consumers) {\r
+ if (!CPriority::isReclaimableConsumer(it_consumer, consumer_id, NULL)) {\r
+ SERVER_ERR("can't reclaim mc(%d) from (%d)", mc->GetId(), it_consumer);\r
+ return false;\r
+ }\r
+ }\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+bool CDependencyController::canReclaimMemClusters(std::set<unsigned int> mc_ids, int consumer_id, std::string app_id)\r
+{\r
+ CMemCluster *mc = NULL;\r
+ CConsumerContainer *c_container = CConsumerContainer::getInstance();\r
+ CConsumer *consumer = NULL;\r
+\r
+ for (auto const &it : mc_ids) {\r
+ mc = findMemCluster(it);\r
+ if (!mc) {\r
+ SERVER_INFO("mem cluster NULL");\r
+ return false;\r
+ }\r
+\r
+ std::set<int> consumers = mc->GetConsumers();\r
+\r
+ for (auto const &it_consumer : consumers) {\r
+ consumer = c_container->findConsumer(it_consumer);\r
+ if (consumer) {\r
+ if (!consumer->GetAppID().compare(app_id)) {\r
+ SERVER_INFO("skip to check priority against same app (%s:%s)", consumer->GetAppID().c_str(), app_id.c_str());\r
+ continue;\r
+ }\r
+ }\r
+\r
+ if (!CPriority::isReclaimableConsumer(it_consumer, consumer_id, NULL)) {\r
+ SERVER_ERR("can't reclaim mc(%d) from (%d)", mc->GetId(), it_consumer);\r
+ return false;\r
+ }\r
+ }\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+int CDependencyController::getReclaimableMemClusterConsumers(std::set<unsigned int> mc_ids, int consumer_id, std::multimap<int, int>* reclaimables)\r
+{\r
+ CMemCluster *mc = NULL;\r
+\r
+ for (auto const &it : mc_ids) {\r
+ mc = findMemCluster(it);\r
+ if (!mc) {\r
+ SERVER_INFO("mem cluster NULL");\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ std::set<int> consumers = mc->GetConsumers();\r
+\r
+ for (auto const &it_consumer : consumers) {\r
+ if (!CPriority::isReclaimableConsumer(it_consumer, consumer_id, NULL)) {\r
+ SERVER_ERR("can't reclaim mc(%d) from (%d)", mc->GetId(), it_consumer);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ std::set<int> device_ids = mc->GetAssignedDeviceId(it_consumer);\r
+ for (auto const &it_dev_id : device_ids) {\r
+ SERVER_INFO("[mc:%d] add (%d:%d)", mc->GetId(), it_dev_id, it_consumer);\r
+ reclaimables->insert(std::pair<int, int>(it_dev_id, it_consumer));\r
+ }\r
+ }\r
+ }\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+int CDependencyController::getReclaimableMemClusterConsumers(std::set<unsigned int> mc_ids, int consumer_id, std::multimap<int, int>* reclaimables, std::string app_id)\r
+{\r
+ CMemCluster *mc = NULL;\r
+ CConsumerContainer *c_container = CConsumerContainer::getInstance();\r
+ CConsumer *consumer = NULL;\r
+\r
+ for (auto const &it : mc_ids) {\r
+ mc = findMemCluster(it);\r
+ if (!mc) {\r
+ SERVER_INFO("mem cluster NULL");\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ std::set<int> consumers = mc->GetConsumers();\r
+\r
+ for (auto const &it_consumer : consumers) {\r
+ consumer = c_container->findConsumer(it_consumer);\r
+ if (!consumer->GetAppID().compare(app_id)) {\r
+ SERVER_INFO("skip to check priority against same app (%s:%s)", consumer->GetAppID().c_str(), app_id.c_str());\r
+ continue;\r
+ }\r
+\r
+ if (!CPriority::isReclaimableConsumer(it_consumer, consumer_id, NULL)) {\r
+ SERVER_ERR("can't reclaim mc(%d) from (%d)", mc->GetId(), it_consumer);\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ std::set<int> device_ids = mc->GetAssignedDeviceId(it_consumer);\r
+ for (auto const &it_dev_id : device_ids) {\r
+ SERVER_INFO("[mc:%d] add (%d:%d)", mc->GetId(), it_dev_id, it_consumer);\r
+ reclaimables->insert(std::pair<int, int>(it_dev_id, it_consumer));\r
+ }\r
+ }\r
+ }\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+void CDependencyController::SwapConsumers(int device_id_a, std::set<int> consumers_a, int device_id_b, std::set<int> consumers_b)\r
+{\r
+ ClearMemClusterConsumer(device_id_a);\r
+ ClearMemClusterConsumer(device_id_b);\r
+\r
+ for (auto const &it : consumers_a)\r
+ addMemClusterConsumer(device_id_b, it);\r
+\r
+ for (auto const &it : consumers_b)\r
+ addMemClusterConsumer(device_id_a, it);\r
+}\r
+\r
+void CDependencyController::addMemClusterConsumer(int device_id, int consumer_id)\r
+{\r
+ CMemCluster *mc = NULL;\r
+ CResource *rsc = CResourceDB::getInstance()->FindResource(device_id);\r
+\r
+ if (!rsc)\r
+ return;\r
+\r
+ if (rsc->GetCurCategory() == RMS_CATEGORY_VIDEO_ENCODER_EXCLUSIVE)\r
+ return;\r
+\r
+ int category_class = rsc->GetCategoryClass();\r
+\r
+ std::set<unsigned int> mc_mc_ids = rsc->GetMemClusters();\r
+ for (auto const &it : mc_mc_ids) {\r
+ mc = findMemCluster(it);\r
+ if (!mc)\r
+ continue;\r
+\r
+ mc->AddConsumer(consumer_id, device_id, category_class, rsc->GetCurCategory());\r
+ SERVER_INFO("add consumer(%d) to mem_cluster(%d)/class(%d)", consumer_id, mc->GetId(), category_class);\r
+ }\r
+}\r
+\r
+void CDependencyController::removeMemClusterConsumer(int device_id, int consumer_id)\r
+{\r
+ CMemCluster *mc = NULL;\r
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
+\r
+ if (!resource)\r
+ return;\r
+\r
+ std::set<unsigned int> mc_mc_ids = resource->GetMemClusters();\r
+\r
+ for (auto const &it : mc_mc_ids) {\r
+ mc = findMemCluster(it);\r
+ if (!mc)\r
+ continue;\r
+\r
+ mc->RemoveConsumer(consumer_id, device_id);\r
+ SERVER_INFO("remove consumer(%d) from mem_cluster(%d)", consumer_id, mc->GetId());\r
+ }\r
+}\r
+\r
+void CDependencyController::ClearMemClusterConsumer(int device_id)\r
+{\r
+ CMemCluster *mc = NULL;\r
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
+ if (!resource)\r
+ return;\r
+\r
+ std::set<unsigned int> mc_mc_ids = resource->GetMemClusters();\r
+\r
+ for (auto const &it : mc_mc_ids) {\r
+ mc = findMemCluster(it);\r
+ if (!mc)\r
+ continue;\r
+\r
+ mc->ClearConsumers();\r
+ SERVER_INFO("clear consumers from mem_cluster(%d)", mc->GetId());\r
+ }\r
+}\r
+\r
+void CDependencyController::Update(resource_update_type_e type, const int device_id, const int consumer_id)\r
+{\r
+ switch (type) {\r
+ case UPDATED_BY_ALLOC:\r
+ addMemClusterConsumer(device_id, consumer_id);\r
+ addAudioCodecConsumer(device_id, consumer_id);\r
+ setCurMixingMode(device_id, consumer_id);\r
+ break;\r
+ case UPDATED_BY_RELEASE:\r
+ removeMemClusterConsumer(device_id, consumer_id);\r
+ removeAudioCodecConsumer(device_id, consumer_id);\r
+ resetCurMixingMode(device_id, consumer_id);\r
+ break;\r
+ default:\r
+ SERVER_ERR("unexpected update type (%d)", type);\r
+ break;\r
+ }\r
+}\r
+\r
+void CDependencyController::addAudioCodecConsumer(int device_id, int consumer_id)\r
+{\r
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
+\r
+ if (!resource->IsAudioDevice())\r
+ return;\r
+\r
+ m_acodec_consumers.insert(std::pair<int, int> (device_id, consumer_id));\r
+\r
+ std::string codec_name = resource->GetAudioCodec();\r
+ CAudioCodec *codec = CAudioCodecCollection::getInstance()->findAudioCodec(codec_name);\r
+\r
+ codec->increaseRef(device_id, consumer_id);\r
+}\r
+\r
+void CDependencyController::removeAudioCodecConsumer(int device_id, int consumer_id)\r
+{\r
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
+\r
+ if (!resource->IsAudioDevice())\r
+ return;\r
+\r
+ m_acodec_consumers.erase(device_id);\r
+\r
+ std::string codec_name = resource->GetAudioCodec();\r
+ CAudioCodec *codec = CAudioCodecCollection::getInstance()->findAudioCodec(codec_name);\r
+\r
+ codec->decreaseRef(device_id, consumer_id);\r
+}\r
+\r
+CMixingMode *CDependencyController::findMixingMode(rms_mixing_mode_e mode)\r
+{\r
+ auto it = m_mixing_modes.find(mode);\r
+\r
+ return (it == m_mixing_modes.end()) ? NULL : it->second;\r
+}\r
+\r
+void CDependencyController::setCurMixingMode(int device_id, int consumer_id)\r
+{\r
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
+\r
+ if (!resource->IsAudioDevice())\r
+ return;\r
+\r
+ rms_mixing_mode_e mode_id = resource->GetMixingMode();\r
+ CMixingMode *mode = findMixingMode(mode_id);\r
+\r
+ if (!mode) {\r
+ SERVER_ERR("undefined mixing mode (%d)", mode_id);\r
+ return;\r
+ }\r
+\r
+ mode->AddConsumer(device_id, consumer_id);\r
+\r
+ m_cur_mixing_mode = mode;\r
+}\r
+\r
+void CDependencyController::resetCurMixingMode(int device_id, int consumer_id)\r
+{\r
+ CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
+\r
+ if (!resource->IsAudioDevice())\r
+ return;\r
+\r
+ rms_mixing_mode_e mode_id = resource->GetMixingMode();\r
+ CMixingMode *mode = findMixingMode(mode_id);\r
+\r
+ if (!mode) {\r
+ SERVER_ERR("undefined mixing mode (%d)", mode_id);\r
+ return;\r
+ }\r
+\r
+ if (mode->RemoveConsumer(device_id, consumer_id) > 0)\r
+ return;\r
+\r
+ m_cur_mixing_mode = NULL;\r
+}\r
+\r
+bool CDependencyController::isAvailableAudioCodec(std::string name)\r
+{\r
+ SERVER_DBG("cur(%zu)/max(%d)", m_acodec_consumers.size(), m_acodec_ref_count_max);\r
+ return (m_acodec_consumers.size() >= m_acodec_ref_count_max); //???\r
+}\r
+\r
+std::map<unsigned long, std::pair<int, int>> CDependencyController::getAudioCodecConsumers(void)\r
+{\r
+ std::map<unsigned long, std::pair<int, int>> consumers;\r
+\r
+ for (auto const &it : m_acodec_consumers) {\r
+ CResource *rsc = CResourceDB::getInstance()->FindResource(it.first);\r
+ consumers.insert(std::pair<unsigned long, std::pair<int, int>>(rsc->GetAllocatedTime(), std::make_pair(it.first, it.second)));\r
+ }\r
+\r
+ return consumers;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <rms_type.h>\r
+#include <rms_debug.h>\r
+#include "CMemCluster.h"\r
+#include "CConsumerContainer.h"\r
+#include "CConsumer.h"\r
+\r
+CMemCluster::CMemCluster(unsigned int id)\r
+{\r
+ m_id = id;\r
+ m_category_class = 0;\r
+ m_category_id = 0;\r
+}\r
+\r
+CMemCluster::~CMemCluster()\r
+{\r
+}\r
+\r
+bool CMemCluster::IsUsed(void)\r
+{\r
+ return (m_consumers.size() > 0);\r
+}\r
+\r
+bool CMemCluster::IsUsedBy(std::string app_id)\r
+{\r
+ CConsumerContainer *cc = CConsumerContainer::getInstance();\r
+ CConsumer *c = NULL;\r
+ bool result = false;\r
+\r
+ if (m_consumers.size() == 0)\r
+ return false;\r
+\r
+ for (auto it : m_consumers) {\r
+ c = cc->findConsumer(it.first);\r
+ if (!c)\r
+ continue;\r
+ if (!c->GetAppID().compare(app_id)) {\r
+ SERVER_INFO("mc(%d) is used by (%s)", m_id, app_id.c_str());\r
+ return true;\r
+ }\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+bool CMemCluster::IsSharable(int device_id)\r
+{\r
+ if (m_consumers.size() == 0)\r
+ return true;\r
+\r
+ for (auto it : m_consumers) {\r
+ auto it_dev_id = it.second.find(device_id);\r
+ if (it_dev_id != it.second.end())\r
+ return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+void CMemCluster::AddConsumer(int consumer_id, int device_id, int category_class, int category_id)\r
+{\r
+ auto it = m_consumers.find(consumer_id);\r
+ if (it == m_consumers.end()) {\r
+ std::set<int> device_ids;\r
+ device_ids.insert(device_id);\r
+ m_consumers.insert(std::pair<int, std::set<int>>(consumer_id, device_ids));\r
+ m_category_class = category_class;\r
+ m_category_id = category_id;\r
+ } else {\r
+ std::set<int> &pdevice_ids = it->second;\r
+ pdevice_ids.insert(device_id);\r
+ }\r
+}\r
+\r
+void CMemCluster::RemoveConsumer(int consumer_id, int device_id)\r
+{\r
+ auto it = m_consumers.find(consumer_id);\r
+ if (it == m_consumers.end())\r
+ return;\r
+\r
+ std::set<int> &device_ids = it->second;\r
+\r
+ auto id_it = device_ids.find(device_id);\r
+ if (id_it == device_ids.end())\r
+ return;\r
+\r
+ device_ids.erase(device_id);\r
+ if (device_ids.empty())\r
+ m_consumers.erase(consumer_id);\r
+\r
+ if (m_consumers.empty()) {\r
+ m_category_class = 0;\r
+ m_category_id = 0;\r
+ }\r
+}\r
+\r
+std::set<int> CMemCluster::GetConsumers(void)\r
+{\r
+ std::set<int> consumers;\r
+\r
+ for (auto it : m_consumers)\r
+ consumers.insert(it.first);\r
+\r
+ return consumers;\r
+}\r
+\r
+void CMemCluster::ClearConsumers(void)\r
+{\r
+ for (auto &it : m_consumers) {\r
+ std::set<int> &id_it = it.second;\r
+ id_it.clear();\r
+ }\r
+ m_consumers.clear();\r
+}\r
+\r
+std::set<int> CMemCluster::GetAssignedDeviceId(int consumer_id)\r
+{\r
+ std::set<int> device_ids;\r
+ auto it = m_consumers.find(consumer_id);\r
+\r
+ if (it == m_consumers.end())\r
+ return device_ids;\r
+\r
+ device_ids.insert(it->second.begin(), it->second.end());\r
+\r
+ return device_ids;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <rms_debug.h>\r
+#include <CMixingMode.h>\r
+\r
+int CMixingMode::AddConsumer(int device_id, int consumer_id)\r
+{\r
+ auto it = m_consumers.find(device_id);\r
+\r
+ if (it != m_consumers.end()) {\r
+ SERVER_ERR("already registered device(%d) by (%d)", device_id, it->second);\r
+ return m_consumers.size();\r
+ }\r
+\r
+ SERVER_INFO("add consumer(%d:%d) to mode(%d)", consumer_id, device_id, m_mode);\r
+ m_consumers.insert(std::pair<int, int>(device_id, consumer_id));\r
+\r
+ return m_consumers.size();\r
+}\r
+\r
+int CMixingMode::RemoveConsumer(int device_id, int consumer_id)\r
+{\r
+ auto it = m_consumers.find(device_id);\r
+\r
+ if (it == m_consumers.end())\r
+ return m_consumers.size();\r
+\r
+ SERVER_INFO("remove consumer(%d:%d) from mode(%d)", consumer_id, device_id, m_mode);\r
+\r
+ m_consumers.erase(device_id);\r
+\r
+ return m_consumers.size();\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <stdlib.h>\r
+\r
+#include <CAllocateModeStrategy.h>\r
+#include <CNormalModeStrategy.h>\r
+#include <CInvalidModeStrategy.h>\r
+#include <CPreferenceModeStrategy.h>\r
+#include <CAllocateModeStrategyProvider.h>\r
+\r
+enum {\r
+ INIT_MODE = -1,\r
+ NORMAL_MODE,\r
+ PREFERENCE_MODE,\r
+ INVALID_MODE\r
+};\r
+\r
+CAllocateModeStrategyProvider *CAllocateModeStrategyProvider::m_instance = NULL;\r
+\r
+CAllocateModeStrategyProvider::CAllocateModeStrategyProvider()\r
+{\r
+}\r
+\r
+CAllocateModeStrategyProvider::~CAllocateModeStrategyProvider()\r
+{\r
+}\r
+\r
+\r
+CAllocateModeStrategyProvider *CAllocateModeStrategyProvider::getInstance()\r
+{\r
+ if (!m_instance)\r
+ m_instance = new CAllocateModeStrategyProvider();\r
+\r
+ return m_instance;\r
+}\r
+\r
+int CAllocateModeStrategyProvider::getAllocateMode(rms_msg_request *req)\r
+{\r
+ int mode = INIT_MODE;\r
+\r
+ for (int i = 0; i < req->request_num; i++) {\r
+ if (req->state[i] == RMS_STATE_EXCLUSIVE_PREFERENCE) {\r
+ if (mode == INIT_MODE) {\r
+ mode = PREFERENCE_MODE;\r
+ } else if (mode == NORMAL_MODE) {\r
+ mode = INVALID_MODE;\r
+ break;\r
+ }\r
+ } else {\r
+ if (mode == INIT_MODE) {\r
+ mode = NORMAL_MODE;\r
+ } else if (mode == PREFERENCE_MODE) {\r
+ mode = INVALID_MODE;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ return mode;\r
+}\r
+\r
+CAllocateModeStrategy *CAllocateModeStrategyProvider::GetStrategy(rms_msg_request *req)\r
+{\r
+ CAllocateModeStrategy *strategy = NULL;\r
+\r
+ switch (getAllocateMode(req)) {\r
+ case NORMAL_MODE:\r
+ strategy = new CNormalModeStrategy();\r
+ break;\r
+ case PREFERENCE_MODE:\r
+ strategy = new CPreferenceModeStrategy();\r
+ break;\r
+ default:\r
+ strategy = new CInvalidModeStrategy();\r
+ break;\r
+ }\r
+\r
+ return strategy;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <assert.h>\r
+#include <map>\r
+#include <algorithm>\r
+\r
+#include <rms_type.h>\r
+#include <rms_debug.h>\r
+#include <CResource.h>\r
+#include <CVirtualResource.h>\r
+#include <CResourceDB.h>\r
+#include <CRequest.h>\r
+#include <CRequester.h>\r
+#include <CPriority.h>\r
+#include <CAllocateStrategy.h>\r
+\r
+void CAllocateStrategy::ExcludeResources(std::map<int, CVirtualResource*> vresources, std::map<int, CVirtualResource*>* filtered_resources, CRequest *req)\r
+{\r
+ for (auto const &it : vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (req->IsMainDeviceRequest() && !vresource->IsMainDevice())\r
+ continue;\r
+ if (req->IsSubDeviceRequest() && vresource->IsMainDevice())\r
+ continue;\r
+ if (req->IsAIDeviceRequest() && !vresource->IsAIDevice())\r
+ continue;\r
+ if (req->IsRequestByDevice() && resource->GetDeviceID() != req->GetDevice())\r
+ continue;\r
+ if (req->GetState() == RMS_STATE_SHARABLE && !resource->IsSharableDevice())\r
+ continue;\r
+ if (req->GetState() != RMS_STATE_SHARABLE && resource->IsSharableDevice())\r
+ continue;\r
+\r
+ filtered_resources->insert(std::pair<int, CVirtualResource*>(it.first, it.second));\r
+ }\r
+}\r
+\r
+void CAllocateStrategy::ExcludeResources(std::multimap<unsigned long, CVirtualResource*> vresources, std::multimap<unsigned long, CVirtualResource*>* filtered_resources, CRequest *req)\r
+{\r
+ for (auto const &it : vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+\r
+ if (req->IsMainDeviceRequest() && !vresource->IsMainDevice())\r
+ continue;\r
+ if (req->IsSubDeviceRequest() && vresource->IsMainDevice())\r
+ continue;\r
+ if (req->IsAIDeviceRequest() && !vresource->IsAIDevice())\r
+ continue;\r
+\r
+ filtered_resources->insert(std::pair<unsigned long, CVirtualResource*>(it.first, it.second));\r
+ }\r
+}\r
+\r
+void CAllocateStrategy::updateReasonByResourceState(int device_id, CRequest *req)\r
+{\r
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+ return;\r
+ }\r
+\r
+ if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)\r
+ return;\r
+\r
+ bool low_priority_consumer_using = (CPriority::compareCurConsumers(device_id, req->getRequester()->getHandle()) == HIGH_PRIORITY);\r
+\r
+ if (low_priority_consumer_using) {\r
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
+ SERVER_INFO("RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER");\r
+ } else {\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+ SERVER_INFO("RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS");\r
+ }\r
+}\r
+\r
+void CAllocateStrategy::updateReasonBySharableCount(int device_id, CRequest *req)\r
+{\r
+ if (req->GetState() != RMS_STATE_SHARABLE)\r
+ return;\r
+\r
+ if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)\r
+ return;\r
+\r
+ bool low_priority_consumer_using = (CPriority::compareCurConsumers(device_id, req->getRequester()->getHandle()) == HIGH_PRIORITY);\r
+\r
+ if (low_priority_consumer_using)\r
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
+ else\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+}\r
+\r
+int CAllocateStrategy::GetReclaimedBW(std::multimap<int, int> *retirables)\r
+{\r
+ CResourceDB *db = CResourceDB::getInstance();\r
+ std::set<int> rsc_ids;\r
+ int bw = 0;\r
+\r
+ ExcludeDuplicatedNDecoders(retirables, &rsc_ids);\r
+\r
+ for (auto const &it : rsc_ids) {\r
+ CResource *rsc = db->FindResource(it);\r
+ if (!rsc)\r
+ continue;\r
+ bw += rsc->GetBW();\r
+ }\r
+\r
+ //SERVER_INFO("reclaimed bw(%d) from (%d)", bw, retirables->size());\r
+ return bw;\r
+}\r
+\r
+void CAllocateStrategy::ExcludeDuplicatedNDecoders(std::multimap<int, int> *retirables, std::set<int> *excluded)\r
+{\r
+ assert(retirables);\r
+ assert(excluded);\r
+ std::map<int, int> rscs_by_category; //category id, device_id\r
+ CResourceDB *db = CResourceDB::getInstance();\r
+\r
+ for (auto &it : *retirables) {\r
+ CResource *rsc = db->FindResource(it.first);\r
+ if (!rsc)\r
+ continue;\r
+ if (rsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) {\r
+ //SERVER_INFO("insert (%d:%d)", rsc->GetCurCategory(), it.first);\r
+ rscs_by_category.insert(std::pair<int, int>(rsc->GetCurCategory(), it.first));\r
+ } else {\r
+ //SERVER_INFO("insert (%d)", it.first);\r
+ excluded->insert(it.first);\r
+ }\r
+ }\r
+\r
+ for (auto &itn : rscs_by_category) {\r
+ //SERVER_INFO("insert (%d)", itn.second);\r
+ excluded->insert(itn.second);\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <rms_debug.h>\r
+#include <CAllocateStrategy.h>\r
+#include <CNormalStrategy.h>\r
+#include <CAudioDecoderStrategy.h>\r
+#include <CNDecodingVideoDecoderStrategy.h>\r
+#include <CVideoDecoderStrategy.h>\r
+#include <CScalerStrategy.h>\r
+#include <CExclusiveStrategy.h>\r
+#include <CAllocateStrategyProvider.h>\r
+#include <CVideoEncoderExclusiveStrategy.h>\r
+\r
+CAllocateStrategyProvider *CAllocateStrategyProvider::m_instance = NULL;\r
+\r
+CAllocateStrategyProvider::CAllocateStrategyProvider()\r
+{\r
+}\r
+\r
+bool CAllocateStrategyProvider::IsAudioDecoderCategory(rms_rsc_category_e category)\r
+{\r
+ bool result = false;\r
+\r
+ switch (category) {\r
+ case RMS_CATEGORY_AUDIO_DECODER:\r
+ case RMS_CATEGORY_AUDIO_DECODER_SUB:\r
+ case RMS_CATEGORY_AUDIO_DECODER_PRIMARY:\r
+ case RMS_CATEGORY_AUDIO_DECODER_ANY:\r
+ result = true;\r
+ break;\r
+ default:\r
+ result = false;\r
+ break;\r
+ }\r
+\r
+ if (category > RMS_CATEGORY_AUDIO_DECODER_OPTION && category < RMS_CATEGORY_AUDIO_DECODER_OPTION_MAX)\r
+ result = true;\r
+\r
+ return result;\r
+}\r
+\r
+bool CAllocateStrategyProvider::IsVideoDecoderCategory(rms_rsc_category_e category)\r
+{\r
+ bool result = false;\r
+\r
+ switch (category) {\r
+ case RMS_CATEGORY_VIDEO_DECODER:\r
+ case RMS_CATEGORY_VIDEO_DECODER_SUB:\r
+ case RMS_CATEGORY_JPEG_DECODER:\r
+ case RMS_CATEGORY_MJPEG_DECODER:\r
+ case RMS_CATEGORY_JPEG_DECODER_FHD:\r
+ case RMS_CATEGORY_JPEG_DECODER_UHD:\r
+ case RMS_CATEGORY_JPEG_DECODER_8K:\r
+ case RMS_CATEGORY_MJPEG_DECODER_FHD:\r
+ case RMS_CATEGORY_MJPEG_DECODER_UHD:\r
+ case RMS_CATEGORY_MJPEG_DECODER_8K:\r
+ case RMS_CATEGORY_HEIC_DECODER:\r
+ result = true;\r
+ break;\r
+ default:\r
+ result = false;\r
+ break;\r
+ }\r
+\r
+ if (category > RMS_CATEGORY_VIDEO_DECODER_OPTION && category < RMS_CATEGORY_VIDEO_DECODER_OPTION_MAX)\r
+ result = true;\r
+\r
+ return result;\r
+}\r
+\r
+bool CAllocateStrategyProvider::IsNDecordingVideoDecoderCategory(int category_class)\r
+{\r
+ return (category_class == RMS_CATEGORY_CLASS_N_DECODING);\r
+}\r
+\r
+bool CAllocateStrategyProvider::IsBGScalerCategory(rms_rsc_category_e category)\r
+{\r
+ return (category == RMS_CATEGORY_SCALER_BG);\r
+}\r
+\r
+bool CAllocateStrategyProvider::IsMultiviewScalerCategory(rms_rsc_category_e category)\r
+{\r
+ return (category == RMS_CATEGORY_SCALER_MULTIVIEW || category == RMS_CATEGORY_SCALER_INTERLACED);\r
+}\r
+\r
+bool CAllocateStrategyProvider::IsSubScalerCategory(rms_rsc_category_e category)\r
+{\r
+ bool result = false;\r
+\r
+ switch (category) {\r
+ case RMS_CATEGORY_SCALER_SUB:\r
+ case RMS_CATEGORY_SCALER_SUB2:\r
+ case RMS_CATEGORY_SCALER_SUB3:\r
+ result = true;\r
+ break;\r
+ default:\r
+ result = false;\r
+ break;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+CAllocateStrategyProvider *CAllocateStrategyProvider::getInstance()\r
+{\r
+ if (!m_instance)\r
+ m_instance = new CAllocateStrategyProvider();\r
+\r
+ return m_instance;\r
+}\r
+\r
+CAllocateStrategyProvider::~CAllocateStrategyProvider()\r
+{\r
+}\r
+\r
+CAllocateStrategy *CAllocateStrategyProvider::GetStrategy(rms_rsc_category_e category, int category_class)\r
+{\r
+ CAllocateStrategy *strategy = NULL;\r
+\r
+ if (IsVideoDecoderCategory(category)) {\r
+ if (IsNDecordingVideoDecoderCategory(category_class))\r
+ strategy = new CNDecodingVideoDecoderStrategy();\r
+ else\r
+ strategy = new CVideoDecoderStrategy();\r
+ } else if (IsAudioDecoderCategory(category)) {\r
+ strategy = new CAudioDecoderStrategy();\r
+ } else if (IsBGScalerCategory(category) || IsSubScalerCategory(category)) {\r
+ strategy = new CExclusiveStrategy();\r
+ } else if (IsMultiviewScalerCategory(category)) {\r
+ strategy = new CScalerStrategy();\r
+ } else if (category == RMS_CATEGORY_VIDEO_ENCODER_EXCLUSIVE) {\r
+ strategy = new CVideoEncoderExclusiveStrategy();\r
+ } else {\r
+ strategy = new CNormalStrategy();\r
+ }\r
+\r
+ return strategy;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <map>\r
+#include <rms_type.h>\r
+#include <rms_debug.h>\r
+#include <CResource.h>\r
+#include <CVirtualResource.h>\r
+#include <CRequest.h>\r
+#include <CRequester.h>\r
+#include <CPriority.h>\r
+#include <CAllocateStrategy.h>\r
+#include <CAudioDecoderStrategy.h>\r
+#include <CMixingStrategy.h>\r
+#include <CDependencyController.h>\r
+#include <CSysInfo.h>\r
+\r
+CVirtualResource *CAudioDecoderStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)\r
+{\r
+ std::map<int, CVirtualResource*> filtered_vresources;\r
+ ExcludeResources(vresources, &filtered_vresources, req);\r
+\r
+ req->SetResult(RMS_ERROR);\r
+ req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);\r
+\r
+ CRequester *requester = req->getRequester();\r
+ CMixingStrategy *strategy = CMixingStrategy::getInstance();\r
+ bool mixing_supported = CSysInfo::GetInstance()->IsAudioMixingSupported();\r
+\r
+ for (auto const &it : filtered_vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+ int device_id = resource->GetDeviceID();\r
+\r
+ SERVER_INFO("vresource id(%d), codec(%s)", vresource->GetVResourceID(), vresource->GetAudioCodec().c_str());\r
+\r
+ rms_error_type_e reason = RMS_ERR_TYPE_NONE;\r
+\r
+ if (mixing_supported) {\r
+ if (!strategy->isAvailableMixingMode(req->GetMixingMode())) {\r
+ strategy->updateReasonByMixingMode(vresource, req, reason);\r
+ continue;\r
+ }\r
+\r
+ if (!strategy->isAvailableAudioCodec(vresource->GetAudioCodec(), requester->getHandle(), &reason)) {\r
+ strategy->updateReasonByAudioCodec(vresource, req, reason);\r
+ continue;\r
+ }\r
+ }\r
+\r
+ if (resource->IsReserved())\r
+ continue;\r
+\r
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
+ updateReasonByResourceState(device_id, req);\r
+ continue;\r
+ }\r
+\r
+ return vresource;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+int CAudioDecoderStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)\r
+{\r
+ CResource *rsc = vrsc->GetResource();\r
+\r
+ if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)\r
+ return RMS_ERROR;\r
+\r
+ rsc->UpdateAudioCodec(vrsc->GetAudioCodec());\r
+ rsc->updateMixingMode(req->GetMixingMode());\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+int CAudioDecoderStrategy::GetRetirableConsumers(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)\r
+{\r
+ CResource *resource = vresource->GetResource();\r
+ CRequester *requester = req->getRequester();\r
+ int cid = requester->getHandle();\r
+ rms_error_type_e err;\r
+\r
+ SERVER_INFO("vresource id(%d), codec(%s)", vresource->GetVResourceID(), vresource->GetAudioCodec().c_str());\r
+\r
+ if (CSysInfo::GetInstance()->IsAudioMixingSupported()) {\r
+ CMixingStrategy *strategy = CMixingStrategy::getInstance();\r
+\r
+ if (!strategy->isAvailableAudioCodec(vresource->GetAudioCodec(), requester->getHandle(), &err)) {\r
+ if (strategy->getReclaimableAudioCodecConsumers(vresource->GetAudioCodec(), cid, req, retirables, err_type) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ if (!strategy->isAvailableMixingMode(req->GetMixingMode())) {\r
+ if (strategy->getReclaimableMixingModeConsumers(req->GetMixingMode(), cid, retirables, err_type) != RMS_OK)\r
+ goto error;\r
+ }\r
+ }\r
+\r
+ if (!resource->IsFreeState()) {\r
+ if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), cid, retirables, err_type) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ return RMS_OK;\r
+\r
+error:\r
+ if (!retirables->empty())\r
+ retirables->clear();\r
+\r
+ return RMS_ERROR;\r
+}\r
+\r
+\r
+void CAudioDecoderStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)\r
+{\r
+ std::map<int, int> consumer_list;\r
+ std::multimap<unsigned long, CVirtualResource *> filtered_vresources;\r
+\r
+ ExcludeResources(vresources, &filtered_vresources, req);\r
+\r
+ for (auto const &it : filtered_vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+\r
+ if (GetRetirableConsumers(vresource, req, retirables, err_type) == RMS_OK)\r
+ break;\r
+ }\r
+\r
+ for (auto const &it : consumer_list) {\r
+ retirables->insert(std::pair<int, int>(it.first, it.second));\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <assert.h>\r
+\r
+#include <rms_debug.h>\r
+#include <CResourceDB.h>\r
+#include <CResource.h>\r
+#include <CVirtualResource.h>\r
+#include <CRequest.h>\r
+#include <CRequester.h>\r
+#include <CPriority.h>\r
+#include <CDependencyController.h>\r
+#include <CAllocateStrategy.h>\r
+#include <CExclusiveStrategy.h>\r
+\r
+void CExclusiveStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)\r
+{\r
+ CRequester *requester = req->getRequester();\r
+\r
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+ return;\r
+ }\r
+\r
+ if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle())) {\r
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
+ return;\r
+ }\r
+\r
+ if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)\r
+ return;\r
+\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+}\r
+\r
+bool CExclusiveStrategy::isAllocatableResource(CVirtualResource *vresource, CRequest *req)\r
+{\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (resource->IsReserved()) {\r
+ SERVER_INFO("device id(%d) is reserved state", resource->GetDeviceID());\r
+ return false;\r
+ }\r
+\r
+ if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters())) {\r
+ updateReasonByMemCluster(vresource, req);\r
+ return false;\r
+ }\r
+\r
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
+ updateReasonByResourceState(resource->GetDeviceID(), req);\r
+ return false;\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+bool CExclusiveStrategy::isSharableResource(CVirtualResource *vresource, CRequest *req)\r
+{\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (resource->IsReserved()) {\r
+ SERVER_INFO("device id(%d) is reserved state", resource->GetDeviceID());\r
+ return false;\r
+ }\r
+\r
+ if (resource->getSharableCount() <= 0) {\r
+ SERVER_INFO("device id(%d) is not sharable state", resource->GetDeviceID());\r
+ updateReasonBySharableCount(resource->GetDeviceID(), req);\r
+ return false;\r
+ }\r
+\r
+ if (!CDependencyController::getInstance()->isSharableMemClusters(vresource->GetMemClusters(), resource->GetDeviceID())) {\r
+ updateReasonByMemCluster(vresource, req);\r
+ return false;\r
+ }\r
+\r
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
+ updateReasonByResourceState(resource->GetDeviceID(), req);\r
+ return false;\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+CVirtualResource *CExclusiveStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)\r
+{\r
+ std::map<int, CVirtualResource *> filtered_vresources;\r
+ ExcludeResources(vresources, &filtered_vresources, req);\r
+\r
+ req->SetResult(RMS_ERROR);\r
+ req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);\r
+\r
+ for (auto const &it : filtered_vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ bool isReservable = (req->GetState() == RMS_STATE_SHARABLE) ? isSharableResource(vresource, req) : isAllocatableResource(vresource, req);\r
+\r
+ SERVER_INFO("is Reservable ? %d", isReservable);\r
+\r
+ if (!isReservable)\r
+ continue;\r
+\r
+ return vresource;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+int CExclusiveStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)\r
+{\r
+ CResource *rsc = vrsc->GetResource();\r
+\r
+ if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)\r
+ return RMS_ERROR;\r
+\r
+ rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+bool CExclusiveStrategy::ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources)\r
+{\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+\r
+ for (auto const &it : vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters()))\r
+ continue;\r
+\r
+ if (!resource->IsFreeState())\r
+ continue;\r
+\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+bool CExclusiveStrategy::ContainSharableResource(std::multimap<unsigned long, CVirtualResource *> vresources)\r
+{\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+\r
+ for (auto const &it : vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (!dc->isSharableMemClusters(vresource->GetMemClusters(), resource->GetDeviceID()))\r
+ continue;\r
+\r
+ if (!resource->IsSharableState())\r
+ continue;\r
+\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+int CExclusiveStrategy::getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)\r
+{\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters())) {\r
+ if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), req->getRequester()->getHandle(), retirables) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ if (!resource->IsFreeState()) {\r
+ if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), req->getRequester()->getHandle(), retirables, err_type) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ return RMS_OK;\r
+\r
+error:\r
+ if (!retirables->empty())\r
+ retirables->clear();\r
+\r
+ return RMS_ERROR;\r
+}\r
+\r
+int CExclusiveStrategy::getRetirableConsumersShare(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)\r
+{\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (!dc->isSharableMemClusters(vresource->GetMemClusters(), resource->GetDeviceID())) {\r
+ if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), req->getRequester()->getHandle(), retirables) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ if (!resource->IsSharableState()) {\r
+ if (CPriority::getReclaimableConsumersShare(resource->GetDeviceID(), req->getRequester()->getHandle(), retirables, err_type) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ return RMS_OK;\r
+\r
+error:\r
+ if (!retirables->empty())\r
+ retirables->clear();\r
+\r
+ return RMS_ERROR;\r
+}\r
+\r
+\r
+void CExclusiveStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)\r
+{\r
+ std::multimap<int, int> consumer_list;\r
+ std::multimap<unsigned long, CVirtualResource *> filtered_vresources;\r
+\r
+ ExcludeResources(vresources, &filtered_vresources, req);\r
+\r
+ bool isShareMode = (req->GetState() == RMS_STATE_SHARABLE);\r
+ bool hasAllocatableResource = (isShareMode) ? ContainSharableResource(filtered_vresources) : ContainAvailableResource(filtered_vresources);\r
+\r
+ if (hasAllocatableResource)\r
+ return;\r
+\r
+ for (auto const &it : filtered_vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+\r
+ int result = (isShareMode) ? getRetirableConsumersShare(vresource, req, &consumer_list, err_type) : getRetirableConsumersExclusive(vresource, req, &consumer_list, err_type);\r
+\r
+ if (result == RMS_OK)\r
+ break;\r
+ }\r
+\r
+ for (auto const &it : consumer_list) {\r
+ retirables->insert(std::pair<int, int>(it.first, it.second));\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <assert.h>\r
+#include <algorithm>\r
+#include <vector>\r
+#include <rms_debug.h>\r
+#include <rms_type.h>\r
+#include <CRequest.h>\r
+#include <CAllocateModeStrategy.h>\r
+#include <CInvalidModeStrategy.h>\r
+\r
+CInvalidModeStrategy::CInvalidModeStrategy()\r
+{\r
+}\r
+\r
+CInvalidModeStrategy::~CInvalidModeStrategy()\r
+{\r
+}\r
+\r
+bool CInvalidModeStrategy::CanAllocateResources(std::vector<CRequest *> requests, rms_allocate_result_s *result)\r
+{\r
+ result->result = RMS_ERROR;\r
+ result->reason = RMS_ERR_TYPE_INVALID_REQUEST;\r
+\r
+ SERVER_ERR("Invalid request set");\r
+ std::for_each(requests.begin(), requests.end(), [](CRequest *req) { SERVER_ERR("req state(%d)", req->GetState()); });\r
+\r
+ return false;\r
+}\r
+\r
+void CInvalidModeStrategy::WriteAllocResult(rms_allocate_result_s *alloc_result, std::vector<CRequest *> requests, rms_return_device_s *allocated_devices)\r
+{\r
+ assert(allocated_devices);\r
+\r
+ allocated_devices->result = RMS_ERROR;\r
+ allocated_devices->error_type = RMS_ERR_TYPE_INVALID_REQUEST;\r
+ allocated_devices->resources_num = 0;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <stdlib.h>\r
+\r
+#include <rms_type.h>\r
+#include <rms_debug.h>\r
+#include <CVirtualResource.h>\r
+#include <CConsumer.h>\r
+#include <CResourceManager.h>\r
+#include <CRequest.h>\r
+#include <CRequester.h>\r
+#include <CMixingMode.h>\r
+#include <CResourceObserver.h>\r
+#include <CDependencyController.h>\r
+#include <CPriority.h>\r
+#include <CAudioCodec.h>\r
+#include <CAudioCodecCollection.h>\r
+#include <CMixingStrategy.h>\r
+\r
+CMixingStrategy *CMixingStrategy::m_instance = NULL;\r
+\r
+CMixingStrategy *CMixingStrategy::getInstance(void)\r
+{\r
+ if (!m_instance)\r
+ m_instance = new CMixingStrategy();\r
+\r
+ return m_instance;\r
+}\r
+\r
+bool CMixingStrategy::isAvailableAudioCodec(std::string name, int consumer_id, rms_error_type_e *reason)\r
+{\r
+ CAudioCodec *audio_codec = CAudioCodecCollection::getInstance()->findAudioCodec(name.c_str());\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+\r
+ if (!audio_codec) {\r
+ SERVER_ERR("not existing audio codec (%s)", name.c_str());\r
+ *reason = RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST;\r
+ return false;\r
+ }\r
+\r
+ if (!audio_codec->isMixingSupported() && dc->isAudioCodecBeingUsed()) {\r
+ SERVER_ERR("mixing not supported (%s)", name.c_str());\r
+ return false;\r
+ }\r
+\r
+ if (!dc->isAvailableAudioCodec(name)) {\r
+ SERVER_ERR("not available audio codec (%s)", name.c_str());\r
+ return false;\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+int CMixingStrategy::getReclaimableAudioCodecConsumers(std::string codec_name, int consumer_id, CRequest *req, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)\r
+{\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+ CAudioCodec *codec = CAudioCodecCollection::getInstance()->findAudioCodec(codec_name);\r
+\r
+ if (!codec)\r
+ return RMS_ERROR;\r
+\r
+ std::map<unsigned long, std::pair<int, int>> acodec_consumers = dc->getAudioCodecConsumers();\r
+\r
+ if (!codec->isMixingSupported() && dc->isAudioCodecBeingUsed()) {\r
+ for (auto const &it : acodec_consumers) {\r
+ if (!CPriority::isReclaimableConsumer(it.second.second, consumer_id, err_type))\r
+ return RMS_ERROR;\r
+\r
+ reclaimables->insert(std::pair<int, int>(it.second.first, it.second.second));\r
+ }\r
+\r
+ return RMS_OK;\r
+ }\r
+\r
+ if (!dc->isAvailableAudioCodec(codec_name)) {\r
+ for (auto const &it : acodec_consumers) {\r
+ CResource *rsc = CResourceDB::getInstance()->FindResource(it.second.first);\r
+ if (req->IsMainDeviceRequest() && !rsc->IsMainDevice())\r
+ continue;\r
+ if (req->IsSubDeviceRequest() && rsc->IsMainDevice())\r
+ continue;\r
+ if (!CPriority::isReclaimableConsumer(it.second.second, consumer_id, err_type))\r
+ continue;\r
+\r
+ reclaimables->insert(std::pair<int, int>(it.second.first, it.second.second));\r
+ return RMS_OK;\r
+ }\r
+ }\r
+\r
+ return RMS_ERROR;\r
+\r
+}\r
+\r
+bool CMixingStrategy::isAvailableMixingMode(rms_mixing_mode_e mode)\r
+{\r
+ CMixingMode *cur_mode = CDependencyController::getInstance()->getCurMixingMode();\r
+\r
+ if (!cur_mode)\r
+ return true;\r
+\r
+ SERVER_INFO("cur_mode(%d)/requested(%d)", cur_mode->getMode(), mode);\r
+\r
+ return (mode == cur_mode->getMode());\r
+}\r
+\r
+int CMixingStrategy::getReclaimableMixingModeConsumers(rms_mixing_mode_e mode, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)\r
+{\r
+ CMixingMode *cur_mode = CDependencyController::getInstance()->getCurMixingMode();\r
+\r
+ if (!cur_mode) {\r
+ SERVER_ERR("there is no mixing mode to reclaim");\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ SERVER_INFO("cur mixing mode (%d), requested codec (%d)", cur_mode->getMode(), mode);\r
+\r
+ std::map<int, int> consumers = cur_mode->GetConsumers();\r
+\r
+ if (consumers.size() == 0) {\r
+ SERVER_ERR("no consumer to reclaim in mixing mode(%d)", cur_mode->getMode());\r
+ return RMS_ERROR;\r
+ }\r
+\r
+ for (auto const &it_consumer : consumers) {\r
+ if (!CPriority::isReclaimableConsumer(it_consumer.second, consumer_id, err_type))\r
+ return RMS_ERROR;\r
+\r
+ reclaimables->insert(std::pair<int, int>(it_consumer.first, it_consumer.second));\r
+ }\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+bool CMixingStrategy::canReclaimMixingMode(rms_mixing_mode_e mode, CMixingMode *cur_mode, int consumer_id)\r
+{\r
+ std::map<int, int> consumers = cur_mode->GetConsumers();\r
+\r
+ if (consumers.size() == 0) {\r
+ SERVER_ERR("no consumer to reclaim in mixing mode(%d)", cur_mode->getMode());\r
+ return false;\r
+ }\r
+\r
+ for (auto const &it_consumer : consumers) {\r
+ if (!CPriority::isReclaimableConsumer(it_consumer.second, consumer_id, NULL))\r
+ return false;\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+bool CMixingStrategy::canReclaimMixingMode(rms_mixing_mode_e mode, int consumer_id)\r
+{\r
+ CMixingMode *mixing_mode = CDependencyController::getInstance()->getCurMixingMode();\r
+\r
+ return (mixing_mode != NULL) ? canReclaimMixingMode(mode, mixing_mode, consumer_id) : false;\r
+}\r
+\r
+void CMixingStrategy::updateReasonByMixingMode(CVirtualResource *vresource, CRequest *req, rms_error_type_e cur_reason)\r
+{\r
+ CRequester *requester = req->getRequester();\r
+\r
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+ return;\r
+ }\r
+\r
+ if (!needReclaimCheck(cur_reason)) {\r
+ req->SetReason(cur_reason);\r
+ return;\r
+ }\r
+\r
+ if (canReclaimMixingMode(req->GetMixingMode(), requester->getHandle())) {\r
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
+ return;\r
+ }\r
+\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+\r
+}\r
+\r
+void CMixingStrategy::updateReasonByAudioCodec(CVirtualResource *vresource, CRequest *req, rms_error_type_e cur_reason)\r
+{\r
+ CRequester *requester = req->getRequester();\r
+\r
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+ return;\r
+ }\r
+\r
+ if (!needReclaimCheck(cur_reason)) {\r
+ req->SetReason(cur_reason);\r
+ return;\r
+ }\r
+\r
+ if (canReclaimAudioCodec(vresource->GetAudioCodec(), requester->getHandle())) {\r
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
+ return;\r
+ }\r
+\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+}\r
+\r
+bool CMixingStrategy::needReclaimCheck(rms_error_type_e reason)\r
+{\r
+ bool result = false;\r
+\r
+ switch (reason) {\r
+ case RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER:\r
+ case RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST:\r
+ SERVER_ERR("erro case : %d", reason);\r
+ result = false;\r
+ break;\r
+ default:\r
+ result = true;\r
+ break;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+bool CMixingStrategy::canReclaimAudioCodec(std::string codec_name, int consumer_id)\r
+{\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+ CAudioCodec *codec = CAudioCodecCollection::getInstance()->findAudioCodec(codec_name);\r
+\r
+ if (!codec)\r
+ return false;\r
+\r
+ std::map<unsigned long, std::pair<int, int>> acodec_consumers = dc->getAudioCodecConsumers();\r
+ rms_error_type_e err_type;\r
+\r
+ if (!codec->isMixingSupported() && dc->isAudioCodecBeingUsed()) {\r
+ for (auto const &it : acodec_consumers)\r
+ {\r
+ if (!CPriority::isReclaimableConsumer(it.second.second, consumer_id, &err_type))\r
+ return false;\r
+ }\r
+\r
+ return true;\r
+ }\r
+\r
+ if (!dc->isAvailableAudioCodec(codec_name)) {\r
+ for (auto const &it : acodec_consumers) {\r
+ if (!CPriority::isReclaimableConsumer(it.second.second, consumer_id, &err_type))\r
+ continue;\r
+\r
+ return true;\r
+ }\r
+ }\r
+\r
+ return false;\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <assert.h>\r
+\r
+#include <rms_debug.h>\r
+#include <CResourceDB.h>\r
+#include <CBandwidth.h>\r
+#include <CResource.h>\r
+#include <CVirtualResource.h>\r
+#include <CRequest.h>\r
+#include <CRequester.h>\r
+#include <CPriority.h>\r
+#include <CDependencyController.h>\r
+#include <CAllocateStrategy.h>\r
+#include <CNDecodingVideoDecoderStrategy.h>\r
+\r
+void CNDecodingVideoDecoderStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)\r
+{\r
+ CRequester *requester = req->getRequester();\r
+\r
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+ return;\r
+ }\r
+\r
+ if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle())) {\r
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
+ return;\r
+ }\r
+\r
+ if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)\r
+ return;\r
+\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+}\r
+\r
+void CNDecodingVideoDecoderStrategy::updateReasonByBW(CVirtualResource *vresource, CRequest *req)\r
+{\r
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+ return;\r
+ }\r
+\r
+ rms_error_type_e reason = canReclaimRequiredBW(req, vresource->GetBW()) ?\r
+ RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER : RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;\r
+ req->SetReason(reason);\r
+}\r
+\r
+void CNDecodingVideoDecoderStrategy::updateReasonByTripleDecoding(CRequest *req)\r
+{\r
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+ return;\r
+ }\r
+\r
+ rms_error_type_e reason = canReclaimActiveVideoDecoders(req) ?\r
+ RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER : RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;\r
+ req->SetReason(reason);\r
+}\r
+\r
+bool CNDecodingVideoDecoderStrategy::isAllocatableResource(CVirtualResource *vresource, CRequest *req)\r
+{\r
+ int category_class = vresource->GetCategoryClass();\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (resource->IsReserved()) {\r
+ SERVER_INFO("device id(%d) is reserved state", resource->GetDeviceID());\r
+ return false;\r
+ }\r
+\r
+ if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters(), category_class, vresource->GetCategoryType())) {\r
+ updateReasonByMemCluster(vresource, req);\r
+ return false;\r
+ }\r
+\r
+ CBandwidth *bandwidth = CBandwidth::GetInstance();\r
+ if ((bandwidth->GetNConsumersNDec(vresource->GetCategoryType()) == 0) && (vresource->GetBW() > bandwidth->GetAvail())) {\r
+ SERVER_INFO("insufficient BW required(%d)/avail(%d)", vresource->GetBW(), bandwidth->GetAvail());\r
+ updateReasonByBW(vresource, req);\r
+ return false;\r
+ }\r
+\r
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
+ updateReasonByResourceState(resource->GetDeviceID(), req);\r
+ return false;\r
+ }\r
+\r
+ if (!CResourceDB::getInstance()->HasAvailableDecoderNDecoding()) {\r
+ updateReasonByTripleDecoding(req);\r
+ return false;\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+CVirtualResource *CNDecodingVideoDecoderStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)\r
+{\r
+ std::map<int, CVirtualResource *> filtered_vresources;\r
+ ExcludeResources(vresources, &filtered_vresources, req);\r
+\r
+ req->SetResult(RMS_ERROR);\r
+ req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);\r
+\r
+ for (auto const &it : filtered_vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ if (!isAllocatableResource(vresource, req))\r
+ continue;\r
+\r
+ return vresource;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+int CNDecodingVideoDecoderStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)\r
+{\r
+ CResource *rsc = vrsc->GetResource();\r
+\r
+ if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)\r
+ return RMS_ERROR;\r
+\r
+ rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+bool CNDecodingVideoDecoderStrategy::ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources)\r
+{\r
+\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+ CBandwidth *bandwidth = CBandwidth::GetInstance();\r
+\r
+ for (auto const &it : vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+ int category_class = vresource->GetCategoryClass();\r
+\r
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters(), category_class, vresource->GetCategoryType()))\r
+ continue;\r
+\r
+ if ((bandwidth->GetNConsumersNDec(vresource->GetCategoryType()) == 0) && (bandwidth->GetAvail() < vresource->GetBW()))\r
+ continue;\r
+\r
+ if (!resource->IsFreeState())\r
+ continue;\r
+\r
+ if (!CResourceDB::getInstance()->HasAvailableDecoderNDecoding())\r
+ continue;\r
+\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+int CNDecodingVideoDecoderStrategy::getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)\r
+{\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+ CResourceDB *resource_db = CResourceDB::getInstance();\r
+ CResource *resource = vresource->GetResource();\r
+ CBandwidth *bandwidth = CBandwidth::GetInstance();\r
+ int requester_id = req->getRequester()->getHandle();\r
+ int category_class = vresource->GetCategoryClass();\r
+\r
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters(), category_class, vresource->GetCategoryType())) {\r
+ if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), requester_id, retirables) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ if ((bandwidth->GetNConsumersNDec(vresource->GetCategoryType()) == 0) && ((bandwidth->GetAvail() + GetReclaimedBW(retirables)) < vresource->GetBW())) {\r
+ if (GetConsumerUsingBW(req, vresource->GetBW(), retirables) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ if (!resource->IsFreeState()) {\r
+ if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), requester_id, retirables, err_type) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ if (!resource_db->HasAvailableDecoderNDecoding(*retirables)) {\r
+ if (GetReclaimableVideoDecoderConsumers(requester_id, retirables, req, err_type) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ return RMS_OK;\r
+error:\r
+ if (!retirables->empty())\r
+ retirables->clear();\r
+\r
+ return RMS_ERROR;\r
+}\r
+\r
+void CNDecodingVideoDecoderStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)\r
+{\r
+ std::multimap<int, int> consumer_list;\r
+ std::multimap<unsigned long, CVirtualResource *> filtered_vresources;\r
+ bool included = false;\r
+\r
+ ExcludeResources(vresources, &filtered_vresources, req);\r
+\r
+ if (ContainAvailableResource(filtered_vresources))\r
+ return;\r
+\r
+ for (auto const &it : filtered_vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ included = false;\r
+ CResource *rsc = vresource->GetResource();\r
+ SERVER_INFO("vrsc(%d)/rsc(%d)", vresource->GetVResourceID(), rsc->GetDeviceID());\r
+ if (getRetirableConsumersExclusive(vresource, req, &consumer_list, err_type) == RMS_OK) {\r
+ for (auto const &it_c : consumer_list) {\r
+ auto it_r = retirables->find(it_c.first);\r
+ if (it_r != retirables->end()) {\r
+ included = true;\r
+ SERVER_INFO("(%d:%d) is already in the list", it_c.first, it_c.second);\r
+ break;\r
+ }\r
+ }\r
+ if (included)\r
+ continue;\r
+\r
+ break;\r
+ }\r
+ }\r
+\r
+ retirables->insert(consumer_list.begin(), consumer_list.end());\r
+}\r
+\r
+bool CNDecodingVideoDecoderStrategy::canReclaimRequiredBW(CRequest *req, unsigned int bw)\r
+{\r
+ CRequester *requester = req->getRequester();\r
+ CResourceDB *resource_db = CResourceDB::getInstance();\r
+ CBandwidth *bandwidth = CBandwidth::GetInstance();\r
+ unsigned int check_available = bandwidth->GetAvail();\r
+ std::map<int, int> bw_consumers = bandwidth->GetConsumers();\r
+\r
+ for (std::map<int, int>::iterator it = bw_consumers.begin(); it != bw_consumers.end(); it++) {\r
+ int device_id = (*it).first;\r
+ int consumer_id = (*it).second;\r
+\r
+ CResource *pRsc = resource_db->FindResource(device_id);\r
+\r
+ if (!pRsc) {\r
+ SERVER_ERR("cannot find resource using device id");\r
+ continue;\r
+ }\r
+\r
+ if (requester->getHandle() == consumer_id) {\r
+ SERVER_INFO("CID[%d] is using BW (%d)", requester->getHandle(), pRsc->GetBW());\r
+ continue;\r
+ }\r
+\r
+ if (CPriority::compare(consumer_id, requester->getHandle()) != HIGH_PRIORITY)\r
+ continue;\r
+\r
+ check_available += pRsc->GetBW();\r
+\r
+ if (bw <= check_available)\r
+ break;\r
+\r
+ SERVER_INFO("DevID[%d]/ need more resource to be released!!! required BW(%d)-resource BW(%d)-check(%d)", pRsc->GetDeviceID(), bw, pRsc->GetBW(), check_available); \r
+\r
+ }\r
+\r
+ SERVER_INFO("required BW(%d) - available (%d)", bw, check_available);\r
+\r
+ return (bw <= check_available);\r
+}\r
+\r
+void CNDecodingVideoDecoderStrategy::SelectDevicesByMainSub(CRequest *req, std::map<int, int> *src, std::map<int, int> *result)\r
+{\r
+ CResourceDB *db = CResourceDB::getInstance();\r
+\r
+ for (auto const &it : *src) {\r
+ CResource *rsc = db->FindResource(it.first);\r
+ if (!rsc)\r
+ continue;\r
+ if (req->IsMainDeviceRequest() && !rsc->IsMainDevice())\r
+ continue;\r
+ if (req->IsSubDeviceRequest() && rsc->IsMainDevice())\r
+ continue;\r
+\r
+ result->insert(std::pair<int, int>(it.first, it.second));\r
+ }\r
+}\r
+\r
+int CNDecodingVideoDecoderStrategy::GetConsumerUsingBW(CRequest *req, unsigned int bw, std::multimap<int, int>* return_ids)\r
+{\r
+ std::map<int, int> candidates;\r
+ std::map<int, int> cur_consumers = CBandwidth::GetInstance()->GetConsumers(); //device id, consumer id\r
+\r
+ SelectDevicesByMainSub(req, &cur_consumers, &candidates);\r
+\r
+ std::multimap<int, int> reclaimed_by_ms;\r
+ unsigned int avail_bw = GetConsumerUsingBWByAllocationTime(req->getRequester()->getHandle(), bw, candidates, &reclaimed_by_ms);\r
+\r
+ if (avail_bw >= bw) {\r
+ return_ids->insert(reclaimed_by_ms.begin(), reclaimed_by_ms.end());\r
+ return RMS_OK;\r
+ }\r
+\r
+ std::multimap<int, int> reclaimed_by_t;\r
+ GetConsumerUsingBWByAllocationTime(req->getRequester()->getHandle(), bw, cur_consumers, &reclaimed_by_t);\r
+ return_ids->insert(reclaimed_by_t.begin(), reclaimed_by_t.end());\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+int CNDecodingVideoDecoderStrategy::GetConsumerUsingBWByAllocationTime(int requester_id, unsigned int required_bw, std::map<int, int> bw_consumers, std::multimap<int, int>* reclaimed_consumers)\r
+{\r
+ assert(reclaimed_consumers);\r
+\r
+ CResourceDB *resource_db = CResourceDB::getInstance();\r
+ CBandwidth *bandwidth = CBandwidth::GetInstance();\r
+\r
+ SERVER_INFO("candidates using BW : %zu", bw_consumers.size());\r
+ unsigned int reclaimed_bw = bandwidth->GetAvail();\r
+\r
+ std::map<unsigned long, int> consumers_by_t;\r
+ for (auto const &itc : bw_consumers) {\r
+ CResource *rsc = resource_db->FindResource(itc.first);\r
+ if (!rsc)\r
+ continue;\r
+\r
+ consumers_by_t.insert(std::pair<unsigned long, int>(rsc->GetAllocatedTime(), itc.first));\r
+ }\r
+\r
+ for (auto const &it : consumers_by_t) {\r
+ int device_id = it.second;\r
+ CResource *pRsc = resource_db->FindResource(device_id);\r
+ if (!pRsc)\r
+ continue;\r
+\r
+ int consumer_id = pRsc->GetFirstConsumer();\r
+ SERVER_INFO("consumer (%d) is using bw for device (%d)", consumer_id, device_id);\r
+\r
+ if (requester_id == consumer_id) {\r
+ SERVER_INFO("CID[%d] is using BW (%d)", requester_id, pRsc->GetBW());\r
+ continue;\r
+ }\r
+\r
+ if (CPriority::compare(consumer_id, requester_id) != HIGH_PRIORITY)\r
+ continue;\r
+\r
+ auto ret = reclaimed_consumers->find(device_id);\r
+ if (ret != reclaimed_consumers->end()) {\r
+ SERVER_INFO("(%d:%d) already inserted", device_id, consumer_id);\r
+ continue;\r
+ }\r
+\r
+ reclaimed_consumers->insert(std::pair<int, int>(device_id, consumer_id));\r
+\r
+ if (pRsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) {\r
+ std::map<int, int> siblings;\r
+ bandwidth->GetConsumersNDec(pRsc->GetCurCategory(), &siblings);\r
+ if (siblings.size() > 0) {\r
+ SERVER_INFO("insert n-dec siblings(%zu)", siblings.size());\r
+ reclaimed_consumers->insert(siblings.begin(), siblings.end());\r
+ }\r
+ }\r
+\r
+ reclaimed_bw += pRsc->GetBW();\r
+\r
+ if (required_bw <= reclaimed_bw)\r
+ break;\r
+ SERVER_INFO("DevID[%d]/ need more BW! required:(%d)-resource(%d)-reclaimed(%d)", pRsc->GetDeviceID(), required_bw, pRsc->GetBW(), reclaimed_bw);\r
+ }\r
+\r
+ return reclaimed_bw;\r
+}\r
+\r
+bool CNDecodingVideoDecoderStrategy::canReclaimActiveVideoDecoders(CRequest *req)\r
+{\r
+ CRequester *requester = req->getRequester();\r
+ CResourceDB *resource_db = CResourceDB::getInstance();\r
+ std::map<int, int> active_vdecs = resource_db->GetActiveVideoDecoders();\r
+\r
+ for (auto const &it : active_vdecs) {\r
+ int dev_id = it.first;\r
+ int cid = it.second;\r
+\r
+ CResource *rsc = resource_db->FindResource(dev_id);\r
+\r
+ if (!rsc) {\r
+ SERVER_ERR("can't find resource (%d)", dev_id);\r
+ continue;\r
+ }\r
+\r
+ if (requester->getHandle() == cid) {\r
+ SERVER_INFO("CID[%d] is using device (%d)", cid, dev_id);\r
+ continue;\r
+ }\r
+\r
+ if (CPriority::compare(cid, requester->getHandle()) == HIGH_PRIORITY)\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+\r
+}\r
+\r
+int CNDecodingVideoDecoderStrategy::GetReclaimableVideoDecoderConsumers(int consumer_id, std::multimap<int, int>* reclaimables, CRequest *req, rms_error_type_e *err_type)\r
+{\r
+ std::map<unsigned long, CResource*> rscs;\r
+ CResource *rsc = NULL;\r
+ CResourceDB *resource_db = CResourceDB::getInstance();\r
+ std::map<int, int> active_vdecs = resource_db->GetActiveVideoDecoders();\r
+ bool has_main_vdec = false;\r
+ bool has_sub_vdec = false;\r
+\r
+ for (auto const &it_vdec : active_vdecs) {\r
+ rsc = resource_db->FindResource(it_vdec.first);\r
+ rscs.insert(std::pair<unsigned long, CResource*>(rsc->GetAllocatedTime(), rsc));\r
+\r
+ if (rsc->IsMainDevice())\r
+ has_main_vdec = true;\r
+ else\r
+ has_sub_vdec = true;\r
+ }\r
+\r
+ for (auto const &it : rscs)\r
+ {\r
+ rsc = it.second;\r
+\r
+ if (req->IsMainDeviceRequest() && has_main_vdec && !rsc->IsMainDevice())\r
+ continue;\r
+ if (req->IsSubDeviceRequest() && has_sub_vdec && rsc->IsMainDevice())\r
+ continue;\r
+\r
+ if (CPriority::getReclaimableConsumers(rsc->GetDeviceID(), consumer_id, reclaimables, err_type) == RMS_OK)\r
+ return RMS_OK;\r
+ }\r
+\r
+ return RMS_ERROR;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <assert.h>\r
+#include <algorithm>\r
+\r
+#include <rms_debug.h>\r
+#include <CRequest.h>\r
+#include <CResource.h>\r
+#include <CResourceDB.h>\r
+#include <CResourceCategory.h>\r
+#include <CAllocateModeStrategy.h>\r
+#include <CNormalModeStrategy.h>\r
+\r
+void ReserveCandidate(CRequest *req)\r
+{\r
+ CResourceCategory *resource_category = CResourceDB::getInstance()->FindResourceCategory(req->GetCategory());\r
+\r
+ req->SetResult(RMS_ERROR);\r
+\r
+ if (!resource_category) {\r
+ if (req->GetCategory() == RMS_CATEGORY_NOT_PERMITTED)\r
+ req->SetReason(RMS_ERR_TYPE_NOT_PERMITTED);\r
+ else\r
+ req->SetReason(RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST);\r
+\r
+ SERVER_ERR("not existing category(%d)! can't allocate a candidate", req->GetCategory());\r
+ return;\r
+ }\r
+\r
+ CResource *resource = resource_category->ReserveCandidate(req, true);\r
+\r
+ if (!resource)\r
+ return;\r
+\r
+ req->SetResult(RMS_OK);\r
+ req->SetCandidateDevice(resource->GetDeviceID());\r
+}\r
+\r
+void ReleaseReservedResources(CRequest *req)\r
+{\r
+ if (req->GetResult() != RMS_OK)\r
+ return;\r
+\r
+ CResource *resource = CResourceDB::getInstance()->FindResource(req->GetCandidateDevice());\r
+\r
+ resource->CancelReservation((rms_requests_resource_state_e) req->GetState());\r
+}\r
+\r
+rms_return_code_e ToAllocReturnCode(rms_error_type_e error_type)\r
+{\r
+ rms_return_code_e result = RMS_OK;\r
+\r
+ switch (error_type) {\r
+ case RMS_ERR_TYPE_NONE:\r
+ result = RMS_OK;\r
+ break;\r
+ case RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER:\r
+ result = RMS_ERROR_TAKE_RESOURCE_FROM_OTHER_CONSUMER;\r
+ break;\r
+ default:\r
+ result = RMS_ERROR;\r
+ break;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+\r
+CNormalModeStrategy::CNormalModeStrategy()\r
+{\r
+}\r
+\r
+CNormalModeStrategy::~CNormalModeStrategy()\r
+{\r
+}\r
+\r
+rms_error_type_e CNormalModeStrategy::GetCandidateFindResult(std::vector<CRequest *> requests)\r
+{\r
+ rms_error_type_e result = RMS_ERR_TYPE_NONE;\r
+\r
+ for (auto& it : requests) {\r
+ CRequest *request = it;\r
+\r
+ if (request->GetResult() == RMS_OK)\r
+ continue;\r
+\r
+ if (request->GetReason() != RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)\r
+ return request->GetReason();\r
+\r
+ result = RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+bool CNormalModeStrategy::CanAllocateResources(std::vector<CRequest*> requests, rms_allocate_result_s *result)\r
+{\r
+ std::for_each(requests.begin(), requests.end(), ReserveCandidate);\r
+\r
+ result->reason = GetCandidateFindResult(requests);\r
+ result->result = ToAllocReturnCode(result->reason);\r
+\r
+ std::for_each(requests.begin(), requests.end(), ReleaseReservedResources);\r
+\r
+ return (result->result == RMS_OK);\r
+}\r
+\r
+void CNormalModeStrategy::WriteAllocResult(rms_allocate_result_s *alloc_result, std::vector<CRequest *> requests, rms_return_device_s *allocated_devices)\r
+{\r
+ assert(allocated_devices);\r
+\r
+ allocated_devices->result = alloc_result->result;\r
+ allocated_devices->error_type = alloc_result->reason;\r
+\r
+ if (alloc_result->result != RMS_OK) {\r
+ allocated_devices->resources_num = 0;\r
+ return;\r
+ }\r
+\r
+ allocated_devices->resources_num = requests.size();\r
+ allocated_devices->device_ids = (int*) calloc(requests.size(), sizeof(int));\r
+ assert(allocated_devices->device_ids);\r
+ allocated_devices->devices = (rms_return_device_info_s*) calloc(requests.size(), sizeof(rms_return_device_info_s));\r
+\r
+ int i = 0;\r
+\r
+ for (auto const &it : requests) {\r
+ allocated_devices->device_ids[i] = it->GetAllocatedVirtualDevice();\r
+ allocated_devices->devices[i].device_id = it->GetAllocatedVirtualDevice();\r
+ CResource *resource = CResourceDB::getInstance()->FindResource(it->GetAllocatedDevice());\r
+ assert(resource);\r
+\r
+ const char *path = resource->GetDevicePath();\r
+ allocated_devices->devices[i].device_path = strndup(path, strlen(path));\r
+ resource->SetAllocatedTime();\r
+ i++;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <assert.h>\r
+\r
+#include <rms_debug.h>\r
+#include <CResource.h>\r
+#include <CVirtualResource.h>\r
+#include <CResourceDB.h>\r
+#include <CRequest.h>\r
+#include <CPriority.h>\r
+#include <CRequester.h>\r
+#include <CNormalStrategy.h>\r
+\r
+CNormalStrategy::CNormalStrategy()\r
+{\r
+}\r
+\r
+CNormalStrategy::~CNormalStrategy()\r
+{\r
+}\r
+\r
+CVirtualResource *CNormalStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)\r
+{\r
+ std::map<int, CVirtualResource *> filtered_vresources;\r
+ ExcludeResources(vresources, &filtered_vresources, req);\r
+\r
+ req->SetResult(RMS_ERROR);\r
+ req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);\r
+\r
+ for (auto const &it : filtered_vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+ int device_id = resource->GetDeviceID();\r
+\r
+ if (resource->IsReserved())\r
+ continue;\r
+\r
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
+ updateReasonByResourceState(device_id, req);\r
+ continue;\r
+ }\r
+\r
+ return vresource;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+int CNormalStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)\r
+{\r
+ CResource *rsc = vrsc->GetResource();\r
+\r
+ if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)\r
+ return RMS_ERROR;\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+bool CNormalStrategy::ContainFreeResource(std::multimap<unsigned long, CVirtualResource *> vresources)\r
+{\r
+ for (auto const &it : vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (resource->IsFreeState())\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+void CNormalStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)\r
+{\r
+ std::multimap<int, int> consumer_list;\r
+ std::multimap<unsigned long, CVirtualResource *> filtered_vresources;\r
+\r
+ ExcludeResources(vresources, &filtered_vresources, req);\r
+\r
+ if (ContainFreeResource(filtered_vresources))\r
+ return;\r
+\r
+ for (auto const &it : filtered_vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), req->getRequester()->getHandle(), &consumer_list, err_type) == RMS_OK)\r
+ break;\r
+ }\r
+\r
+ for (auto const &it : consumer_list) {\r
+ retirables->insert(std::pair<int, int>(it.first, it.second));\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <assert.h>\r
+#include <algorithm>\r
+\r
+#include <rms_type.h>\r
+#include <rms_debug.h>\r
+\r
+#include <CRequest.h>\r
+#include <CResource.h>\r
+#include <CResourceDB.h>\r
+#include <CResourceCategory.h>\r
+#include <CAllocateModeStrategy.h>\r
+#include <CPreferenceModeStrategy.h>\r
+\r
+CPreferenceModeStrategy::CPreferenceModeStrategy()\r
+{\r
+}\r
+\r
+CPreferenceModeStrategy::~CPreferenceModeStrategy()\r
+{\r
+}\r
+\r
+bool CPreferenceModeStrategy::CanAllocateResources(std::vector<CRequest*> requests, rms_allocate_result_s *result)\r
+{\r
+ result->result = RMS_ERROR;\r
+ result->reason = RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE;\r
+\r
+ for (auto const &it : requests) {\r
+ CRequest *req = it;\r
+ CResourceCategory *resource_category = CResourceDB::getInstance()->FindResourceCategory(req->GetCategory());\r
+\r
+ if (!resource_category) {\r
+ SERVER_ERR("not existing category(%d)! can't allocate a candidate", req->GetCategory());\r
+ continue;\r
+ }\r
+\r
+ CResource *resource = resource_category->ReserveCandidate(req, false);\r
+\r
+ if (!resource)\r
+ continue;\r
+\r
+ req->SetResult(RMS_OK);\r
+ req->SetCandidateDevice(resource->GetDeviceID());\r
+ result->result = RMS_OK;\r
+ break;\r
+ }\r
+\r
+ std::for_each(requests.begin(), requests.end(), [](CRequest *req) { if (req->GetResult()!= RMS_OK) return;\r
+ CResource *resource = CResourceDB::getInstance()->FindResource(req->GetCandidateDevice());\r
+ resource->CancelReservation((rms_requests_resource_state_e) req->GetState()); });\r
+\r
+ return (result->result == RMS_OK);\r
+}\r
+\r
+void CPreferenceModeStrategy::WriteAllocResult(rms_allocate_result_s *alloc_result, std::vector<CRequest *> requests, rms_return_device_s *allocated_devices)\r
+{\r
+ assert(allocated_devices);\r
+\r
+ allocated_devices->result = alloc_result->result;\r
+ allocated_devices->error_type = alloc_result->reason;\r
+\r
+ if (alloc_result->result != RMS_OK) {\r
+ allocated_devices->resources_num = 0;\r
+ return;\r
+ }\r
+\r
+ allocated_devices->resources_num = requests.size();\r
+ allocated_devices->device_ids = (int*) calloc(requests.size(), sizeof(int));\r
+ allocated_devices->devices = (rms_return_device_info_s*) calloc(requests.size(), sizeof(rms_return_device_info_s));\r
+\r
+ int i = 0;\r
+\r
+ for (auto const &it : requests) {\r
+ bool is_allocated = (it->GetResult() == RMS_OK);\r
+ int allocated_device_id = (is_allocated) ? it->GetAllocatedVirtualDevice() : RMS_DEVICE_NONE;\r
+\r
+ allocated_devices->device_ids[i] = allocated_device_id;\r
+ allocated_devices->devices[i].device_id = allocated_device_id;\r
+\r
+ if (!is_allocated) {\r
+ i++;\r
+ continue;\r
+ }\r
+\r
+ CResource *resource = CResourceDB::getInstance()->FindResource(it->GetAllocatedDevice());\r
+ assert(resource);\r
+\r
+ const char *path = resource->GetDevicePath();\r
+ allocated_devices->devices[i].device_path = strndup(path, strlen(path));\r
+ resource->SetAllocatedTime();\r
+ i++;\r
+ }\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <assert.h>\r
+\r
+#include <rms_debug.h>\r
+#include <CResource.h>\r
+#include <CVirtualResource.h>\r
+#include <CResourceDB.h>\r
+#include <CRequest.h>\r
+#include <CPriority.h>\r
+#include <CRequester.h>\r
+#include <CDependencyController.h>\r
+#include <CScalerStrategy.h>\r
+\r
+CScalerStrategy::CScalerStrategy()\r
+{\r
+}\r
+\r
+CScalerStrategy::~CScalerStrategy()\r
+{\r
+}\r
+\r
+void CScalerStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)\r
+{\r
+ CRequester *requester = req->getRequester();\r
+\r
+ if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle())) {\r
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
+ return;\r
+ }\r
+\r
+ if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)\r
+ return;\r
+\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+}\r
+\r
+CVirtualResource *CScalerStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)\r
+{\r
+ std::map<int, CVirtualResource *> filtered_vresources;\r
+ ExcludeResources(vresources, &filtered_vresources, req);\r
+\r
+ req->SetResult(RMS_ERROR);\r
+ req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);\r
+\r
+ for (auto const &it : filtered_vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+ int device_id = resource->GetDeviceID();\r
+\r
+ if (resource->IsReserved())\r
+ continue;\r
+\r
+ if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters())) {\r
+ updateReasonByMemCluster(vresource, req);\r
+ continue;\r
+ }\r
+\r
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
+ updateReasonByResourceState(device_id, req);\r
+ continue;\r
+ }\r
+\r
+ return vresource;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+int CScalerStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)\r
+{\r
+ CResource *rsc = vrsc->GetResource();\r
+\r
+ if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)\r
+ return RMS_ERROR;\r
+\r
+ rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());\r
+ return RMS_OK;\r
+}\r
+\r
+bool CScalerStrategy::ContainFreeResource(std::multimap<unsigned long, CVirtualResource *> vresources)\r
+{\r
+ for (auto const &it : vresources)\r
+ {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (resource->IsFreeState())\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+void CScalerStrategy::SelectConsumersByAllocationTime(std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)\r
+{\r
+ CResourceDB *db = CResourceDB::getInstance();\r
+ std::map<unsigned long, int> candidates_by_alloc_t; // allocation time, virtual resource id\r
+\r
+ for (auto const &it : *candidates) {\r
+ std::multimap<int, int> candidate = it.second;\r
+ for (auto const &itc : candidate) {\r
+ CResource *rsc = db->FindResource(itc.first);\r
+ candidates_by_alloc_t.insert(std::pair<unsigned long, int>(rsc->GetAllocatedTime(), it.first));\r
+ SERVER_INFO("vrsc(%d)/dev(%d:%ld)/cid(%d)", it.first, itc.first, rsc->GetAllocatedTime(), itc.second);\r
+ }\r
+ }\r
+\r
+ auto itf = candidates_by_alloc_t.begin();\r
+ if (itf == candidates_by_alloc_t.end()) {\r
+ SERVER_ERR("no candidate");\r
+ return;\r
+ }\r
+\r
+ auto const &ite = candidates->find(itf->second);\r
+ std::multimap<int, int> *elected = &ite->second;\r
+\r
+ result->insert(elected->begin(), elected->end());\r
+}\r
+\r
+void CScalerStrategy::SelectConsumersByZoneId(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)\r
+{\r
+ if (zone_id <= 0) {\r
+ SERVER_ERR("invalid zone id(%d)", zone_id);\r
+ return;\r
+ }\r
+\r
+ CResourceDB *db = CResourceDB::getInstance();\r
+\r
+ for (auto const &it : *candidates) {\r
+ std::multimap<int, int> candidate = it.second;\r
+ for (auto const &itc : candidate) {\r
+ CResource *rsc = db->FindResource(itc.first);\r
+ if (rsc->GetZoneId() == zone_id) {\r
+ SERVER_INFO("[%d] select (%d) > (%d:%d)", it.first, zone_id, itc.first, itc.second);\r
+ result->insert(candidate.begin(), candidate.end());\r
+ break;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+bool CScalerStrategy::ContainInterlacedNotSupportedApp(std::map<int, std::multimap<int, int>> *candidates)\r
+{\r
+ CResourceDB *db = CResourceDB::getInstance();\r
+\r
+ for (auto const &it : *candidates) {\r
+ std::multimap<int, int> candidate = it.second;\r
+ for (auto const &itc : candidate) {\r
+ CResource *rsc = db->FindResource(itc.first);\r
+ if (rsc->GetCurCategory() != RMS_CATEGORY_SCALER_INTERLACED)\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+}\r
+\r
+int CScalerStrategy::FindScalerInSameZone(int zone_id)\r
+{\r
+ std::map<int, CResource*> scalers;\r
+ CResourceDB::getInstance()->GetScalerList(&scalers);\r
+\r
+ for (auto const &it : scalers) {\r
+ CResource *rsc = it.second;\r
+ if (rsc->GetZoneId() == zone_id) {\r
+ SERVER_INFO("scaler in same zone(%d:%d:%d) found", zone_id, rsc->GetDeviceID(), rsc->GetVirtualDeviceId());\r
+ return rsc->GetDeviceID();\r
+ }\r
+ }\r
+ SERVER_INFO("scaler in same zone not found");\r
+ return -1;\r
+}\r
+\r
+int CScalerStrategy::FindScalerUsedByAppInterlacedNotSupported(std::map<int, std::multimap<int, int>> *candidates)\r
+{\r
+ CResourceDB *db = CResourceDB::getInstance();\r
+ for (auto const &it : *candidates) {\r
+ std::multimap<int, int> candidate = it.second;\r
+ for (auto const &itc : candidate) {\r
+ CResource *rsc = db->FindResource(itc.first);\r
+ if (rsc->GetCurCategory() == RMS_CATEGORY_SCALER_INTERLACED)\r
+ continue;\r
+ SERVER_INFO("scaler(%d:%d:%d) used by the app interlaced not supported found", rsc->GetCurCategory(), rsc->GetDeviceID(), rsc->GetVirtualDeviceId());\r
+ return rsc->GetDeviceID();\r
+ }\r
+ }\r
+ SERVER_INFO("scaler used by the app interlaced not supported not found");\r
+ return -1;\r
+}\r
+\r
+void CScalerStrategy::SelectConsumersBySwap(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)\r
+{\r
+ if (!ContainInterlacedNotSupportedApp(candidates)) {\r
+ SERVER_INFO("all scalers are being used by apps supporting interlaced");\r
+ return;\r
+ }\r
+\r
+ int scaler_id_sz = FindScalerInSameZone(zone_id);\r
+ if (scaler_id_sz < 0)\r
+ return;\r
+\r
+ int scaler_id_ins = FindScalerUsedByAppInterlacedNotSupported(candidates);\r
+ if (scaler_id_ins < 0)\r
+ return;\r
+\r
+ CResourceDB *db = CResourceDB::getInstance();\r
+ CResource *rsc_sz = db->FindResource(scaler_id_sz);\r
+ CResource *rsc_ins = db->FindResource(scaler_id_ins);\r
+\r
+ if (db->SwapScaler(rsc_sz->GetVirtualDeviceId(), rsc_ins->GetVirtualDeviceId()) < 0)\r
+ return;\r
+\r
+ db->UpdateVirtualScalerIds();\r
+\r
+ std::set<int> consumers = rsc_ins->GetConsumers();\r
+ for (auto const &it : consumers) {\r
+ SERVER_INFO("insert (%d:%d)", scaler_id_ins, it);\r
+ result->insert(std::pair<int, int>(scaler_id_ins, it));\r
+ }\r
+}\r
+\r
+void CScalerStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource*> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)\r
+{\r
+ std::multimap<int, int> consumer_list;\r
+ std::multimap<unsigned long, CVirtualResource *> filtered_vresources;\r
+ std::map<int, std::multimap<int, int>> candidates; // <vrsc id, <device id, consumer id>>\r
+\r
+ ExcludeResources(vresources, &filtered_vresources, req);\r
+\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+\r
+ for (auto const &it : filtered_vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+ SERVER_INFO("vrsc(%d)/rsc(%d)", vresource->GetVResourceID(), resource->GetDeviceID());\r
+\r
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters())) {\r
+ if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), req->getRequester()->getHandle(), &consumer_list) != RMS_OK) {\r
+ SERVER_ERR("failed to find reclaimable consumer vrsc(%d)/rsc(%d)", vresource->GetVResourceID(), resource->GetDeviceID());\r
+ };\r
+ }\r
+ if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), req->getRequester()->getHandle(), &consumer_list, err_type) == RMS_OK) {\r
+ candidates.insert(std::pair<int, std::multimap<int, int>>(vresource->GetVResourceID(), consumer_list));\r
+ consumer_list.clear();\r
+ }\r
+ }\r
+ SERVER_INFO("zone id : %d, candidates(%zu)", req->GetMultiviewZoneId(), candidates.size());\r
+ if (req->GetMultiviewZoneId() > 0)\r
+ SelectConsumersByZoneId(req->GetMultiviewZoneId(), &candidates, &consumer_list);\r
+\r
+ if (consumer_list.empty() && (req->GetCategory() == RMS_CATEGORY_SCALER_INTERLACED))\r
+ SelectConsumersBySwap(req->GetMultiviewZoneId(), &candidates, &consumer_list);\r
+\r
+ if (consumer_list.empty())\r
+ SelectConsumersByAllocationTime(&candidates, &consumer_list);\r
+\r
+ for (auto const &it : consumer_list)\r
+ retirables->insert(std::pair<int, int>(it.first, it.second));\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <assert.h>\r
+\r
+#include <ri-module-api.h>\r
+#include <rms_debug.h>\r
+#include <CResourceDB.h>\r
+#include <CBandwidth.h>\r
+#include <CResource.h>\r
+#include <CVirtualResource.h>\r
+#include <CRequest.h>\r
+#include <CRequester.h>\r
+#include <CPriority.h>\r
+#include <CDependencyController.h>\r
+#include <CAllocateStrategy.h>\r
+#include <CVideoDecoderStrategy.h>\r
+\r
+CVideoDecoderStrategy::CVideoDecoderStrategy()\r
+{\r
+ m_reclaim_policy_by_zone_id = ri_get_zone_id_based_reclaim_policy();\r
+}\r
+\r
+void CVideoDecoderStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)\r
+{\r
+ CRequester *requester = req->getRequester();\r
+\r
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+ return;\r
+ }\r
+\r
+ if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle())) {\r
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
+ return;\r
+ }\r
+\r
+ if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER)\r
+ return;\r
+\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+}\r
+\r
+void CVideoDecoderStrategy::updateReasonByBW(CVirtualResource *vresource, CRequest *req)\r
+{\r
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+ return;\r
+ }\r
+\r
+ rms_error_type_e reason = canReclaimRequiredBW(req, vresource->GetBW()) ?\r
+ RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER:RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;\r
+ req->SetReason(reason);\r
+}\r
+\r
+void CVideoDecoderStrategy::updateReasonByTripleDecoding(CRequest *req)\r
+{\r
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+ return;\r
+ }\r
+\r
+ rms_error_type_e reason = canReclaimActiveVideoDecoders(req) ?\r
+ RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER : RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;\r
+ req->SetReason(reason);\r
+}\r
+\r
+bool CVideoDecoderStrategy::isAllocatableResource(CVirtualResource *vresource, CRequest *req)\r
+{\r
+ CResource *resource = vresource->GetResource();\r
+ //int cat_id = vresource->GetCategoryType();\r
+ //int vid = vresource->GetVResourceID();\r
+ int device_id = resource->GetDeviceID();\r
+\r
+ //SERVER_INFO("> cat(%d)/vid(%d) device id(%d)", cat_id, vid, device_id);\r
+\r
+ if (resource->IsReserved()) {\r
+ SERVER_INFO("device id(%d) is reserved state", device_id);\r
+ return false;\r
+ }\r
+\r
+ if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters())) {\r
+ updateReasonByMemCluster(vresource, req);\r
+ return false;\r
+ }\r
+\r
+ CBandwidth *bandwidth = CBandwidth::GetInstance();\r
+\r
+ if (vresource->GetBW() > bandwidth->GetAvail()) {\r
+ SERVER_INFO("insufficient BW required(%d)/avail(%d)", vresource->GetBW(), bandwidth->GetAvail());\r
+ updateReasonByBW(vresource, req);\r
+ return false;\r
+ }\r
+\r
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
+ updateReasonByResourceState(device_id, req);\r
+ return false;\r
+ }\r
+\r
+ if (!CResourceDB::getInstance()->HasAvailableDecoder()) {\r
+ updateReasonByTripleDecoding(req);\r
+ return false;\r
+ }\r
+\r
+ //SERVER_INFO("> cat(%d)/vid(%d) device id(%d) allocatable", cat_id, vid, device_id);\r
+\r
+ return true;\r
+}\r
+\r
+CVirtualResource *CVideoDecoderStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)\r
+{\r
+ std::map<int, CVirtualResource*> filtered_vresources;\r
+ ExcludeResources(vresources, &filtered_vresources, req);\r
+\r
+ req->SetResult(RMS_ERROR);\r
+ req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);\r
+\r
+ for (auto const &it : filtered_vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+\r
+ if (!isAllocatableResource(vresource, req))\r
+ continue;\r
+\r
+ return vresource;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+int CVideoDecoderStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)\r
+{\r
+ CResource *rsc = vrsc->GetResource();\r
+\r
+ if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)\r
+ return RMS_ERROR;\r
+\r
+ rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());\r
+ return RMS_OK;\r
+}\r
+\r
+bool CVideoDecoderStrategy::ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources)\r
+{\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+ CBandwidth *bandwidth = CBandwidth::GetInstance();\r
+\r
+ for (auto const &it : vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters()))\r
+ continue;\r
+\r
+ if (bandwidth->GetAvail() < vresource->GetBW())\r
+ continue;\r
+\r
+ if (!resource->IsFreeState())\r
+ continue;\r
+\r
+ if (!CResourceDB::getInstance()->HasAvailableDecoder())\r
+ continue;\r
+\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+int CVideoDecoderStrategy::getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)\r
+{\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+ CResourceDB *resource_db = CResourceDB::getInstance();\r
+ CResource *resource = vresource->GetResource();\r
+ CBandwidth *bandwidth = CBandwidth::GetInstance();\r
+ int requester_id = req->getRequester()->getHandle();\r
+\r
+ SERVER_INFO(":: Get retirable consumers (%d:%d)", vresource->GetVResourceID(), resource->GetDeviceID());\r
+\r
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters())) {\r
+ SERVER_INFO("vrsc(%d)/rsc(%d)", vresource->GetVResourceID(), resource->GetDeviceID());\r
+ if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), requester_id, retirables) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ if ((bandwidth->GetAvail() + GetReclaimedBW(retirables)) < vresource->GetBW()) {\r
+ if (getConsumerUsingBW(req, vresource->GetBW(), retirables) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ if (!resource->IsFreeState()) {\r
+ if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), requester_id, retirables, err_type) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ if (!resource_db->HasAvailableDecoder(*retirables)) {\r
+ if (GetReclaimableVideoDecoderConsumers(requester_id, retirables, req, err_type) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ SERVER_WARN("RMS_OK");\r
+ return RMS_OK;\r
+\r
+error:\r
+ if (!retirables->empty())\r
+ retirables->clear();\r
+\r
+ return RMS_ERROR;\r
+}\r
+\r
+void CVideoDecoderStrategy::SelectInSameCategoryAndZone(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)\r
+{\r
+ CResourceDB *db = CResourceDB::getInstance();\r
+\r
+ for (auto const &it : *candidates) {\r
+ std::multimap<int, int> candidate = it.second;\r
+ for (auto const &itc : candidate) {\r
+ CResource *rsc = db->FindResource(itc.first);\r
+ if ((rsc->GetVirtualResourceID() == it.first) && (rsc->GetZoneId() == zone_id)) {\r
+ SERVER_INFO("[%d] select (%d) > (%d:%d)", it.first, zone_id, itc.first, itc.second);\r
+ result->insert(candidate.begin(), candidate.end());\r
+ return;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+int CVideoDecoderStrategy::GetConflictScore(int n_conflicts)\r
+{\r
+ return (10000 - n_conflicts);\r
+}\r
+\r
+void CVideoDecoderStrategy::SelectInSameZone(int zone_id, std::map<int, std::multimap<int, int>> candidates, std::multimap<int, int> *result)\r
+{\r
+ CResourceDB *db = CResourceDB::getInstance();\r
+ std::map<int, int> candidates_by_score;\r
+\r
+ for (auto const &it : candidates) {\r
+ std::multimap<int, int> candidate = it.second;\r
+ for (auto const &itc : candidate) {\r
+ CResource *rsc = db->FindResource(itc.first);\r
+ if (rsc->GetZoneId() != zone_id)\r
+ continue;\r
+\r
+ int score = GetConflictScore(candidate.size());\r
+ SERVER_INFO("insert (%d:%d) : score(%d) by (%d)", it.first, zone_id, score, itc.first);\r
+ candidates_by_score.insert(std::pair<int, int>(score, it.first));\r
+ }\r
+ }\r
+\r
+ if (candidates_by_score.empty())\r
+ return;\r
+\r
+ auto const top = candidates_by_score.rbegin();\r
+ auto const it = candidates.find(top->second);\r
+ if (it == candidates.end())\r
+ return;\r
+\r
+ std::multimap<int, int> selected = it->second;\r
+ SERVER_INFO("select (%d:%d)", top->second, zone_id);\r
+ result->insert(selected.begin(), selected.end());\r
+}\r
+\r
+void CVideoDecoderStrategy::SelectConsumersByZoneId(int zone_id, std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)\r
+{\r
+ if (zone_id <= 0) {\r
+ SERVER_ERR("invalid zone id(%d)", zone_id);\r
+ return;\r
+ }\r
+\r
+ SelectInSameCategoryAndZone(zone_id, candidates, result);\r
+\r
+ if (!result->empty())\r
+ return;\r
+\r
+ SelectInSameZone(zone_id, *candidates, result);\r
+}\r
+\r
+void CVideoDecoderStrategy::SelectConsumersByAllocationTime(std::map<int, std::multimap<int, int>> *candidates, std::multimap<int, int> *result)\r
+{\r
+ CResourceDB *db = CResourceDB::getInstance();\r
+ std::map<unsigned long, int> candidates_by_alloc_t; // allocation time, virtual resource id\r
+\r
+ std::map<int, int> conflicts; //virtual resource id, n conflicts\r
+ int n_conflicts = 0;\r
+ for (auto const &itn : *candidates) {\r
+ std::multimap<int, int> candidate = itn.second;\r
+ n_conflicts = candidate.size();\r
+ if (n_conflicts > 0) {\r
+ SERVER_INFO("vrsc(%d)/conflicts(%d)", itn.first, n_conflicts);\r
+ conflicts.insert(std::pair<int, int>(itn.first, n_conflicts));\r
+ }\r
+ }\r
+\r
+ bool inserted = false;\r
+\r
+ for (auto const &it : *candidates) {\r
+ std::multimap<int, int> candidate = it.second;\r
+ n_conflicts = candidate.size();\r
+ for (auto const &itc : candidate) {\r
+ CResource *rsc = db->FindResource(itc.first);\r
+ unsigned long alloc_t = rsc->GetAllocatedTime();\r
+ SERVER_INFO("insert vrsc(%d)/dev(%d:%ld)/cid(%d)", it.first, itc.first, rsc->GetAllocatedTime(), itc.second);\r
+ inserted = candidates_by_alloc_t.insert(std::pair<unsigned long, int>(alloc_t, it.first)).second;\r
+ if (!inserted) {\r
+ SERVER_INFO("t:%ld already in it", alloc_t);\r
+ auto const &cur = candidates_by_alloc_t.find(alloc_t);\r
+ if (cur == candidates_by_alloc_t.end())\r
+ continue;\r
+\r
+ auto const &n = conflicts.find(cur->second);\r
+ if (n == conflicts.end())\r
+ continue;\r
+\r
+ int cur_conflicts = n->second;\r
+ SERVER_INFO("cur_conflicts(%d)/n_conflicts(%d)", cur_conflicts, n_conflicts);\r
+ if (cur_conflicts > n_conflicts) {\r
+ candidates_by_alloc_t.erase(rsc->GetAllocatedTime());\r
+ SERVER_INFO("insert vrsc(%d)/dev(%d:%ld)/cid(%d)", it.first, itc.first, rsc->GetAllocatedTime(), itc.second);\r
+ candidates_by_alloc_t.insert(std::pair<unsigned long, int>(rsc->GetAllocatedTime(), it.first));\r
+ }\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ auto itf = candidates_by_alloc_t.begin();\r
+ if (itf == candidates_by_alloc_t.end()) {\r
+ SERVER_ERR("no candidate");\r
+ return;\r
+ }\r
+\r
+ auto const &ite = candidates->find(itf->second);\r
+ std::multimap<int, int> *elected = &ite->second;\r
+\r
+ result->insert(elected->begin(), elected->end());\r
+}\r
+\r
+void CVideoDecoderStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)\r
+{\r
+ std::multimap<int, int> consumer_list;\r
+ std::multimap<unsigned long, CVirtualResource *> filtered_vresources;\r
+ std::map<int, std::multimap<int, int>> candidates;\r
+\r
+ ExcludeResources(vresources, &filtered_vresources, req);\r
+\r
+ if (ContainAvailableResource(filtered_vresources))\r
+ return;\r
+\r
+ for (auto const &it : filtered_vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+\r
+ if (getRetirableConsumersExclusive(vresource, req, &consumer_list, err_type) == RMS_OK) {\r
+ candidates.insert(std::pair<int, std::multimap<int, int>>(vresource->GetVResourceID(), consumer_list));\r
+ consumer_list.clear();\r
+ }\r
+ }\r
+\r
+ if (m_reclaim_policy_by_zone_id && req->GetMultiviewZoneId() > 0)\r
+ SelectConsumersByZoneId(req->GetMultiviewZoneId(), &candidates, &consumer_list);\r
+\r
+ if (consumer_list.empty())\r
+ SelectConsumersByAllocationTime(&candidates, &consumer_list);\r
+\r
+ for (auto const &it : consumer_list)\r
+ retirables->insert(std::pair<int, int>(it.first, it.second));\r
+}\r
+\r
+bool CVideoDecoderStrategy::canReclaimRequiredBW(CRequest *req, unsigned int bw)\r
+{\r
+ CRequester *requester = req->getRequester();\r
+ CResourceDB *resource_db = CResourceDB::getInstance();\r
+ CBandwidth *bandwidth = CBandwidth::GetInstance();\r
+ unsigned int reclaimed_bw = bandwidth->GetAvail();\r
+ std::map<int, int> bw_consumers = bandwidth->GetConsumers();\r
+\r
+ for (std::map<int, int>::iterator it = bw_consumers.begin(); it != bw_consumers.end(); it++) {\r
+ int device_id = (*it).first;\r
+ int consumer_id = (*it).second;\r
+\r
+ CResource *pRsc = resource_db->FindResource(device_id);\r
+\r
+ if (!pRsc) {\r
+ SERVER_ERR("cannot find resource using device id");\r
+ continue;\r
+ }\r
+\r
+ if (requester->getHandle() == consumer_id) {\r
+ SERVER_INFO("CID[%d] is using BW (%d)", requester->getHandle(), pRsc->GetBW());\r
+ continue;\r
+ }\r
+\r
+ if (CPriority::compare(consumer_id, requester->getHandle()) != HIGH_PRIORITY)\r
+ continue;\r
+\r
+ reclaimed_bw += pRsc->GetBW();\r
+\r
+ if (bw <= reclaimed_bw)\r
+ break;\r
+\r
+ SERVER_INFO("DevID[%d] / need more resource to be released!!! required BW(%d)-resource BW(%d)-check(%d)", pRsc->GetDeviceID(), bw, pRsc->GetBW(), reclaimed_bw);\r
+ }\r
+\r
+ SERVER_INFO("required BW(%d) - available (%d)", bw, reclaimed_bw);\r
+\r
+ return (bw <= reclaimed_bw);\r
+\r
+}\r
+\r
+void CVideoDecoderStrategy::SelectDevicesByMainSub(CRequest *req, std::map<int, int> *src, std::map<int, int> *result)\r
+{\r
+ CResourceDB *db = CResourceDB::getInstance();\r
+\r
+ for (auto const &it : *src) {\r
+ CResource *rsc = db->FindResource(it.first);\r
+ if (!rsc)\r
+ continue;\r
+ if (req->IsMainDeviceRequest() && !rsc->IsMainDevice())\r
+ continue;\r
+ if (req->IsSubDeviceRequest() && rsc->IsMainDevice())\r
+ continue;\r
+\r
+ result->insert(std::pair<int, int>(it.first, it.second));\r
+ }\r
+}\r
+\r
+int CVideoDecoderStrategy::getConsumerUsingBW(CRequest *req, unsigned int bw, std::multimap<int, int> *return_ids)\r
+{\r
+ std::map<int, int> candidates;\r
+ std::map<int, int> cur_consumers = CBandwidth::GetInstance()->GetConsumers(); //device id, consumer id\r
+\r
+ SelectDevicesByMainSub(req, &cur_consumers, &candidates);\r
+\r
+ std::multimap<int, int> reclaimed_by_ms;\r
+ unsigned int avail_bw = GetConsumerUsingBWByAllocationTime(req->getRequester()->getHandle(), bw, candidates, &reclaimed_by_ms);\r
+\r
+ if (avail_bw >= bw) {\r
+ return_ids->insert(reclaimed_by_ms.begin(), reclaimed_by_ms.end());\r
+ return RMS_OK;\r
+ }\r
+\r
+ std::multimap<int, int> reclaimed_by_t;\r
+ GetConsumerUsingBWByAllocationTime(req->getRequester()->getHandle(), bw, cur_consumers, &reclaimed_by_t);\r
+ return_ids->insert(reclaimed_by_t.begin(), reclaimed_by_t.end());\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+int CVideoDecoderStrategy::GetConsumerUsingBWByAllocationTime(int requester_id, unsigned int required_bw, std::map<int, int> bw_consumers, std::multimap<int, int> *reclaimed_consumers)\r
+{\r
+ assert(reclaimed_consumers);\r
+\r
+ CResourceDB *resource_db = CResourceDB::getInstance();\r
+ CBandwidth *bandwidth = CBandwidth::GetInstance();\r
+\r
+ SERVER_INFO("candidates using BW : %zu", bw_consumers.size());\r
+ unsigned int reclaimed_bw = bandwidth->GetAvail();\r
+\r
+ std::map<unsigned long, int> consumers_by_t;\r
+ for (auto const &itc : bw_consumers) {\r
+ CResource *rsc = resource_db->FindResource(itc.first);\r
+ if (!rsc)\r
+ continue;\r
+\r
+ consumers_by_t.insert(std::pair<unsigned long, int>(rsc->GetAllocatedTime(), itc.first));\r
+ }\r
+\r
+ for (auto const &it : consumers_by_t) {\r
+ int device_id = it.second;\r
+ CResource *pRsc = resource_db->FindResource(device_id);\r
+ if (!pRsc)\r
+ continue;\r
+\r
+ int consumer_id = pRsc->GetFirstConsumer();\r
+ SERVER_INFO("consumer (%d) is using bw for device (%d)", consumer_id, device_id);\r
+\r
+ if (requester_id == consumer_id) {\r
+ SERVER_INFO("CID[%d] is using BW (%d)", requester_id, pRsc->GetBW());\r
+ continue;\r
+ }\r
+\r
+ if (CPriority::compare(consumer_id, requester_id) != HIGH_PRIORITY)\r
+ continue;\r
+\r
+ auto ret = reclaimed_consumers->find(device_id);\r
+ if (ret != reclaimed_consumers->end()) {\r
+ SERVER_INFO("(%d:%d) already inserted", device_id, consumer_id);\r
+ continue;\r
+ }\r
+\r
+ reclaimed_consumers->insert(std::pair<int, int>(device_id, consumer_id));\r
+\r
+ if (pRsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) {\r
+ std::map<int, int> siblings;\r
+ bandwidth->GetConsumersNDec(pRsc->GetCurCategory(), &siblings);\r
+ if (siblings.size() > 0) {\r
+ SERVER_INFO("insert n-dec siblings(%zu)", siblings.size());\r
+ reclaimed_consumers->insert(siblings.begin(), siblings.end());\r
+ }\r
+ }\r
+\r
+ reclaimed_bw += pRsc->GetBW();\r
+\r
+ if (required_bw <= reclaimed_bw)\r
+ break;\r
+ SERVER_INFO("DevID[%d]/ need more BW! required:(%d)-resource(%d)-reclaimed(%d)", pRsc->GetDeviceID(), required_bw, pRsc->GetBW(), reclaimed_bw);\r
+ }\r
+\r
+ return reclaimed_bw;\r
+}\r
+\r
+bool CVideoDecoderStrategy::canReclaimActiveVideoDecoders(CRequest *req)\r
+{\r
+ CRequester *requester = req->getRequester();\r
+ CResourceDB *resource_db = CResourceDB::getInstance();\r
+ std::map<int, int> active_vdecs = resource_db->GetActiveVideoDecoders();\r
+\r
+ for (auto const &it : active_vdecs) {\r
+ int dev_id = it.first;\r
+ int cid = it.second;\r
+\r
+ CResource *rsc = resource_db->FindResource(dev_id);\r
+\r
+ if (!rsc) {\r
+ SERVER_ERR("can't find resource (%d)", dev_id);\r
+ continue;\r
+ }\r
+\r
+ if (requester->getHandle() == cid) {\r
+ SERVER_INFO("CID[%d] is using device (%d)", cid, dev_id);\r
+ continue;\r
+ }\r
+\r
+ if (CPriority::compare(cid, requester->getHandle()) == HIGH_PRIORITY)\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+\r
+}\r
+\r
+int CVideoDecoderStrategy::GetReclaimableVideoDecoderConsumers(int consumer_id, std::multimap<int, int>* reclaimables, CRequest *req, rms_error_type_e *err_type)\r
+{\r
+ std::map<unsigned long, CResource*> rscs;\r
+ CResource *rsc = NULL;\r
+ CResourceDB *db = CResourceDB::getInstance();\r
+ std::map<int, int> active_vdecs = db->GetActiveVideoDecoders();\r
+ bool has_main_vdec = false;\r
+ bool has_sub_vdec = false;\r
+\r
+ for (auto const &it_vdec : active_vdecs) {\r
+ rsc = db->FindResource(it_vdec.first);\r
+ rscs.insert(std::pair<unsigned long, CResource*>(rsc->GetAllocatedTime(), rsc));\r
+\r
+ if (rsc->IsMainDevice())\r
+ has_main_vdec = true;\r
+ else\r
+ has_sub_vdec = true;\r
+ }\r
+\r
+ for (auto const &it : rscs) {\r
+ rsc = it.second;\r
+\r
+ if (req->IsMainDeviceRequest() && has_main_vdec && !rsc->IsMainDevice())\r
+ continue;\r
+ if (req->IsSubDeviceRequest() && has_sub_vdec && rsc->IsMainDevice())\r
+ continue;\r
+\r
+ if (CPriority::getReclaimableConsumers(rsc->GetDeviceID(), consumer_id, reclaimables, err_type) == RMS_OK) {\r
+ if (rsc->GetCategoryClass() == RMS_CATEGORY_CLASS_N_DECODING) {\r
+ std::map<int, int> active_ndecs = db->GetActiveNVideoDecoders();\r
+ reclaimables->insert(active_ndecs.begin(), active_ndecs.end());\r
+ }\r
+ return RMS_OK;\r
+ }\r
+ }\r
+\r
+ return RMS_ERROR;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <assert.h>\r
+\r
+#include <rms_debug.h>\r
+#include <CResourceDB.h>\r
+#include <CResource.h>\r
+#include <CVirtualResource.h>\r
+#include <CRequest.h>\r
+#include <CRequester.h>\r
+#include <CPriority.h>\r
+#include <CDependencyController.h>\r
+#include <CAllocateStrategy.h>\r
+#include <CVideoEncoderExclusiveStrategy.h>\r
+\r
+void CVideoEncoderExclusiveStrategy::updateReasonByMemCluster(CVirtualResource *vresource, CRequest *req)\r
+{\r
+ CRequester *requester = req->getRequester();\r
+\r
+ if (req->GetState() == RMS_STATE_EXCLUSIVE_CONDITIONAL) {\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+ return;\r
+ }\r
+\r
+ if (CDependencyController::getInstance()->canReclaimMemClusters(vresource->GetMemClusters(), requester->getHandle(), requester->getAppId())) {\r
+ SERVER_ERR("canReclaimMemClusters is failed");\r
+ req->SetReason(RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER);\r
+ return;\r
+ }\r
+\r
+ if (req->GetReason() == RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER) {\r
+ SERVER_ERR("RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER");\r
+ return;\r
+ }\r
+\r
+ req->SetReason(RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS);\r
+}\r
+\r
+bool CVideoEncoderExclusiveStrategy::isAllocatableResource(CVirtualResource *vresource, CRequest *req)\r
+{\r
+ CResource *resource = vresource->GetResource();\r
+ CRequester *requester = req->getRequester();\r
+\r
+ if (resource->IsReserved()) {\r
+ SERVER_ERR("device id(%d) is reserved state", resource->GetDeviceID());\r
+ return false;\r
+ }\r
+\r
+ if (!CDependencyController::getInstance()->isAvailableMemClusters(vresource->GetMemClusters(), requester->getAppId())) {\r
+ SERVER_ERR("isAvailableMemClusters is failed");\r
+ updateReasonByMemCluster(vresource, req);\r
+ return false;\r
+ }\r
+\r
+ if (!resource->IsAllocatableState((rms_requests_resource_state_e) req->GetState())) {\r
+ SERVER_ERR("IsAllocatableState is failed");\r
+ updateReasonByResourceState(resource->GetDeviceID(), req);\r
+ return false;\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+CVirtualResource *CVideoEncoderExclusiveStrategy::findCandidate(std::map<int, CVirtualResource *> vresources, CRequest *req)\r
+{\r
+ std::map<int, CVirtualResource *> filtered_vresources;\r
+ ExcludeResources(vresources, &filtered_vresources, req);\r
+\r
+ req->SetResult(RMS_ERROR);\r
+ req->SetReason(RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE);\r
+\r
+ for (auto const &it : filtered_vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ if (!isAllocatableResource(vresource, req))\r
+ continue;\r
+\r
+ return vresource;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+int CVideoEncoderExclusiveStrategy::reserveResource(CVirtualResource *vrsc, CRequest *req)\r
+{\r
+ CResource *rsc = vrsc->GetResource();\r
+\r
+ if (rsc->Reserve(req->getRequester()->getHandle(), req->GetState()) != RMS_OK)\r
+ return RMS_ERROR;\r
+\r
+ rsc->UpdateProperties(vrsc->GetMemClusters(), vrsc->GetBW(), vrsc->GetCategoryType(), vrsc->GetCategoryClass(), vrsc->GetVResourceID());\r
+\r
+ return RMS_OK;\r
+}\r
+\r
+bool CVideoEncoderExclusiveStrategy::ContainAvailableResource(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req)\r
+{\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+ CRequester *requester = req->getRequester();\r
+\r
+ for (auto const &it : vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ CResource *resource = vresource->GetResource();\r
+\r
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters(), requester->getAppId()))\r
+ continue;\r
+\r
+ if (!resource->IsFreeState())\r
+ continue;\r
+\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+int CVideoEncoderExclusiveStrategy::getRetirableConsumersExclusive(CVirtualResource *vresource, CRequest *req, std::multimap<int, int> *retirables, rms_error_type_e *err_type)\r
+{\r
+ CDependencyController *dc = CDependencyController::getInstance();\r
+ CResource *resource = vresource->GetResource();\r
+ CRequester *requester = req->getRequester();\r
+\r
+ if (!requester) {\r
+ SERVER_ERR("can't find requester");\r
+ goto error;\r
+ }\r
+\r
+ if (!dc->isAvailableMemClusters(vresource->GetMemClusters(), requester->getAppId())) {\r
+ if (dc->getReclaimableMemClusterConsumers(vresource->GetMemClusters(), req->getRequester()->getHandle(), retirables, requester->getAppId()) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ if (!resource->IsFreeState()) {\r
+ if (CPriority::getReclaimableConsumers(resource->GetDeviceID(), req->getRequester()->getHandle(), retirables, err_type) != RMS_OK)\r
+ goto error;\r
+ }\r
+\r
+ return RMS_OK;\r
+\r
+error:\r
+ if (!retirables->empty())\r
+ retirables->clear();\r
+\r
+ return RMS_ERROR;\r
+}\r
+\r
+void CVideoEncoderExclusiveStrategy::GetRetirableConsumers(std::multimap<unsigned long, CVirtualResource *> vresources, CRequest *req, std::multimap<int, int>* retirables, rms_error_type_e *err_type)\r
+{\r
+ std::multimap<int, int> consumer_list;\r
+ std::multimap<unsigned long, CVirtualResource *> filtered_vresources;\r
+\r
+ ExcludeResources(vresources, &filtered_vresources, req);\r
+\r
+ bool hasAllocatableResource = ContainAvailableResource(filtered_vresources, req);\r
+ if (hasAllocatableResource)\r
+ return;\r
+\r
+ for (auto const &it : filtered_vresources) {\r
+ CVirtualResource *vresource = it.second;\r
+ if (getRetirableConsumersExclusive(vresource, req, &consumer_list, err_type) == RMS_OK)\r
+ break;\r
+ }\r
+\r
+ for (auto const &it : consumer_list) {\r
+ retirables->insert(std::pair<int, int>(it.first, it.second));\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <trace.h>\r
+#include <rms_debug.h>\r
+#include <CResourceService.h>\r
+\r
+#include <iostream>\r
+\r
+int main(void)\r
+{\r
+ SERVER_INFO("RscMgr server main loop\n");\r
+ trace_begin("[RSC_MGR] main start");\r
+ trace_end();\r
+\r
+ GMainLoop *main_loop;\r
+ main_loop = g_main_loop_new(NULL, FALSE);\r
+\r
+ if (!main_loop) {\r
+ SERVER_ERR("failed to create a main loop\n");\r
+ return 0;\r
+ }\r
+\r
+ CResourceService *service = new(std::nothrow) CResourceService;\r
+ service->Init(main_loop);\r
+\r
+ g_main_loop_ref(main_loop);\r
+ g_main_loop_run(main_loop);\r
+\r
+ return 0;\r
+}\r