-package org.simantics.nativemem;\r
-\r
-import org.simantics.nativemem.internal.Arch;\r
-import org.simantics.nativemem.internal.OS;\r
-import org.simantics.nativemem.internal.Psapi32;\r
-import org.simantics.nativemem.internal.Psapi64;\r
-\r
-import com.sun.jna.platform.win32.Kernel32;\r
-import com.sun.jna.platform.win32.WinNT.HANDLE;\r
-\r
-\r
-public class NativeMem {\r
-\r
- /**\r
- * @param out\r
- * the structure to write the result into or <code>null</code> to\r
- * create a new structure\r
- * @return the result structure\r
- */\r
- public static ProcessMemoryCounters getMemoryCounters(ProcessMemoryCounters out) {\r
- if (out == null)\r
- out = new ProcessMemoryCounters();\r
-\r
- OS os = OS.calculate();\r
- Arch arch = Arch.calculate();\r
- switch (os) {\r
- case WINDOWS: {\r
- HANDLE proc = Kernel32.INSTANCE.GetCurrentProcess();\r
- switch (arch) {\r
- case X86: {\r
- Psapi32.PROCESS_MEMORY_COUNTERS_EX pmem = new Psapi32.PROCESS_MEMORY_COUNTERS_EX();\r
- boolean ok = Psapi32.INSTANCE.GetProcessMemoryInfo(proc, pmem, pmem.size());\r
- if (ok)\r
- pmem.writeTo(out);\r
- return out;\r
- }\r
-\r
- case X86_64: {\r
- Psapi64.PROCESS_MEMORY_COUNTERS_EX pmem = new Psapi64.PROCESS_MEMORY_COUNTERS_EX();\r
- boolean ok = Psapi64.INSTANCE.GetProcessMemoryInfo(proc, pmem, pmem.size());\r
- if (ok)\r
- pmem.writeTo(out);\r
- return out;\r
- }\r
-\r
- default:\r
- throw new UnsupportedOperationException("Architecture " + arch + " not supported on operating system " + os);\r
- }\r
- }\r
-\r
- default:\r
- throw new UnsupportedOperationException("Operating system " + os + " not supported");\r
- }\r
- }\r
-\r
+/*******************************************************************************
+ * Copyright (c) 2016, 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.nativemem;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.simantics.nativemem.internal.Arch;
+import org.simantics.nativemem.internal.DummyProcessMemoryInfo;
+import org.simantics.nativemem.internal.CMemoryInfo;
+import org.simantics.nativemem.internal.OS;
+import org.simantics.nativemem.internal.Resource;
+import org.simantics.nativemem.internal.Resource32;
+import org.simantics.nativemem.internal.Resource64;
+import org.simantics.nativemem.internal.linux.Stat;
+import org.simantics.nativemem.internal.win.ProcessMemoryCounters;
+import org.simantics.nativemem.internal.win.Psapi32;
+import org.simantics.nativemem.internal.win.Psapi64;
+
+import com.sun.jna.platform.win32.Kernel32;
+import com.sun.jna.platform.win32.WinNT.HANDLE;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class NativeMem {
+
+ /**
+ * @param out
+ * the structure to write the result into or <code>null</code> to
+ * create a new structure
+ * @return the result structure
+ */
+ public static ProcessMemoryInfo getMemoryInfo(ProcessMemoryInfo out) {
+ switch (OS.calculate()) {
+ case WINDOWS:
+ return getProcessMemoryCounters(out);
+
+ case APPLE:
+ return getCMemoryInfo(out);
+
+ case LINUX: {
+ CMemoryInfo info = getCMemoryInfo(out);
+ info.peakRSS *= 1024L;
+ getCurrentRSS(info);
+ return info;
+ }
+
+ default:
+ return DummyProcessMemoryInfo.INSTANCE;
+ }
+ }
+
+ private static ProcessMemoryCounters getProcessMemoryCounters(ProcessMemoryInfo out) {
+ ProcessMemoryCounters counters = castOrCreate(out, ProcessMemoryCounters.class);
+ HANDLE proc = Kernel32.INSTANCE.GetCurrentProcess();
+ switch (Arch.calculate()) {
+ case X86: {
+ Psapi32.PROCESS_MEMORY_COUNTERS_EX pmem = new Psapi32.PROCESS_MEMORY_COUNTERS_EX();
+ boolean ok = Psapi32.INSTANCE.GetProcessMemoryInfo(proc, pmem, pmem.size());
+ if (ok)
+ pmem.writeTo(counters);
+ return counters;
+ }
+
+ case X86_64: {
+ Psapi64.PROCESS_MEMORY_COUNTERS_EX pmem = new Psapi64.PROCESS_MEMORY_COUNTERS_EX();
+ boolean ok = Psapi64.INSTANCE.GetProcessMemoryInfo(proc, pmem, pmem.size());
+ if (ok)
+ pmem.writeTo(counters);
+ return counters;
+ }
+
+ default:
+ return counters;
+ }
+ }
+
+ private static CMemoryInfo getCMemoryInfo(ProcessMemoryInfo out) {
+ CMemoryInfo info = castOrCreate(out, CMemoryInfo.class);
+
+ switch (Arch.calculate()) {
+ case X86: {
+ Resource32.Rusage rusage = new Resource32.Rusage();
+ int ok = Resource32.INSTANCE.getrusage(Resource.RUSAGE_SELF, rusage);
+ if (ok == 0)
+ rusage.writeTo(info);
+ return info;
+ }
+
+ case X86_64: {
+ Resource64.Rusage rusage = new Resource64.Rusage();
+ int ok = Resource64.INSTANCE.getrusage(Resource.RUSAGE_SELF, rusage);
+ if (ok == 0)
+ rusage.writeTo(info);
+ return info;
+ }
+
+ default:
+ return info;
+ }
+ }
+
+ private static CMemoryInfo getCurrentRSS(ProcessMemoryInfo out) {
+ CMemoryInfo info = castOrCreate(out, CMemoryInfo.class);
+
+ switch (Arch.calculate()) {
+ case X86: {
+ long rss = Stat.getCurrentRSS(Resource32.INSTANCE);
+ if (rss >= 0)
+ info.currentRSS = rss;
+ return info;
+ }
+
+ case X86_64: {
+ long rss = Stat.getCurrentRSS(Resource64.INSTANCE);
+ if (rss >= 0)
+ info.currentRSS = rss;
+ return info;
+ }
+
+ default:
+ return info;
+ }
+ }
+
+ private static <T> T castOrCreate(Object o, Class<T> clazz) {
+ if (clazz.isInstance(o))
+ return clazz.cast(o);
+ try {
+ return clazz.getConstructor().newInstance();
+ } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
+ | NoSuchMethodException | SecurityException e) {
+ throw new Error("Class " + clazz + " does not have a public parameterless constructor", e);
+ }
+ }
+
}
\ No newline at end of file