Skip to content

Commit

Permalink
src,lib: add constrainedMemory API for process
Browse files Browse the repository at this point in the history
  • Loading branch information
theanarkh committed Jan 20, 2023
1 parent 5d50b84 commit 1ac7401
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 2 deletions.
22 changes: 22 additions & 0 deletions doc/api/process.md
Original file line number Diff line number Diff line change
Expand Up @@ -1103,6 +1103,27 @@ and [Cluster][] documentation), the `process.connected` property will return
Once `process.connected` is `false`, it is no longer possible to send messages
over the IPC channel using `process.send()`.

## `process.constrainedMemory()`

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental
* {number}

Gets the amount of memory available to the process (in bytes) based on
limits imposed by the OS. If there is no such constraint, or the constraint
is unknown, `undefined` is returned.

It is not unusual for this value to be less than or greater than `os.totalmem()`.
This function currently only returns a non-zero value on Linux, based on cgroups
if it is present, and on z/OS based on `RLIMIT_MEMLIMIT`.

See [`uv_get_constrained_memory`][uv_get_constrained_memory] for more
information.

## `process.cpuUsage([previousValue])`

<!-- YAML
Expand Down Expand Up @@ -3901,6 +3922,7 @@ cases:
[process_warning]: #event-warning
[report documentation]: report.md
[terminal raw mode]: tty.md#readstreamsetrawmodemode
[uv_get_constrained_memory]: https://docs.libuv.org/en/v1.x/misc.html#c.uv_get_constrained_memory
[uv_rusage_t]: https://docs.libuv.org/en/v1.x/misc.html#c.uv_rusage_t
[wikipedia_major_fault]: https://en.wikipedia.org/wiki/Page_fault#Major
[wikipedia_minor_fault]: https://en.wikipedia.org/wiki/Page_fault#Minor
1 change: 1 addition & 0 deletions lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ const rawMethods = internalBinding('process_methods');

process.hrtime = perThreadSetup.hrtime;
process.hrtime.bigint = perThreadSetup.hrtimeBigInt;
process.constrainedMemory = perThreadSetup.constrainedMemory;

process.openStdin = function() {
process.stdin.resume();
Expand Down
9 changes: 9 additions & 0 deletions lib/internal/process/per_thread.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const binding = internalBinding('process_methods');

let hrValues;
let hrBigintValues;
let constrainedMemoryValues;

function refreshHrtimeBuffer() {
// The 3 entries filled in by the original process.hrtime contains
Expand Down Expand Up @@ -100,6 +101,13 @@ function hrtimeBigInt() {
return hrBigintValues[0];
}

function constrainedMemory() {
const value = binding.constrainedMemory();
if (value > 0) {
return value;
}
}

function nop() {}

// The execution of this function itself should not cause any side effects.
Expand Down Expand Up @@ -427,4 +435,5 @@ module.exports = {
hrtime,
hrtimeBigInt,
refreshHrtimeBuffer,
constrainedMemory,
};
2 changes: 0 additions & 2 deletions lib/internal/process/pre_execution.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,7 @@ function refreshRuntimeOptions() {
function patchProcessObject(expandArgv1) {
const binding = internalBinding('process_methods');
binding.patchProcessObject(process);

require('internal/process/per_thread').refreshHrtimeBuffer();

ObjectDefineProperty(process, 'argv0', {
__proto__: null,
enumerable: true,
Expand Down
7 changes: 7 additions & 0 deletions src/node_process_methods.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,11 @@ static void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
: static_cast<double>(array_buffer_allocator->total_mem_usage());
}

static void GetConstrainedMemory(const FunctionCallbackInfo<Value>& args) {
double value = static_cast<double>(uv_get_constrained_memory());
args.GetReturnValue().Set(value);
}

void RawDebug(const FunctionCallbackInfo<Value>& args) {
CHECK(args.Length() == 1 && args[0]->IsString() &&
"must be called with a single string");
Expand Down Expand Up @@ -582,6 +587,7 @@ static void Initialize(Local<Object> target,

SetMethod(context, target, "umask", Umask);
SetMethod(context, target, "memoryUsage", MemoryUsage);
SetMethod(context, target, "constrainedMemory", GetConstrainedMemory);
SetMethod(context, target, "rss", Rss);
SetMethod(context, target, "cpuUsage", CPUUsage);
SetMethod(context, target, "resourceUsage", ResourceUsage);
Expand Down Expand Up @@ -612,6 +618,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(Umask);
registry->Register(RawDebug);
registry->Register(MemoryUsage);
registry->Register(GetConstrainedMemory);
registry->Register(Rss);
registry->Register(CPUUsage);
registry->Register(ResourceUsage);
Expand Down
12 changes: 12 additions & 0 deletions test/parallel/test-process-constrained-memory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';
require('../common');
const assert = require('assert');
const { Worker } = require('worker_threads');
const constrainedMemory = process.constrainedMemory();
if (constrainedMemory) {
assert(process.constrainedMemory() > 0);
}
if (!process.env.isWorker) {
process.env.isWorker = true;
new Worker(__filename);
}

0 comments on commit 1ac7401

Please sign in to comment.