[dart:io] Adds ProcessInfo.{max,current}Rss. Adds OS::MaxRSS on Fuchsia.

R=rmacnak@google.com

Review-Url: https://codereview.chromium.org/2822943002 .
This commit is contained in:
Zachary Anderson
2017-04-17 14:41:39 -07:00
parent d42f61155f
commit 9ce608e89d
16 changed files with 280 additions and 3 deletions
@@ -290,6 +290,19 @@ class _ProcessUtils {
}
}
@patch
class ProcessInfo {
@patch
static int get currentRss {
throw new UnsupportedError("ProcessInfo.currentRss");
}
@patch
static int get maxRss {
throw new UnsupportedError("ProcessInfo.maxRss");
}
}
@patch
class Process {
@patch
+2
View File
@@ -102,6 +102,8 @@ namespace bin {
V(Process_Pid, 1) \
V(Process_SetSignalHandler, 1) \
V(Process_ClearSignalHandler, 1) \
V(ProcessInfo_CurrentRSS, 0) \
V(ProcessInfo_MaxRSS, 0) \
V(SecureSocket_Connect, 7) \
V(SecureSocket_Destroy, 1) \
V(SecureSocket_FilterPointer, 1) \
+20
View File
@@ -366,6 +366,26 @@ void FUNCTION_NAME(StringToSystemEncoding)(Dart_NativeArguments args) {
Dart_SetReturnValue(args, external_array);
}
void FUNCTION_NAME(ProcessInfo_CurrentRSS)(Dart_NativeArguments args) {
int64_t current_rss = Process::CurrentRSS();
if (current_rss < 0) {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
return;
}
Dart_SetIntegerReturnValue(args, current_rss);
}
void FUNCTION_NAME(ProcessInfo_MaxRSS)(Dart_NativeArguments args) {
int64_t max_rss = Process::MaxRSS();
if (max_rss < 0) {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
return;
}
Dart_SetIntegerReturnValue(args, max_rss);
}
} // namespace bin
} // namespace dart
+3
View File
@@ -146,6 +146,9 @@ class Process {
intptr_t* pid);
static Dart_Handle SetProcessIdNativeField(Dart_Handle process, intptr_t pid);
static int64_t CurrentRSS();
static int64_t MaxRSS();
private:
static int global_exit_code_;
static Mutex* global_exit_code_mutex_;
+36
View File
@@ -20,8 +20,10 @@
#include "bin/dartutils.h"
#include "bin/fdutils.h"
#include "bin/file.h"
#include "bin/lockers.h"
#include "bin/log.h"
#include "bin/reference_counting.h"
#include "bin/thread.h"
#include "platform/signal_blocker.h"
@@ -887,6 +889,40 @@ intptr_t Process::CurrentProcessId() {
}
int64_t Process::CurrentRSS() {
// The second value in /proc/self/statm is the current RSS in pages.
File* statm = File::Open("/proc/self/statm", File::kRead);
if (statm == NULL) {
return -1;
}
RefCntReleaseScope<File> releaser(statm);
const intptr_t statm_length = 1 * KB;
void* buffer = reinterpret_cast<void*>(Dart_ScopeAllocate(statm_length));
const intptr_t statm_read = statm->Read(buffer, statm_length);
if (statm_read <= 0) {
return -1;
}
int64_t current_rss_pages = 0;
int matches = sscanf(reinterpret_cast<char*>(buffer), "%*s%" Pd64 "",
&current_rss_pages);
if (matches != 1) {
return -1;
}
return current_rss_pages * getpagesize();
}
int64_t Process::MaxRSS() {
struct rusage usage;
usage.ru_maxrss = 0;
int r = getrusage(RUSAGE_SELF, &usage);
if (r < 0) {
return -1;
}
return usage.ru_maxrss * KB;
}
static Mutex* signal_mutex = new Mutex();
static SignalInfo* signal_handlers = NULL;
static const int kSignalsCount = 7;
+21
View File
@@ -431,6 +431,27 @@ intptr_t Process::CurrentProcessId() {
}
int64_t Process::CurrentRSS() {
mx_info_task_stats_t task_stats;
mx_handle_t process = mx_process_self();
mx_status_t status = mx_object_get_info(
process, MX_INFO_TASK_STATS, &task_stats, sizeof(task_stats), NULL, NULL);
if (status != NO_ERROR) {
// TODO(zra): Translate this to a Unix errno.
errno = status;
return -1;
}
return task_stats.mem_committed_bytes;
}
int64_t Process::MaxRSS() {
// There is currently no way to get the high watermark value on Fuchsia, so
// just return the current RSS value.
return CurrentRSS();
}
static bool ProcessWaitCleanup(intptr_t out,
intptr_t err,
intptr_t exit_event,
+37
View File
@@ -15,13 +15,16 @@
#include <stdio.h> // NOLINT
#include <stdlib.h> // NOLINT
#include <string.h> // NOLINT
#include <sys/resource.h> // NOLINT
#include <sys/wait.h> // NOLINT
#include <unistd.h> // NOLINT
#include "bin/dartutils.h"
#include "bin/fdutils.h"
#include "bin/file.h"
#include "bin/lockers.h"
#include "bin/log.h"
#include "bin/reference_counting.h"
#include "bin/thread.h"
#include "platform/signal_blocker.h"
@@ -887,6 +890,40 @@ intptr_t Process::CurrentProcessId() {
}
int64_t Process::CurrentRSS() {
// The second value in /proc/self/statm is the current RSS in pages.
File* statm = File::Open("/proc/self/statm", File::kRead);
if (statm == NULL) {
return -1;
}
RefCntReleaseScope<File> releaser(statm);
const intptr_t statm_length = 1 * KB;
void* buffer = reinterpret_cast<void*>(Dart_ScopeAllocate(statm_length));
const intptr_t statm_read = statm->Read(buffer, statm_length);
if (statm_read <= 0) {
return -1;
}
int64_t current_rss_pages = 0;
int matches = sscanf(reinterpret_cast<char*>(buffer), "%*s%" Pd64 "",
&current_rss_pages);
if (matches != 1) {
return -1;
}
return current_rss_pages * getpagesize();
}
int64_t Process::MaxRSS() {
struct rusage usage;
usage.ru_maxrss = 0;
int r = getrusage(RUSAGE_SELF, &usage);
if (r < 0) {
return -1;
}
return usage.ru_maxrss * KB;
}
static Mutex* signal_mutex = new Mutex();
static SignalInfo* signal_handlers = NULL;
static const int kSignalsCount = 7;
+25
View File
@@ -14,6 +14,7 @@
#endif
#include <errno.h> // NOLINT
#include <fcntl.h> // NOLINT
#include <mach/mach.h> // NOLINT
#include <poll.h> // NOLINT
#include <signal.h> // NOLINT
#include <stdio.h> // NOLINT
@@ -968,6 +969,30 @@ intptr_t Process::CurrentProcessId() {
}
int64_t Process::CurrentRSS() {
struct mach_task_basic_info info;
mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
kern_return_t result =
task_info(mach_task_self(), MACH_TASK_BASIC_INFO,
reinterpret_cast<task_info_t>(&info), &infoCount);
if (result != KERN_SUCCESS) {
return -1;
}
return info.resident_size;
}
int64_t Process::MaxRSS() {
struct rusage usage;
usage.ru_maxrss = 0;
int r = getrusage(RUSAGE_SELF, &usage);
if (r < 0) {
return -1;
}
return usage.ru_maxrss;
}
static Mutex* signal_mutex = new Mutex();
static SignalInfo* signal_handlers = NULL;
static const int kSignalsCount = 7;
+24
View File
@@ -165,6 +165,30 @@ class _ProcessUtils {
}
}
@patch
class ProcessInfo {
@patch
static int get maxRss {
var result = _maxRss();
if (result is OSError) {
throw result;
}
return result;
}
@patch
static int get currentRss {
var result = _currentRss();
if (result is OSError) {
throw result;
}
return result;
}
static _maxRss() native "ProcessInfo_MaxRSS";
static _currentRss() native "ProcessInfo_CurrentRSS";
}
class _ProcessStartStatus {
int _errorCode; // Set to OS error code if process start failed.
String _errorMessage; // Set to OS error message if process start failed.
+12
View File
@@ -92,6 +92,18 @@ void FUNCTION_NAME(StringToSystemEncoding)(Dart_NativeArguments args) {
DartUtils::NewInternalError("Process is not supported on this platform"));
}
void FUNCTION_NAME(ProcessInfo_CurrentRSS)(Dart_NativeArguments args) {
Dart_ThrowException(
DartUtils::NewInternalError("Process is not supported on this platform"));
}
void FUNCTION_NAME(ProcessInfo_MaxRSS)(Dart_NativeArguments args) {
Dart_ThrowException(
DartUtils::NewInternalError("Process is not supported on this platform"));
}
} // namespace bin
} // namespace dart
+19
View File
@@ -9,6 +9,7 @@
#include "bin/process.h"
#include <psapi.h> // NOLINT
#include <process.h> // NOLINT
#include "bin/builtin.h"
@@ -941,6 +942,24 @@ intptr_t Process::CurrentProcessId() {
}
int64_t Process::CurrentRSS() {
PROCESS_MEMORY_COUNTERS pmc;
if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
return -1;
}
return pmc.WorkingSetSize;
}
int64_t Process::MaxRSS() {
PROCESS_MEMORY_COUNTERS pmc;
if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
return -1;
}
return pmc.PeakWorkingSetSize;
}
static SignalInfo* signal_handlers = NULL;
static Mutex* signal_mutex = new Mutex();
+2 -1
View File
@@ -80,7 +80,8 @@ bool CanonicalName::IsMember() {
// Note the two occurrences of the parameter 'literal'.
#define COMPARE_NAME(canonical_name, literal) \
((canonical_name)->name()->size() == strlen(literal) && \
((canonical_name)->name()->size() == \
static_cast<intptr_t>(strlen(literal)) && \
memcmp((canonical_name)->name()->buffer(), (literal), strlen(literal)) == \
0)
+7 -2
View File
@@ -8,7 +8,9 @@
#include "vm/os.h"
#include <errno.h>
#include <magenta/process.h>
#include <magenta/syscalls.h>
#include <magenta/syscalls/object.h>
#include <magenta/types.h>
#include "platform/assert.h"
@@ -156,8 +158,11 @@ int OS::NumberOfAvailableProcessors() {
uintptr_t OS::MaxRSS() {
// TODO(US-95): Implement.
return 0;
mx_info_task_stats_t task_stats;
mx_handle_t process = mx_process_self();
mx_status_t status = mx_object_get_info(
process, MX_INFO_TASK_STATS, &task_stats, sizeof(task_stats), NULL, NULL);
return (status == NO_ERROR) ? task_stats.mem_committed_bytes : 0;
}
@@ -290,6 +290,19 @@ class _ProcessUtils {
}
}
@patch
class ProcessInfo {
@patch
static int get currentRss {
throw new UnsupportedError("ProcessInfo.currentRss");
}
@patch
static int get maxRss {
throw new UnsupportedError("ProcessInfo.maxRss");
}
}
@patch
class Process {
@patch
+27
View File
@@ -99,6 +99,33 @@ void sleep(Duration duration) {
*/
int get pid => _ProcessUtils._pid(null);
/**
* [ProcessInfo] provides methods for retrieving information about the
* current process.
*/
class ProcessInfo {
/**
* The current resident set size of memory for the process.
*
* Note that the meaning of this field is platform dependent. For example,
* some memory acounted for here may be shared with other processes, or if
* the same page is mapped into a process's address space, it may be counted
* twice.
*/
external static int get currentRss;
/**
* The high-watermark in bytes for the resident set size of memory for the
* process.
*
* Note that the meaning of this field is platform dependent. For example,
* some memory acounted for here may be shared with other processes, or if
* the same page is mapped into a process's address space, it may be counted
* twice.
*/
external static int get maxRss;
}
/**
* Modes for running a new process.
*/
@@ -0,0 +1,19 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import "dart:io";
import "package:expect/expect.dart";
main() {
int currentRss = ProcessInfo.currentRss;
print('currentRss = $currentRss');
Expect.isTrue(currentRss > 0);
int maxRss = ProcessInfo.maxRss;
print('maxRss = $maxRss');
Expect.isTrue(maxRss > 0);
Expect.isTrue(currentRss <= maxRss);
}