From 023632a7e5a1f11b00ee6f82a9148f359c8d1440 Mon Sep 17 00:00:00 2001 From: yunmiha <49266695+yunmiha@users.noreply.github.com> Date: Tue, 16 Mar 2021 19:57:51 +0900 Subject: [PATCH] [Tizen.System.Information][Non-ACR] Add API for internal (#2740) * [Tizen.System.Information] Add API - GetGemRss - GetGpu - GetSwap Signed-off-by: Yunmi Ha * [Tizen.System.Information] Add API - GetGemRss - GetGpu - GetSwap Signed-off-by: Yunmi Ha * Fix build warning Signed-off-by: Yunmi Ha * Update src/Tizen.System.Information/Interop/Interop.RuntimeInfo.cs Co-authored-by: WonYoung Choi * Update src/Tizen.System.Information/Usage/ProcessMemoryUsage.cs Co-authored-by: WonYoung Choi * Update src/Tizen.System.Information/Usage/ProcessMemoryUsage.cs Co-authored-by: WonYoung Choi * Update src/Tizen.System.Information/Usage/ProcessMemoryUsage.cs Co-authored-by: WonYoung Choi * Update src/Tizen.System.Information/Interop/Interop.RuntimeInfo.cs Co-authored-by: WonYoung Choi * Update src/Tizen.System.Information/Usage/ProcessMemoryUsage.cs Co-authored-by: WonYoung Choi * Update src/Tizen.System.Information/Usage/ProcessMemoryUsage.cs Co-authored-by: WonYoung Choi * Update src/Tizen.System.Information/Usage/ProcessMemoryUsage.cs Co-authored-by: WonYoung Choi * Update Interop.RuntimeInfo.cs * Update ProcessMemoryUsage.cs * Create ProcessMemoryUsage.cs * Update ProcessMemoryUsage.cs * Update ProcessMemoryUsage.cs * Update ProcessMemoryUsage.cs * [Tizen.System.Information][Non-ACR] Fix memory leak Signed-off-by: Yunmi Ha Co-authored-by: WonYoung Choi --- .../Interop/Interop.Libc.cs | 27 +++++ .../Interop/Interop.Libraries.cs | 1 + .../Interop/Interop.RuntimeInfo.cs | 52 ++++++++ .../Usage/ProcessMemoryUsage.cs | 132 +++++++++++++++++++-- 4 files changed, 204 insertions(+), 8 deletions(-) create mode 100755 src/Tizen.System.Information/Interop/Interop.Libc.cs mode change 100644 => 100755 src/Tizen.System.Information/Interop/Interop.Libraries.cs diff --git a/src/Tizen.System.Information/Interop/Interop.Libc.cs b/src/Tizen.System.Information/Interop/Interop.Libc.cs new file mode 100755 index 0000000..ef021f1 --- /dev/null +++ b/src/Tizen.System.Information/Interop/Interop.Libc.cs @@ -0,0 +1,27 @@ +/* +* 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. +*/ + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Libc + { + [DllImport(Libraries.Libc, EntryPoint = "free")] + public static extern void Free(IntPtr ptr); + } +} diff --git a/src/Tizen.System.Information/Interop/Interop.Libraries.cs b/src/Tizen.System.Information/Interop/Interop.Libraries.cs old mode 100644 new mode 100755 index ddb1884..60ae721 --- a/src/Tizen.System.Information/Interop/Interop.Libraries.cs +++ b/src/Tizen.System.Information/Interop/Interop.Libraries.cs @@ -20,5 +20,6 @@ internal static partial class Interop { internal const string RuntimeInfo = "libcapi-system-runtime-info.so.0"; internal const string SystemInfo = "libcapi-system-info.so.0"; + internal const string Libc = "libc.so.6"; } } diff --git a/src/Tizen.System.Information/Interop/Interop.RuntimeInfo.cs b/src/Tizen.System.Information/Interop/Interop.RuntimeInfo.cs index fb51f52..681ae93 100755 --- a/src/Tizen.System.Information/Interop/Interop.RuntimeInfo.cs +++ b/src/Tizen.System.Information/Interop/Interop.RuntimeInfo.cs @@ -15,6 +15,7 @@ */ using System; +using System.ComponentModel; using System.Runtime.InteropServices; using Tizen.Internals; using Tizen.System; @@ -67,6 +68,54 @@ internal static partial class Interop public readonly uint STime; } + /// + /// Enumeration for the process memory information key. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public enum ProcessMemoryInfoKey + { + /// + /// Virtual memory size (KiB) + /// + Vsz = 100, + /// + /// Resident set size (KiB) + /// + Rss = 200, + /// + /// Proportional set size (KiB) + /// + Pss = 300, + /// + /// Not modified and mapped by other processes (KiB) + /// + SharedClean = 400, + /// + /// Modified and mapped by other processes (KiB) + /// + SharedDirty = 500, + /// + /// Not modified and available only to that process (KiB) + /// + PrivateClean = 600, + /// + /// Modified and available only to that process (KiB) + /// + PrivateDirty = 700, + /// + /// SWAP memory size (KiB) + /// + Swap = 800, + /// + /// GPU memory size (KiB) + /// + Gpu = 900, + /// + /// Resident set size in graphic execution manager (KiB) + /// + GemRss = 1000 + } + [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_get_value_int")] public static extern InformationError GetValue(RuntimeInfoKey key, out int status); @@ -105,5 +154,8 @@ internal static partial class Interop [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_unset_changed_cb")] public static extern InformationError UnsetRuntimeInfoChangedCallback(RuntimeInfoKey runtimeInfoKey); + + [DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_get_process_memory_value_int")] + public static extern InformationError GetProcessMemoryValueInt(int[] pid, int size, ProcessMemoryInfoKey memoryInfoKey, out IntPtr array); } } diff --git a/src/Tizen.System.Information/Usage/ProcessMemoryUsage.cs b/src/Tizen.System.Information/Usage/ProcessMemoryUsage.cs index 02c03bb..9583f81 100755 --- a/src/Tizen.System.Information/Usage/ProcessMemoryUsage.cs +++ b/src/Tizen.System.Information/Usage/ProcessMemoryUsage.cs @@ -15,6 +15,7 @@ */ using System; +using System.ComponentModel; using System.Collections.Generic; using System.IO; using System.Linq; @@ -30,6 +31,9 @@ namespace Tizen.System { private int[] Pids; private Interop.RuntimeInfo.ProcessMemoryInfo[] Usages; + private int[] Swaps; + private int[] Gpus; + private int[] Gems; /// /// The constructor of ProcessMemoryInformation class. @@ -50,7 +54,7 @@ namespace Tizen.System /// The number of usage entries. /// /// 4 - public int Count { get; internal set; } + public int Count => Pids.Length; /// /// Gets the virtual memory size of a process. @@ -179,6 +183,108 @@ namespace Tizen.System } /// + /// Gets the GPU memory size of a process. + /// + /// The process id. + /// The GPU memory size is using (KiB). + /// Thrown when the is invalid. + /// Thrown when the data is empty. + [EditorBrowsable(EditorBrowsableState.Never)] + public int GetGPU(int pid) + { + if (Gpus == null) + { + Log.Error(InformationErrorFactory.LogTag, "No data"); + InformationErrorFactory.ThrowException(InformationError.NoData); + } + + for (int i = 0; i < Count; i++) + if (pid == Pids[i]) + return Gpus[i]; + + Log.Error(InformationErrorFactory.LogTag, "Invalid pid"); + InformationErrorFactory.ThrowException(InformationError.InvalidParameter); + return 0; + } + + /// + /// Gets the resident set size in graphic execution manager of a process. + /// + /// The process id. + /// The resident set size is using (KiB). + /// Thrown when the is invalid. + /// Thrown when the data is empty. + [EditorBrowsable(EditorBrowsableState.Never)] + public int GetGemRss(int pid) + { + if (Gems == null) + { + Log.Error(InformationErrorFactory.LogTag, "No data"); + InformationErrorFactory.ThrowException(InformationError.NoData); + } + + for (int i = 0; i < Count; i++) + if (pid == Pids[i]) + return Gems[i]; + + Log.Error(InformationErrorFactory.LogTag, "Invalid pid"); + InformationErrorFactory.ThrowException(InformationError.InvalidParameter); + return 0; + } + + /// + /// Gets the SWAP memory size of a process. + /// + /// The process id. + /// The SWAP memory size is using (KiB). + /// Thrown when the is invalid. + /// Thrown when the data is empty. + [EditorBrowsable(EditorBrowsableState.Never)] + public int GetSwap(int pid) + { + if (Swaps == null) + { + Log.Error(InformationErrorFactory.LogTag, "No data"); + InformationErrorFactory.ThrowException(InformationError.NoData); + } + + for (int i = 0; i < Count; i++) + if (pid == Pids[i]) + return Swaps[i]; + + Log.Error(InformationErrorFactory.LogTag, "Invalid pid"); + InformationErrorFactory.ThrowException(InformationError.InvalidParameter); + return 0; + } + + private int[] GetProcessMemoryValueInt(Interop.RuntimeInfo.ProcessMemoryInfoKey key, IEnumerable pids) + { + var ret = Interop.RuntimeInfo.GetProcessMemoryValueInt(pids.ToArray(), pids.ToArray().Length, key, out IntPtr ptr); + if (ret != InformationError.None) + { + Log.Error(InformationErrorFactory.LogTag, "Interop failed to get process memory info: " + key.ToString()); + if (ret == InformationError.NoData) + return null; + InformationErrorFactory.ThrowException(ret); + } + + try + { + var array = new int[Count]; + unsafe + { + for (int i = 0; i < Count; i++) + array[i] = *((int*)ptr.ToPointer() + (i * sizeof(int))); + } + return array; + } + finally + { + Interop.Libc.Free(ptr); + } + } + + /// /// Update the process memory information to the latest. /// /// 4 @@ -194,21 +300,31 @@ namespace Tizen.System Pids = pid.ToArray(); IntPtr ptr = new IntPtr(); - Count = Pids.Count(); ret = Interop.RuntimeInfo.GetProcessMemoryInfo(Pids, Count, ref ptr); if (ret != InformationError.None) { - Log.Error(InformationErrorFactory.LogTag, "Interop failed to get Process cpu usage"); + Log.Error(InformationErrorFactory.LogTag, "Interop failed to get Process cpu usage."); InformationErrorFactory.ThrowException(ret); } - - Usages = new Interop.RuntimeInfo.ProcessMemoryInfo[Count]; - for (int i = 0; i < Count; i++) + try + { + var data = ptr; + Usages = new Interop.RuntimeInfo.ProcessMemoryInfo[Count]; + for (int i = 0; i < Count; i++) + { + Usages[i] = Marshal.PtrToStructure(data); + data += Marshal.SizeOf(); + } + } + finally { - Usages[i] = Marshal.PtrToStructure(ptr); - ptr += Marshal.SizeOf(); + Interop.Libc.Free(ptr); } + + Gpus = GetProcessMemoryValueInt(Interop.RuntimeInfo.ProcessMemoryInfoKey.Gpu, pid); + Gems = GetProcessMemoryValueInt(Interop.RuntimeInfo.ProcessMemoryInfoKey.GemRss, pid); + Swaps = GetProcessMemoryValueInt(Interop.RuntimeInfo.ProcessMemoryInfoKey.Swap, pid); } } } -- 2.7.4