X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.nativemem%2Fsrc%2Forg%2Fsimantics%2Fnativemem%2FNativeMem.java;h=5f7190f08ee588451e50f7322203dcb0da809b54;hb=ea17057d1c483f8a2bcb765527e45cf4fba36df5;hp=c902214ac9bcee3711f747bbb31451100719a2f8;hpb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;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 c902214ac..5f7190f08 100644 --- a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java @@ -1,14 +1,36 @@ +/******************************************************************************* + * 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.Psapi32; -import org.simantics.nativemem.internal.Psapi64; +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 { /** @@ -17,39 +39,107 @@ public class NativeMem { * 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); - } + 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: - throw new UnsupportedOperationException("Operating system " + os + " not supported"); + 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); } }