Add TPA cache to reduce application startup time.
authorWoongsuk Cho <ws77.cho@samsung.com>
Wed, 13 Feb 2019 06:29:49 +0000 (15:29 +0900)
committer이형주/Common Platform Lab(SR)/Staff Engineer/삼성전자 <leee.lee@samsung.com>
Wed, 10 Apr 2019 00:36:49 +0000 (09:36 +0900)
It takes a lot of time to configure the TPA through file I/O
in the case of an application launching as standalone while device booting (like VD CSFS application).

To avoid this kind of overhead, add tool to create TPA cache and modify path_manager to get TPA list.

NativeLauncher/CMakeLists.txt
NativeLauncher/inc/plugin_manager.h
NativeLauncher/installer-plugin/tpatool.cc [new file with mode: 0644]
NativeLauncher/util/path_manager.cc
NativeLauncher/util/plugin_manager.cc
packaging/dotnet-launcher.spec

index 5b98b24..ec16431 100644 (file)
@@ -106,6 +106,14 @@ ADD_EXECUTABLE(${NITOOL} ${${NITOOL}_SOURCE_FILES})
 SET_TARGET_PROPERTIES(${NITOOL} PROPERTIES COMPILE_FLAGS "-fPIE")
 TARGET_LINK_LIBRARIES(${NITOOL} ${${PROJECT_NAME}_LDFLAGS} "-pie" ${DOTNET_LAUNCHER_UTIL} ${NI_COMMON})
 
+SET(TPATOOL "tpatool")
+SET(${TPATOOL}_SOURCE_FILES
+    installer-plugin/tpatool.cc
+)
+ADD_EXECUTABLE(${TPATOOL} ${${TPATOOL}_SOURCE_FILES})
+SET_TARGET_PROPERTIES(${TPATOOL} PROPERTIES COMPILE_FLAGS "-fPIE")
+TARGET_LINK_LIBRARIES(${TPATOOL} ${${PROJECT_NAME}_LDFLAGS} "-pie" ${DOTNET_LAUNCHER_UTIL})
+
 #SET(INSTALLER_PLUGIN "ui-application")
 #SET(${INSTALLER_PLUGIN}_SOURCE_FILES
 #    util/utils.cc
@@ -131,6 +139,7 @@ INSTALL(TARGETS ${DOTNET_LAUNCHER_UTIL} DESTINATION ${LIBDIR})
 INSTALL(TARGETS ${DOTNET_LAUNCHER} DESTINATION ${BINDIR})
 INSTALL(TARGETS ${NI_COMMON} DESTINATION ${LIBDIR})
 INSTALL(TARGETS ${NITOOL} DESTINATION ${BINDIR})
+INSTALL(TARGETS ${TPATOOL} DESTINATION ${BINDIR})
 #INSTALL(TARGETS ${INSTALLER_PLUGIN} DESTINATION ${INSTALL_PLUGIN_DIR})
 INSTALL(TARGETS ${PREFER_DOTNET_AOT_PLUGIN} DESTINATION ${INSTALL_MDPLUGIN_DIR})
 INSTALL(FILES dotnet.loader DESTINATION ${LOADERDIR})
index 534e0f8..2a8ff56 100644 (file)
@@ -30,6 +30,7 @@ typedef void (*plugin_set_coreclr_info_ptr)(
                        unsigned int domainId,
                        coreclr_create_delegate_ptr delegateFunc);
 typedef char* (*plugin_get_dll_path_ptr)();
+typedef char* (*plugin_get_tpa_ptr)();
 typedef void (*plugin_before_execute_ptr)();
 typedef void (*plugin_finalize_ptr)();
 
@@ -40,6 +41,7 @@ typedef struct PluginFunc {
        plugin_set_app_info_ptr set_app_info;
        plugin_set_coreclr_info_ptr set_coreclr_info;
        plugin_get_dll_path_ptr get_dll_path;
+       plugin_get_tpa_ptr get_tpa;
        plugin_before_execute_ptr before_execute;
        plugin_finalize_ptr finalize;
 } PluginFunc;
@@ -50,6 +52,7 @@ bool pluginHasLogControl();
 void pluginSetAppInfo(const char* appId, const char* managedAssemblyPath);
 void pluginSetCoreclrInfo(void* hostHandle, unsigned int domainId, coreclr_create_delegate_ptr delegateFunc);
 char* pluginGetDllPath();
+char* pluginGetTPA();
 void pluginBeforeExecute();
 void pluginFinalize();
 
