[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:
@@ -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
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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 "",
|
||||
¤t_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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 "",
|
||||
¤t_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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user