X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.nativemem%2Fsrc%2Forg%2Fsimantics%2Fnativemem%2FNativeMem.java;h=bf761380312de52f69e32e574a3dc4dc16ab9482;hb=99f23679ed1b7c4a47cd841fa75be142225eb7aa;hp=cfccc215447af083bbf6e5d032464309185400da;hpb=9a175feb652b2b7bba7afa540831b9076be3c10e;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java index cfccc2154..bf7613803 100644 --- a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java @@ -1,56 +1,144 @@ -package org.simantics.nativemem; - -import org.simantics.nativemem.internal.Arch; -import org.simantics.nativemem.internal.OS; -import org.simantics.nativemem.internal.Psapi32; -import org.simantics.nativemem.internal.Psapi64; - -import com.sun.jna.platform.win32.Kernel32; -import com.sun.jna.platform.win32.WinNT.HANDLE; - - -public class NativeMem { - - /** - * @param out - * the structure to write the result into or null to - * create a new structure - * @return the result structure - */ - public static ProcessMemoryCounters getMemoryCounters(ProcessMemoryCounters out) { - if (out == null) - out = new ProcessMemoryCounters(); - - OS os = OS.calculate(); - Arch arch = Arch.calculate(); - switch (os) { - case WINDOWS: { - HANDLE proc = Kernel32.INSTANCE.GetCurrentProcess(); - switch (arch) { - 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(out); - return out; - } - - 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(out); - return out; - } - - default: - throw new UnsupportedOperationException("Architecture " + arch + " not supported on operating system " + os); - } - } - - default: - throw new UnsupportedOperationException("Operating system " + os + " not supported"); - } - } - +/******************************************************************************* + * 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; + + +public class NativeMem { + + /** + * @param out + * the structure to write the result into or null 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 castOrCreate(Object o, Class 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