From 7ae59856cb0fec4bf9b42639faae32bb29fd1d96 Mon Sep 17 00:00:00 2001 From: Alexander Shabalin Date: Thu, 10 Jun 2021 12:53:57 +0300 Subject: [PATCH] Add internal MemoryUsageInfo object Currently it only provides peak RSS usage for iOS, Linux, macOS and Windows. --- .../runtime/src/main/cpp/MemoryUsageInfo.cpp | 63 +++++++++++++++++++ .../runtime/src/main/cpp/MemoryUsageInfo.hpp | 17 +++++ .../kotlin/native/internal/MemoryUsageInfo.kt | 17 +++++ 3 files changed, 97 insertions(+) create mode 100644 kotlin-native/runtime/src/main/cpp/MemoryUsageInfo.cpp create mode 100644 kotlin-native/runtime/src/main/cpp/MemoryUsageInfo.hpp create mode 100644 kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/MemoryUsageInfo.kt diff --git a/kotlin-native/runtime/src/main/cpp/MemoryUsageInfo.cpp b/kotlin-native/runtime/src/main/cpp/MemoryUsageInfo.cpp new file mode 100644 index 00000000000..1f91f5a521c --- /dev/null +++ b/kotlin-native/runtime/src/main/cpp/MemoryUsageInfo.cpp @@ -0,0 +1,63 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +#include "MemoryUsageInfo.hpp" + +#include +#include + +#include "Types.h" + +#if KONAN_WINDOWS + +#include +#include + +size_t kotlin::GetPeakResidentSetSizeBytes() noexcept { + ::PROCESS_MEMORY_COUNTERS memoryCounters; + auto succeeded = ::GetProcessMemoryInfo(::GetCurrentProcess(), &memoryCounters, sizeof(memoryCounters)); + if (!succeeded) { + return 0; + } + return memoryCounters.PeakWorkingSetSize; +} + +#elif KONAN_LINUX || KONAN_MACOSX || KONAN_IOS + +#include +#include + +size_t kotlin::GetPeakResidentSetSizeBytes() noexcept { + ::rusage usage; + auto failed = ::getrusage(RUSAGE_SELF, &usage); +#if KONAN_LINUX + // On Linux it's in kilobytes. + size_t maxrss = static_cast(usage.ru_maxrss * 1024); +#elif KONAN_MACOSX || KONAN_IOS + // On macOS and iOS it's in bytes. + size_t maxrss = static_cast(usage.ru_maxrss); +#else +#error "Check what units ru_maxrss is in." +#endif + if (failed) { + return 0; + } + return maxrss; +} + +#else + +// TODO: Support more platforms +size_t kotlin::GetPeakResidentSetSizeBytes() noexcept { + return 0; +} + +#endif + +extern "C" RUNTIME_NOTHROW KLong Kotlin_MemoryUsageInfo_getPeakResidentSetSizeBytes() { + auto result = kotlin::GetPeakResidentSetSizeBytes(); + auto boundedResult = std::min(result, std::numeric_limits::max()); + return static_cast(boundedResult); +} diff --git a/kotlin-native/runtime/src/main/cpp/MemoryUsageInfo.hpp b/kotlin-native/runtime/src/main/cpp/MemoryUsageInfo.hpp new file mode 100644 index 00000000000..0f7c518f3d7 --- /dev/null +++ b/kotlin-native/runtime/src/main/cpp/MemoryUsageInfo.hpp @@ -0,0 +1,17 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +#ifndef RUNTIME_MEMORY_USAGE_INFO_H +#define RUNTIME_MEMORY_USAGE_INFO_H + +#include + +namespace kotlin { + +size_t GetPeakResidentSetSizeBytes() noexcept; + +} + +#endif // RUNTIME_MEMORY_USAGE_INFO_H diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/MemoryUsageInfo.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/MemoryUsageInfo.kt new file mode 100644 index 00000000000..85193f08463 --- /dev/null +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/MemoryUsageInfo.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ +package kotlin.native.internal + +@InternalForKotlinNative +object MemoryUsageInfo { + // An estimate of how much memory was committed by the process at its peak. + // Resident Set Size in *nix, Working Set Size in Windows. + // May return 0 if unimplemented on some platform, or in case of an error. + val peakResidentSetSizeBytes: Long + get() = MemoryUsageInfo_getPeakResidentSetSizeBytes() +} + +@GCUnsafeCall("Kotlin_MemoryUsageInfo_getPeakResidentSetSizeBytes") +private external fun MemoryUsageInfo_getPeakResidentSetSizeBytes(): Long