From ac952532bac864e145498a0cc724d84a67339ac0 Mon Sep 17 00:00:00 2001 From: "pius.lee" Date: Wed, 30 Nov 2016 18:22:11 +0900 Subject: [PATCH 01/16] Fix unused native image in application. Now launcher use Native image in application's bin, lib directory. --native option is added to dotnet-launcher. It must be use with --standalone. --native launch dll without managed launcher. But it can't launch ni.dll. Change-Id: Icf0ab0e9330ec1e94db5440e517e76710f1d81e1 --- NativeLauncher/launcher/dotnet/dotnet_launcher.cc | 12 ++++++++++++ NativeLauncher/launcher/main.cc | 18 ++++++++++++++++++ Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs | 11 ++++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/NativeLauncher/launcher/dotnet/dotnet_launcher.cc b/NativeLauncher/launcher/dotnet/dotnet_launcher.cc index 509248d..cb9fcd0 100644 --- a/NativeLauncher/launcher/dotnet/dotnet_launcher.cc +++ b/NativeLauncher/launcher/dotnet/dotnet_launcher.cc @@ -277,6 +277,18 @@ int CoreRuntime::Launch(const char* root, const char* path, int argc, char* argv return 1; } + std::string cpppath(path); + + if (IsManagedAssembly(cpppath) && !IsNativeImage(cpppath)) + { + size_t extindex = cpppath.size() - 4; + cpppath = cpppath.substr(0, extindex) + ".ni" + cpppath.substr(extindex, 4); + if (!FileNotExist(cpppath)) + { + path = cpppath.c_str(); + } + } + if (FileNotExist(path)) { _ERR("File not exist : %s", path); diff --git a/NativeLauncher/launcher/main.cc b/NativeLauncher/launcher/main.cc index 3d574ec..314e719 100644 --- a/NativeLauncher/launcher/main.cc +++ b/NativeLauncher/launcher/main.cc @@ -38,12 +38,14 @@ static std::string VersionOption("--version"); static std::string StandaloneOption("--standalone"); +static std::string NativeOption("--native"); int main(int argc, char *argv[]) { int i; bool standalone = false; const char* standalonePath = nullptr; + bool nativeOnly = false; std::vector vargs; @@ -66,12 +68,22 @@ int main(int argc, char *argv[]) i++; standalonePath = argv[i]; } + else if (NativeOption.compare(argv[i]) == 0) + { + nativeOnly = true; + } else { vargs.push_back(argv[i]); } } + if (!standalone && nativeOnly) + { + fprintf(stderr, "\"--native\" option must be use with \"--standalone\"\n"); + return 1; + } + using tizen::runtime::LauncherInterface; using tizen::runtime::Launchpad; using tizen::runtime::AppInfo; @@ -120,6 +132,12 @@ int main(int argc, char *argv[]) return 1; } + if (!nativeOnly && runtime->RunManagedLauncher() != 0) + { + _ERR("Failed to run managed launcher"); + return 1; + } + int args_len = vargs.size(); char** args = &vargs[0]; if (runtime->Launch(approot.c_str(), standalonePath, args_len, args)) diff --git a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs index ea31f8f..26b8868 100644 --- a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs +++ b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs @@ -165,7 +165,16 @@ namespace Tizen.Runtime.Coreclr FileInfo f = new FileInfo(dllPath); if (File.Exists(f.FullName)) { - Assembly asm = CurrentAssemblyLoaderContext.LoadFromAssemblyPath(f.FullName); + Assembly asm = null; + if (0 == string.Compare(f.FullName, f.FullName.Length - 7, ".ni", 0, 3, StringComparison.OrdinalIgnoreCase)) + { + asm = CurrentAssemblyLoaderContext.LoadFromNativeImagePath(f.FullName, null); + } + else + { + asm = CurrentAssemblyLoaderContext.LoadFromAssemblyPath(f.FullName); + } + if (asm == null) throw new FileNotFoundException($"{f.FullName} is not found"); if (asm.EntryPoint == null) throw new ArgumentException($"{f.FullName} did not have EntryPoint"); asm.EntryPoint.Invoke(null, new object[]{argv}); -- 2.7.4 From af016aa0f9cf9e442f0d122d933875c54e258a77 Mon Sep 17 00:00:00 2001 From: "pius.lee" Date: Thu, 24 Nov 2016 11:16:25 +0900 Subject: [PATCH 02/16] Fix Preload DLL Use LoadFromNativeImagePath for ni dlls. Change directory to text file for reading dll lists. Change-Id: Icc2142a80765e4551ef6b85bdb1e1643f5c9404d --- NativeLauncher/installer-plugin/common.cc | 6 --- .../Tizen.Runtime.Coreclr/AssemblyManager.cs | 52 +++++++++++++++++----- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/NativeLauncher/installer-plugin/common.cc b/NativeLauncher/installer-plugin/common.cc index 8701b2e..d4d007f 100644 --- a/NativeLauncher/installer-plugin/common.cc +++ b/NativeLauncher/installer-plugin/common.cc @@ -105,12 +105,6 @@ static void smack_(const char* dll_path) dll_path, nullptr }; - for (const char* arg : args) - { - printf("%s ", arg); - } - printf("\n"); - execv(CHKSMACK, const_cast(args)); exit(0); diff --git a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs index 26b8868..52297a1 100644 --- a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs +++ b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs @@ -105,7 +105,7 @@ namespace Tizen.Runtime.Coreclr PrintException(e); } - public static bool Initialize(string preloadDirectory) + public static bool Initialize(string preloadFile) { try { @@ -132,19 +132,49 @@ namespace Tizen.Runtime.Coreclr { CurrentAssemblyLoaderContext = new AssemblyLoader(); - if (!string.IsNullOrEmpty(preloadDirectory)) + if (!string.IsNullOrEmpty(preloadFile)) { - ALog.Debug($"Load from [{preloadDirectory}]"); - DirectoryInfo d = new DirectoryInfo(preloadDirectory); - if (Directory.Exists(d.FullName)) + ALog.Debug($"Load from [{preloadFile}]"); + FileInfo f = new FileInfo(preloadFile); + if (File.Exists(f.FullName)) { - CurrentAssemblyLoaderContext.AddSearchableDirectory(d.FullName); - string[] dlls = Directory.GetFiles(d.FullName, "*.dll"); - - foreach (string dll in dlls) + using (StreamReader sr = File.OpenText(f.FullName)) { - ALog.Debug($"preload dll : {dll}"); - CurrentAssemblyLoaderContext.LoadFromAssemblyPath(dll); + string s = String.Empty; + while ((s = sr.ReadLine()) != null) + { + ALog.Debug($"preload dll : {s}"); + try + { + Assembly asm = null; + if (s.EndsWith(".ni.dll", StringComparison.CurrentCultureIgnoreCase)) + { + asm = CurrentAssemblyLoaderContext.LoadFromNativeImagePath(s, null); + } + else + { + asm = CurrentAssemblyLoaderContext.LoadFromAssemblyPath(s); + } + + // this works strange, vm can't load types except loaded in here. + // so user code spit out not found exception. + /* + if (asm != null) + { + foreach (TypeInfo t in asm.DefinedTypes) + { + ALog.Debug("===> TYPE : " + t.FullName); + GC.KeepAlive(t.AsType()); + } + } + */ + } + catch (Exception e) + { + ALog.Debug("Exception on preload"); + PrintException(e); + } + } } } } -- 2.7.4 From 69a43a53ef090e1c70ab8969c420073c14caf21a Mon Sep 17 00:00:00 2001 From: Cho Woong Suk Date: Tue, 22 Nov 2016 12:57:02 +0900 Subject: [PATCH 03/16] preload native libraries and pre-create windows to optimize app launching performance Change-Id: Ia9065c5b2a1470aa3c72675b7bb953bd4bf00dc1 Signed-off-by: Cho Woong Suk --- NativeLauncher/CMakeLists.txt | 2 +- NativeLauncher/dotnet.loader | 10 +++++ NativeLauncher/launcher/launcher.cc | 73 ++++++++++++++++++++++++++++++++++++- packaging/dotnet-launcher.spec | 1 + 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/NativeLauncher/CMakeLists.txt b/NativeLauncher/CMakeLists.txt index cd273e1..3c35c5f 100644 --- a/NativeLauncher/CMakeLists.txt +++ b/NativeLauncher/CMakeLists.txt @@ -7,7 +7,7 @@ IF(DEFINED NO_TIZEN) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -DNO_TIZEN") ELSE(DEFINED NO_TIZEN) INCLUDE(FindPkgConfig) - PKG_CHECK_MODULES(${PROJECT_NAME} REQUIRED aul pkgmgr-info pkgmgr-installer dlog ecore bundle dlog launchpad) + PKG_CHECK_MODULES(${PROJECT_NAME} REQUIRED aul pkgmgr-info pkgmgr-installer dlog ecore bundle dlog launchpad elementary) ENDIF(DEFINED NO_TIZEN) FOREACH(flag ${${PROJECT_NAME}_CFLAGS}) diff --git a/NativeLauncher/dotnet.loader b/NativeLauncher/dotnet.loader index 67094b9..57b547d 100644 --- a/NativeLauncher/dotnet.loader +++ b/NativeLauncher/dotnet.loader @@ -4,3 +4,13 @@ EXE /usr/bin/dotnet-launcher APP_TYPE dotnet DETECTION_METHOD TIMEOUT|DEMAND TIMEOUT 5000 +EXTRA_ARRAY preload +EXTRA_ARRAY_VAL /usr/lib/libappcore-efl.so.1 +EXTRA_ARRAY_VAL /usr/lib/libappcore-common.so.1 +EXTRA_ARRAY_VAL /usr/lib/libcapi-appfw-application.so.0 +EXTRA_ARRAY_VAL /usr/lib/ecore_imf/modules/wayland/v-1.16/libwltextinputmodule.so +EXTRA_ARRAY_VAL /usr/lib/libdali-toolkit.so +EXTRA_ARRAY_VAL /usr/lib/libcairo.so.2 +EXTRA_ARRAY_VAL /usr/lib/libefl-assist.so.0 +EXTRA_ARRAY_VAL /usr/lib/libcapi-media-player.so.0 +EXTRA_ARRAY_VAL /usr/lib/libcapi-media-camera.so.0 diff --git a/NativeLauncher/launcher/launcher.cc b/NativeLauncher/launcher/launcher.cc index ebbc58d..c26b0e0 100644 --- a/NativeLauncher/launcher/launcher.cc +++ b/NativeLauncher/launcher/launcher.cc @@ -21,12 +21,15 @@ #include #include +#include +#include #include #include #include #include +#include namespace tizen { @@ -38,6 +41,12 @@ struct FdHandler loader_receiver_cb receiver; }; +static int __argc; +static char **__argv; +static Evas_Object *__win; +static Evas_Object *__bg; +static Evas_Object *__conform; + class LaunchpadAdapterImpl : public LaunchpadAdapter { public: @@ -124,12 +133,74 @@ static void Fd_Remove(void *data, int fd) } } -void LaunchpadAdapterImpl::LoaderMain(int argc, char* argv[]) + +static void PreloadLibsAndWindow(bundle *extra, int type, void *user_data) { + int elm_init_cnt = 0; + const char **so_array; + int len = 0; + int i; + void *handle = NULL; + + // Preload native libraries + if (extra == NULL) { + _DBG("No extra data"); + return; + } + + so_array = bundle_get_str_array(extra, "preload", &len); + if (!so_array) + return; + + for (i = 0; i < len; i++) { + handle = dlopen(so_array[i], RTLD_NOW); + _DBG("preload %s# - handle : %x\n", so_array[i], handle); + } + + // Precreate window + elm_init_cnt = elm_init(__argc, __argv); + _DBG("[candidate] elm init, returned: %d", elm_init_cnt); + + elm_config_accel_preference_set("hw"); + + __win = elm_win_add(NULL, "package_name", ELM_WIN_BASIC); + if (__win == NULL) { + _DBG("[candidate] elm_win_add() failed"); + return; + } + + elm_win_precreated_object_set(__win); + + __bg = elm_bg_add(__win); + if (__bg) { + evas_object_size_hint_weight_set(__bg, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + elm_win_resize_object_add(__win, __bg); + elm_bg_precreated_object_set(__bg); + } else { + _DBG("[candidate] elm_bg_add() failed"); + } + + __conform = elm_conformant_add(__win); + if (__conform) { + evas_object_size_hint_weight_set(__conform, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + elm_win_resize_object_add(__win, __conform); + elm_conformant_precreated_object_set(__conform); + } else { + _DBG("elm_conformant_add() failed"); + } +} + +void LaunchpadAdapterImpl::LoaderMain(int argc, char* argv[]) +{ + __argc = argc; + __argv = argv; callbacks.create = [](bundle *extra, int type, void *user_data) { ecore_init(); + PreloadLibsAndWindow(extra, type, user_data); WITH_SELF(user_data) { if (self->OnCreate != nullptr) diff --git a/packaging/dotnet-launcher.spec b/packaging/dotnet-launcher.spec index 0a95375..87cef0e 100644 --- a/packaging/dotnet-launcher.spec +++ b/packaging/dotnet-launcher.spec @@ -17,6 +17,7 @@ BuildRequires: pkgconfig(ecore) BuildRequires: pkgconfig(launchpad) BuildRequires: pkgconfig(pkgmgr-info) BuildRequires: pkgconfig(pkgmgr-installer) +BuildRequires: pkgconfig(elementary) BuildRequires: aul-devel BuildRequires: mono-compiler BuildRequires: mono-devel -- 2.7.4 From 7831908665a20bc904217edfbdbb7e40343ff2bd Mon Sep 17 00:00:00 2001 From: Cho Woong Suk Date: Thu, 8 Dec 2016 22:10:16 +0900 Subject: [PATCH 04/16] generate ni file for dotnet-launcher for nitool --system command Change-Id: I6b2f15085b2e63f11951d0ba3e67e271bacfc77e --- NativeLauncher/installer-plugin/common.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NativeLauncher/installer-plugin/common.cc b/NativeLauncher/installer-plugin/common.cc index d4d007f..377fab9 100644 --- a/NativeLauncher/installer-plugin/common.cc +++ b/NativeLauncher/installer-plugin/common.cc @@ -71,10 +71,10 @@ void create_ni_platform() smack_(nicorlib.c_str()); } - const char* platform_dirs[] = {RuntimeDir, DeviceAPIDir}; + const char* platform_dirs[] = {RuntimeDir, DeviceAPIDir, "/usr/bin"}; const char* ignores[] = {corlib.c_str()}; - create_ni_under_dirs(platform_dirs, 2, ignores, 1, [](const char* ni){ + create_ni_under_dirs(platform_dirs, 3, ignores, 1, [](const char* ni){ smack_(ni); }); } -- 2.7.4 From 41189edf30c5be8a7db7930111d268cc31f7345f Mon Sep 17 00:00:00 2001 From: Cho Woong Suk Date: Thu, 8 Dec 2016 22:08:59 +0900 Subject: [PATCH 05/16] bug-fix : load app ni dll file Change-Id: Iaf03cfb5893bf5ace992c48cbc96756dbdf3f814 --- Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) mode change 100644 => 100755 Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs diff --git a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs old mode 100644 new mode 100755 index 693877f..cbb0095 --- a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs +++ b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs @@ -68,7 +68,13 @@ namespace Tizen.Runtime.Coreclr { foreach (string dir in DllDirectories) { - FileInfo f = new FileInfo(Path.Combine(dir, $"{assemblyName.Name}.dll")); + FileInfo f = new FileInfo(Path.Combine(dir, $"{assemblyName.Name}.ni.dll")); + if (File.Exists(f.FullName)) + { + asm = LoadFromNativeImagePath(f.FullName, null); + break; + } + f = new FileInfo(Path.Combine(dir, $"{assemblyName.Name}.dll")); if (File.Exists(f.FullName)) { asm = LoadFromAssemblyPath(f.FullName); -- 2.7.4 From fc168cf98012b338709f2a80bf11fe24d34f6903 Mon Sep 17 00:00:00 2001 From: JongHeon Choi Date: Wed, 14 Dec 2016 17:10:14 +0900 Subject: [PATCH 06/16] Exclude arm64 and i586 architecture Change-Id: I52410a37cdb4dacf5c3789c23d0a0b5211e88a5b --- packaging/dotnet-launcher.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packaging/dotnet-launcher.spec b/packaging/dotnet-launcher.spec index 87cef0e..7e12b6e 100644 --- a/packaging/dotnet-launcher.spec +++ b/packaging/dotnet-launcher.spec @@ -38,6 +38,8 @@ Requires(preun): /usr/bin/systemctl %define _preload_dir /opt/usr/share/dotnet.tizen/preload %define _install_plugin_dir /usr/etc/package-manager/parserlib +ExcludeArch: %{ix86} aarch64 + %description Launchpad plugin for launching dotnet apps -- 2.7.4 From 98afe6369fccef9715458cc954f3b408c83bd572 Mon Sep 17 00:00:00 2001 From: Cho Woong Suk Date: Fri, 16 Dec 2016 15:10:10 +0900 Subject: [PATCH 07/16] bug-fix: do not pre-create bg and conformant. Change-Id: I27cc5e44c72656f87eca5ef94f3c722c20254990 --- NativeLauncher/launcher/launcher.cc | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/NativeLauncher/launcher/launcher.cc b/NativeLauncher/launcher/launcher.cc index c26b0e0..c2d1ce4 100644 --- a/NativeLauncher/launcher/launcher.cc +++ b/NativeLauncher/launcher/launcher.cc @@ -171,26 +171,6 @@ static void PreloadLibsAndWindow(bundle *extra, int type, void *user_data) } elm_win_precreated_object_set(__win); - - __bg = elm_bg_add(__win); - if (__bg) { - evas_object_size_hint_weight_set(__bg, EVAS_HINT_EXPAND, - EVAS_HINT_EXPAND); - elm_win_resize_object_add(__win, __bg); - elm_bg_precreated_object_set(__bg); - } else { - _DBG("[candidate] elm_bg_add() failed"); - } - - __conform = elm_conformant_add(__win); - if (__conform) { - evas_object_size_hint_weight_set(__conform, EVAS_HINT_EXPAND, - EVAS_HINT_EXPAND); - elm_win_resize_object_add(__win, __conform); - elm_conformant_precreated_object_set(__conform); - } else { - _DBG("elm_conformant_add() failed"); - } } void LaunchpadAdapterImpl::LoaderMain(int argc, char* argv[]) -- 2.7.4 From 095697508a12bc9c471e096fdbd0a2e2b0b8f458 Mon Sep 17 00:00:00 2001 From: Pawel Andruszkiewicz Date: Fri, 9 Dec 2016 08:52:45 +0100 Subject: [PATCH 08/16] AssemblyLoader should assist in loading all assemblies The Resolving event from the AssemblyLoadContext is invoked each time it fails to load an assembly. The default AssemblyLoadContext is used internally i.e. when Assembly.Load() or Type.GetType(string) methods are called. Registering for the Resolving event from the default AssemblyLoadContext helps handling the unresolved assemblies and fixes XAML-related issues in Xamarin. TASK=TNET-136 TASK=TCAPI-1863 Change-Id: I0f5f4c2925829eac448a6184a3e19dbde5c1dfc0 Signed-off-by: Pawel Andruszkiewicz --- .../Tizen.Runtime.Coreclr/AssemblyLoader.cs | 89 +++++++++++++++------- .../Tizen.Runtime.Coreclr/AssemblyManager.cs | 24 ++---- 2 files changed, 69 insertions(+), 44 deletions(-) diff --git a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs index cbb0095..35a8ddf 100755 --- a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs +++ b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs @@ -16,6 +16,7 @@ using System; using System.IO; +using System.Linq; using System.Reflection; using System.Runtime.Loader; using System.Collections.Generic; @@ -24,9 +25,24 @@ namespace Tizen.Runtime.Coreclr { public class AssemblyLoader : AssemblyLoadContext { + private const string NativeAssemblyInfix = ".ni"; + + private const string DllAssemblySuffix = ".dll"; + + private const string NativeDllAssemblySuffix = NativeAssemblyInfix + DllAssemblySuffix; + + private static readonly string[] s_suffixes = new string[] { NativeDllAssemblySuffix, DllAssemblySuffix }; + private SortedSet _dllDirectories = new SortedSet(); private SortedSet _nativeDirectories = new SortedSet(); + private HashSet _dllCache = new HashSet(); + + public AssemblyLoader() + { + AssemblyLoadContext.Default.Resolving += OnResolving; + } + public IEnumerable DllDirectories { get { return _dllDirectories; } @@ -43,6 +59,16 @@ namespace Tizen.Runtime.Coreclr { _dllDirectories.Add(directory); _nativeDirectories.Add(directory); + + foreach (var file in Directory.GetFiles(directory)) + { + var info = new FileInfo(file); + + if (info.Extension == DllAssemblySuffix) + { + _dllCache.Add(info); + } + } } } @@ -50,39 +76,30 @@ namespace Tizen.Runtime.Coreclr { _dllDirectories.Remove(directory); _nativeDirectories.Remove(directory); + + _dllCache.RemoveWhere(x => x.DirectoryName == directory); } - protected override Assembly Load(AssemblyName assemblyName) + public Assembly LoadFromPath(string path) { - Assembly asm = null; - - try + if (0 == string.Compare(path, // strA + path.Length - NativeDllAssemblySuffix.Length, // indexA + NativeAssemblyInfix, // strB + 0, // indexB + NativeAssemblyInfix.Length, // length + StringComparison.OrdinalIgnoreCase)) // options { - //asm = AssemblyLoadContext.Default.Load(assemblyName); - asm = AssemblyLoadContext.Default.LoadFromAssemblyName(assemblyName); + return LoadFromNativeImagePath(path, null); } - catch (Exception ex) - when (ex is FileNotFoundException || - ex is BadImageFormatException || - ex is FileLoadException) + else { - foreach (string dir in DllDirectories) - { - FileInfo f = new FileInfo(Path.Combine(dir, $"{assemblyName.Name}.ni.dll")); - if (File.Exists(f.FullName)) - { - asm = LoadFromNativeImagePath(f.FullName, null); - break; - } - f = new FileInfo(Path.Combine(dir, $"{assemblyName.Name}.dll")); - if (File.Exists(f.FullName)) - { - asm = LoadFromAssemblyPath(f.FullName); - break; - } - } + return LoadFromAssemblyPath(path); } - return asm; + } + + protected override Assembly Load(AssemblyName assemblyName) + { + return Resolve(assemblyName); } protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) @@ -103,5 +120,25 @@ namespace Tizen.Runtime.Coreclr return native; } + + private Assembly Resolve(AssemblyName assemblyName) + { + foreach (string suffix in s_suffixes) + { + var info = _dllCache.FirstOrDefault(x => x.Name == assemblyName.Name + suffix); + + if (info != null) + { + return LoadFromPath(info.FullName); + } + } + + return null; + } + + private Assembly OnResolving(AssemblyLoadContext context, AssemblyName assemblyName) + { + return Resolve(assemblyName); + } } } diff --git a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs index 52297a1..de0b293 100644 --- a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs +++ b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs @@ -146,15 +146,7 @@ namespace Tizen.Runtime.Coreclr ALog.Debug($"preload dll : {s}"); try { - Assembly asm = null; - if (s.EndsWith(".ni.dll", StringComparison.CurrentCultureIgnoreCase)) - { - asm = CurrentAssemblyLoaderContext.LoadFromNativeImagePath(s, null); - } - else - { - asm = CurrentAssemblyLoaderContext.LoadFromAssemblyPath(s); - } + Assembly asm = CurrentAssemblyLoaderContext.LoadFromPath(s); // this works strange, vm can't load types except loaded in here. // so user code spit out not found exception. @@ -195,20 +187,16 @@ namespace Tizen.Runtime.Coreclr FileInfo f = new FileInfo(dllPath); if (File.Exists(f.FullName)) { - Assembly asm = null; - if (0 == string.Compare(f.FullName, f.FullName.Length - 7, ".ni", 0, 3, StringComparison.OrdinalIgnoreCase)) - { - asm = CurrentAssemblyLoaderContext.LoadFromNativeImagePath(f.FullName, null); - } - else - { - asm = CurrentAssemblyLoaderContext.LoadFromAssemblyPath(f.FullName); - } + Assembly asm = CurrentAssemblyLoaderContext.LoadFromPath(f.FullName); if (asm == null) throw new FileNotFoundException($"{f.FullName} is not found"); if (asm.EntryPoint == null) throw new ArgumentException($"{f.FullName} did not have EntryPoint"); asm.EntryPoint.Invoke(null, new object[]{argv}); } + else + { + ALog.Debug($"Requested file does not exist: {dllPath}"); + } } catch (Exception e) { -- 2.7.4 From 8ea5d0a517060f492c1757a4b5e85061f8ca7333 Mon Sep 17 00:00:00 2001 From: Inhwan Lee Date: Thu, 15 Dec 2016 14:27:39 +0900 Subject: [PATCH 09/16] add test tool for check launching time Change-Id: I4d29972eceb263559135f8ca7c659ffdaefd0c27 --- tools/README | 95 ++++++++++++++++ tools/performance_test.sh | 285 ++++++++++++++++++++++++++++++++++++++++++++++ tools/timestamp.sh | 56 +++++++++ 3 files changed, 436 insertions(+) create mode 100755 tools/README create mode 100755 tools/performance_test.sh create mode 100755 tools/timestamp.sh diff --git a/tools/README b/tools/README new file mode 100755 index 0000000..41e934b --- /dev/null +++ b/tools/README @@ -0,0 +1,95 @@ +README file for performance test of dotnet launcher + + +[*] SUMMARY +------------------------------------------------------------------------------- +Performance test is a tool to calcuate launching time. +This tool is performed on the host where the device is connected with sdb + +[*] PREPARATIONS +------------------------------------------------------------------------------- +The test consists of two files. + - performance_test.sh : main executable script + - timestamp.sh : used by "performance_test.sh" +The files should be in the same directory in host. + +For running automatic test, you have to locate ".tpk" files in specific directory +More detail, it describes in "USAGE" section. + +This test need below package + - inotify-tools +If the package is not exist, it will try to install the package. + +The host can connect device with sdb. + + +[*] TEST MODES +------------------------------------------------------------------------------- +There are two modes in performance test + - auto test mode + - manual test mode + +Each mode has the following characteristics. +[Auto test mode] + This mode automatically installs applications and measures and records performance. + This mode need ".tpk" packaged dotnet application. It should located in "tpk" directory. + So, files locates likes below. + . + ├── performance_test.sh + ├── README + ├── timestamp.sh + └── tpk + └── .tpk + There can be several tpk files. And tpk files can be freely added or deleted by the user. +[Manual test mode] + This mode measures the execution time when the user executes the installed applications. + After executing this mode, the user runs and terminates the application. + And then, result of launching time and making report file. + + +[*] USAGE +------------------------------------------------------------------------------- +The test has two modes. + - automatic test + - manual test + +Each test can be run through shell below options. + -a --auto : execute automatic test + -m --manual : execute manual test + +In the auto test mode does not require user input. +In the manual test mode, the user executes / terminates the application after executing the test. + + +[*] TEST RESULT +------------------------------------------------------------------------------- +Test results are generated as files in the "result/" directory. +The resulting file name is determined by the date and time, likes "result/result_YYYYMMDD_HHmm.log" + +Test results consist of launching time(ms) and applicatoin id. +example of result : + T(ms) APP ID + 680 org.tizen.example.BasicSampleXamarine.Tizen + 710 org.tizen.example.XamarinApplication1.Tizen + 1460 org.tizen.example.EmailUI.Tizen + 770 org.tizen.example.FormsTizenGallery.Tizen + 2390 org.tizen.example.SNSUI.Tizen + + +[*] ERROR CASE +------------------------------------------------------------------------------- +Some system can be occur error with some points. +In this section, we would like to share some solutions to solve the problems. + +[>] Inotify-tools - 'max_user_watchers' error + + [ERROR CASE] + Failed to watch stream.log; upper limit on inotify watches reached! + Please increase the amount of inotify watches allowed per user via `/proc/sys/fs/inotify/max_user_watches'. + + execute below command for expand max_user_watchers for inotify-tool + + [SOLVE] + echo 32768 | sudo tee /proc/sys/fs/inotify/max_user_watches + echo fs.inotify.max_user_watches=32768 | sudo tee -a /etc/sysctl.conf + sudo sysctl -p diff --git a/tools/performance_test.sh b/tools/performance_test.sh new file mode 100755 index 0000000..def3105 --- /dev/null +++ b/tools/performance_test.sh @@ -0,0 +1,285 @@ +#!/bin/bash + +STREAM_LOG_FILE=stream.log +DATE=$(date +%Y%m%d_%H%M) +RESULT_LOG_FILE='result/result_'$DATE'.log' + +WAIT_FOR_LAUNCH=10 +WAIT_FOR_KILL=5 + +PKG_IDS=() +APP_IDS=() + +initialize () +{ + echo "" + echo "[>] Initialize for Performance Test" + if [ $(sdb get-state 2>/dev/null | grep -c "device") -eq 0 ]; + then + echo "" + echo "[!] device is not connected - cannot execute" + echo "" + exit 0 + fi + + if [ $(dpkg-query -W -f='${Status}' inotify-tools 2>/dev/null | grep -c "ok installed") -eq 0 ]; + then + echo "" + echo "[!] inotify-tools package should install" + echo "[!] starting install inotify-tools .. " + sudo apt-get install inotify-tools + if [ $(dpkg-query -W -f='${Status}' inotify-tools 2>/dev/null | grep -c "ok installed") -eq 0 ]; + then + echo "" + echo "[!] install inotify-tools fail - cannot execute" + echo "" + exit 0 + fi + echo 32768 | sudo tee /proc/sys/fs/inotify/max_user_watches + echo fs.inotify.max_user_watches=32768 | sudo tee -a /etc/sysctl.conf + sudo sysctl -p + fi + sdb root on + sdb shell "devicectl display stop">/dev/null 2>&1 + mkdir result>/dev/null 2>&1 + rm $STREAM_LOG_FILE>/dev/null 2>&1 + touch $STREAM_LOG_FILE +} + +install_tpk () +{ +#install tpk packages + echo "[>] Installing package in tpk directory" + TPKS=($(ls tpk | grep .tpk)) + + + for item in ${TPKS[*]} + do + INSTALL_MSG=$(sdb install tpk/$item | grep start) + INSTALL_MSG=$(echo $INSTALL_MSG | sed "s/\[/ /g") + INSTALL_MSG=$(echo $INSTALL_MSG | sed "s/\]/ /g") + PKG_IDS+=($(echo $INSTALL_MSG | awk '{print $7}')) + echo " [>] ($(echo $INSTALL_MSG | awk '{print $7}')) installs complete" + done +} + +get_current_tpk_apps () +{ + echo "[>] Get application list in device" + PKG_IDS+=$( + sdb shell "su - owner -c 'pkgcmd -l | grep tpk'" | while read line + do + APP_LIST_ENTITY=$line + APP_LIST_ENTITY=$(echo $APP_LIST_ENTITY | sed "s/\[/ /g") + APP_LIST_ENTITY=$(echo $APP_LIST_ENTITY | sed "s/\]/ /g") + APP_OWNER=($(echo $APP_LIST_ENTITY | awk '{print $1}')) + if [[ $APP_OWNER == 'user' ]] + then + echo $APP_LIST_ENTITY | awk '{print $6}' + fi + done | sort + ) +} + +make_appid_list () +{ +#get app ids + echo "[>] Get application id that installed" + for item in ${PKG_IDS[*]} + do + APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -l | grep $item'") + APP_LIST_MSG=${APP_LIST_MSG#*\'} + APP_LIST_MSG=$(echo $APP_LIST_MSG | sed "s/'/ /g") + APP_IDS+=($(echo $APP_LIST_MSG | awk '{print $2}')) + done +} + +initialize_first_launch () +{ + if [[ -z ${APP_IDS[0]} ]]; then + echo "" + echo "[!] No tpk Packages for test" + echo "[!] Copy tpk files in [./tpk] directory" + echo "" + exit 0 + fi + echo "[>] Initial launch an application" + APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -s ${APP_IDS[0]}'") + sleep 10 + APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -k ${APP_IDS[0]}'") + sleep 5 +} + +execute_time_stamp_auto () +{ + echo "" + echo "[>] Start performance test that applciation launching " + echo "" +#execute dlogstreamer + sdb shell "dlogutil -c" + sdb shell "dlogutil -v time AUL APP_CORE|grep -E 'app_request_to_launchpad_for_uid.*[SECURE_LOG].*launch.*request|__show_cb.*[EVENT_TEST][EVENT]'" >> $STREAM_LOG_FILE & + DLOG_STREAMER_PID=$! +#execute timestamp + /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE & + TIMESTAMP_PID=$! +} + +execute_time_stamp_manual () +{ +#execute dlogstreamer + echo "" + echo "[>] Start performance test that applciation launching " + echo "" + rm $STREAM_LOG_FILE + touch $STREAM_LOG_FILE + sdb shell "dlogutil -c" + sdb shell "dlogutil -v time AUL APP_CORE|grep -E 'app_request_to_launchpad_for_uid.*[SECURE_LOG].*launch.*request|__show_cb.*[EVENT_TEST][EVENT]'" >> $STREAM_LOG_FILE & + DLOG_STREAMER_PID=$! +#execute timestamp + /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE + TIMESTAMP_PID=$! + wait $TIMESTAMP_PID +} + +execute_time_stamp_manual_trace () +{ +#execute dlogstreamer + echo "" + echo "[>] Start performance test that applciation launching " + echo "" + rm $STREAM_LOG_FILE + touch $STREAM_LOG_FILE + sdb shell "dlogutil -c" + sdb shell "dlogutil -v time AUL APP_CORE|grep -E 'app_request_to_launchpad_for_uid.*[SECURE_LOG].*launch.*request|__show_cb.*[EVENT_TEST][EVENT]'" >> $STREAM_LOG_FILE & + DLOG_STREAMER_PID=$! +#execute timestamp + /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE & + TIMESTAMP_PID=$! +#execute ttrace + ~/tizen-sdk/tools/ttrace/ttrace.py -b 20480 -t 10 -o result/trace.html idle app view am & + TTRACE_PID=$! + wait $TTRACE_PID + rm result/*.ftrace + rm result/*.raw +} + +execute_all_app () +{ +#execute each apps + for item in ${APP_IDS[*]} + do + APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -s $item'") + sleep $WAIT_FOR_LAUNCH + APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -k $item'") + sleep $WAIT_FOR_KILL + done +} + +execute_all_app_trace () +{ +#execute each apps + for item in ${APP_IDS[*]} + do + ~/tizen-sdk/tools/ttrace/ttrace.py -b 20480 -t 13 -o result/${item}.html idle app view am & > /dev/null 2>&1 + TTRACE_PID=$! + sleep 1 + APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -s $item'") + sleep $WAIT_FOR_LAUNCH + APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -t $item'") + sleep $WAIT_FOR_KILL + sleep 4 + done + rm result/*.ftrace + rm result/*.raw +} + +finalize () +{ + echo "" + echo "[>] Result" + echo "" + cat $RESULT_LOG_FILE + echo "" + echo "[>] Result file : [ $RESULT_LOG_FILE ]" +} + +destory () +{ + echo "" + kill -9 $DLOG_STREAMER_PID>/dev/null 2>&1 + kill -9 $TIMESTAMP_PID>/dev/null 2>&1 + kill -9 $TTRACE_PID>/dev/null 2>&1 + rm $STREAM_LOG_FILE>/dev/null 2>&1 + sdb shell "devicectl display start">/dev/null 2>&1 + echo "[>] Finalize for Performance Test" + echo "" +} + +help () +{ + echo "" + echo "[!] usage :