diff --git a/NativeLauncher/installer-plugin/tpatool.cc b/NativeLauncher/installer-plugin/tpatool.cc
new file mode 100644 (file)
index 0000000..834eb14
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 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 <fstream>
+#include <string>
+#include <iostream>
+
+#include "utils.h"
+
+const char* __RUNTIME_DIR = "/usr/share/dotnet.tizen/netcoreapp";
+const char* __TIZENFX_DIR = "/usr/share/dotnet.tizen/framework";
+const char* __TIZENFX_REF_DIR = "/usr/share/dotnet.tizen/framework/ref";
+const char* __PLATFORM_TPA_CACHE = "/usr/share/dotnet.tizen/lib/platform_tpa_cache";
+
+int main(int argc, char* argv[])
+{
+    std::string tpaList;
+    std::vector<std::string> tpaDir;
+
+    tpaDir.push_back(__RUNTIME_DIR);
+    tpaDir.push_back(__TIZENFX_DIR);
+    tpaDir.push_back(__TIZENFX_REF_DIR);
+
+    assembliesInDirectory(tpaDir, tpaList);
+
+    std::ofstream out(__PLATFORM_TPA_CACHE);
+    out << tpaList;
+    out.close();
+    
+    return 0;
+}
+
index 1da1a65..8644bf0 100644 (file)
 #include <iterator>
 #include <sstream>
 #include <vconf.h>
+#include <fstream>
 
 #include "utils.h"
 #include "plugin_manager.h"
 #include "log.h"
 
 static const char* __TIZEN_API_PATH_KEY = "db/dotnet/tizen_api_path";
+static const char* PLATFORM_TPA_CACHE = "/usr/share/dotnet.tizen/lib/platform_tpa_cache";
 
 #define __XSTR(x) #x
 #define __STR(x) __XSTR(x)
@@ -114,23 +116,44 @@ std::vector <std::string> getExtraDirs()
        return __dllPath->extra_dirs;
 }
 
+static std::string getPlatformTPA()
+{
+       std::string platform_tpa;
+
+       if (isFileExist(PLATFORM_TPA_CACHE)) {
+               _INFO("platform tpa cache found.\n");
+               std::ifstream cacheFile;
+               cacheFile.open(PLATFORM_TPA_CACHE);
+               std::getline(cacheFile, platform_tpa);
+               cacheFile.close();
+       } else {
+               std::vector<std::string> tpaDir;
+               tpaDir.push_back(getRuntimeDir());
+               tpaDir.push_back(getTizenFXDir());
+               tpaDir.push_back(getTizenFXRefDir());
+               assembliesInDirectory(tpaDir, platform_tpa);
+       }
+
+       return platform_tpa;
+}
+
 std::string getTPA()
 {
        if (!__tpa.empty()) {
                return __tpa;
        }
 
-       std::vector<std::string> tpaDir;
-
        if (__dllPath == NULL) {
                return std::string("");
        }
 
-       tpaDir.push_back(getRuntimeDir());
-       tpaDir.push_back(getTizenFXDir());
-       tpaDir.push_back(getTizenFXRefDir());
-       tpaDir.insert(tpaDir.end(), __dllPath->extra_dirs.begin(), __dllPath->extra_dirs.end());
-       assembliesInDirectory(tpaDir, __tpa);
+       __tpa = getPlatformTPA();
+
+       char* pluginTPA = pluginGetTPA();
+       if (pluginTPA) {
+               _INFO("plugin tpa found.\n");
+               __tpa = __tpa + ":" + pluginTPA;
+       }
 
        return __tpa;
 }
index 44b401d..0ceffec 100644 (file)
@@ -40,6 +40,7 @@ int initializePluginManager(const char* mode)
                        __pluginFunc->set_app_info = (plugin_set_app_info_ptr)dlsym(__pluginLib, "plugin_set_app_info");
                        __pluginFunc->set_coreclr_info = (plugin_set_coreclr_info_ptr)dlsym(__pluginLib, "plugin_set_coreclr_info");
                        __pluginFunc->get_dll_path = (plugin_get_dll_path_ptr)dlsym(__pluginLib, "plugin_get_dll_path");
+                       __pluginFunc->get_tpa = (plugin_get_tpa_ptr)dlsym(__pluginLib, "plugin_get_tpa");
                        __pluginFunc->before_execute = (plugin_before_execute_ptr)dlsym(__pluginLib, "plugin_before_execute");
                        __pluginFunc->finalize  = (plugin_finalize_ptr)dlsym(__pluginLib, "plugin_finalize");
                }
@@ -106,6 +107,15 @@ char* pluginGetDllPath()
        }
 }
 
+char* pluginGetTPA()
+{
+       if (__pluginFunc && __pluginFunc->get_tpa) {
+               return __pluginFunc->get_tpa();
+       } else {
+               return NULL;
+       }
+}
+
 void pluginBeforeExecute()
 {
        if (__pluginFunc && __pluginFunc->before_execute) {
index 3afa960..a073f42 100644 (file)
@@ -116,6 +116,7 @@ chsmack -t -a User::App::Shared /opt/etc/skel/.dotnet
 %{_loaderdir}/dotnet.debugger
 %{_native_lib_dir}/libsqlite3.so
 %{_bindir}/nitool
+%{_bindir}/tpatool
 %{_install_mdplugin_dir}/libprefer_dotnet_aot_plugin.so
 %{_bindir}/dotnet-launcher
 %{_libdir}/libdotnet_launcher_util.so