--- /dev/null
+/*
+* 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);
+ }
+}
*/
using System;
+using System.ComponentModel;
using System.Runtime.InteropServices;
using Tizen.Internals;
using Tizen.System;
public readonly uint STime;
}
+ /// <summary>
+ /// Enumeration for the process memory information key.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public enum ProcessMemoryInfoKey
+ {
+ /// <summary>
+ /// Virtual memory size (KiB)
+ /// </summary>
+ Vsz = 100,
+ /// <summary>
+ /// Resident set size (KiB)
+ /// </summary>
+ Rss = 200,
+ /// <summary>
+ /// Proportional set size (KiB)
+ /// </summary>
+ Pss = 300,
+ /// <summary>
+ /// Not modified and mapped by other processes (KiB)
+ /// </summary>
+ SharedClean = 400,
+ /// <summary>
+ /// Modified and mapped by other processes (KiB)
+ /// </summary>
+ SharedDirty = 500,
+ /// <summary>
+ /// Not modified and available only to that process (KiB)
+ /// </summary>
+ PrivateClean = 600,
+ /// <summary>
+ /// Modified and available only to that process (KiB)
+ /// </summary>
+ PrivateDirty = 700,
+ /// <summary>
+ /// SWAP memory size (KiB)
+ /// </summary>
+ Swap = 800,
+ /// <summary>
+ /// GPU memory size (KiB)
+ /// </summary>
+ Gpu = 900,
+ /// <summary>
+ /// Resident set size in graphic execution manager (KiB)
+ /// </summary>
+ GemRss = 1000
+ }
+
[DllImport(Libraries.RuntimeInfo, EntryPoint = "runtime_info_get_value_int")]
public static extern InformationError GetValue(RuntimeInfoKey key, out int status);
[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);
}
}
*/
using System;
+using System.ComponentModel;
using System.Collections.Generic;
using System.IO;
using System.Linq;
{
private int[] Pids;
private Interop.RuntimeInfo.ProcessMemoryInfo[] Usages;
+ private int[] Swaps;
+ private int[] Gpus;
+ private int[] Gems;
/// <summary>
/// The constructor of ProcessMemoryInformation class.
/// The number of usage entries.
/// </summary>
/// <since_tizen> 4 </since_tizen>
- public int Count { get; internal set; }
+ public int Count => Pids.Length;
/// <summary>
/// Gets the virtual memory size of a process.
}
/// <summary>
+ /// Gets the GPU memory size of a process.
+ /// </summary>
+ /// <param name="pid">The process id.</param>
+ /// <returns>The GPU memory size <paramref name="pid"/> is using (KiB).</returns>
+ /// <exception cref="ArgumentException">Thrown when the <paramref name="pid"/> is invalid.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the data is empty.</exception>
+ [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;
+ }
+
+ /// <summary>
+ /// Gets the resident set size in graphic execution manager of a process.
+ /// </summary>
+ /// <param name="pid">The process id.</param>
+ /// <returns>The resident set size <paramref name="pid"/> is using (KiB).</returns>
+ /// <exception cref="ArgumentException">Thrown when the <paramref name="pid"/> is invalid.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the data is empty.</exception>
+ [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;
+ }
+
+ /// <summary>
+ /// Gets the SWAP memory size of a process.
+ /// </summary>
+ /// <param name="pid">The process id.</param>
+ /// <returns>The SWAP memory size <paramref name="pid"/> is using (KiB).</returns>
+ /// <exception cref="ArgumentException">Thrown when the <paramref name="pid"/> is invalid.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the data is empty.</exception>
+ [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<int> pids)
+ {
+ var ret = Interop.RuntimeInfo.GetProcessMemoryValueInt(pids.ToArray<int>(), pids.ToArray<int>().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);
+ }
+ }
+
+ /// <summary>
/// Update the process memory information to the latest.
/// </summary>
/// <since_tizen> 4 </since_tizen>
Pids = pid.ToArray<int>();
IntPtr ptr = new IntPtr();
- Count = Pids.Count<int>();
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<Interop.RuntimeInfo.ProcessMemoryInfo>(data);
+ data += Marshal.SizeOf<Interop.RuntimeInfo.ProcessCpuUsage>();
+ }
+ }
+ finally
{
- Usages[i] = Marshal.PtrToStructure<Interop.RuntimeInfo.ProcessMemoryInfo>(ptr);
- ptr += Marshal.SizeOf<Interop.RuntimeInfo.ProcessCpuUsage>();
+ 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);
}
}
}