Skip to content

Commit

Permalink
On Linux, respect memory limit from cgroups (oven-sh#5849)
Browse files Browse the repository at this point in the history
* Implement `process.constrainedMemory()`

* Add a comment

* Handle max

* Missing header

* We can use WTF::ramSize now

* Update WebKit

* Update ZigGlobalObject.cpp

* WebKit

* ✂️

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
  • Loading branch information
Jarred-Sumner and Jarred-Sumner authored Sep 21, 2023
1 parent abfc10a commit d1e9b33
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 59 deletions.
Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/runtime/nodejs-apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ The table below lists all globals implemented by Node.js and Bun's current compa

### [`process`](https://nodejs.org/api/process.html)

🟡 Missing `process.allowedNodeEnvironmentFlags` `process.channel` `process.constrainedMemory()` `process.getActiveResourcesInfo/setActiveResourcesInfo()` `process.setuid/setgid/setegid/seteuid/setgroups()` `process.hasUncaughtExceptionCaptureCallback` `process.initGroups()` `process.report` `process.resourceUsage()`. `process.binding` is partially implemented.
🟡 Missing `process.allowedNodeEnvironmentFlags` `process.channel` `process.getActiveResourcesInfo/setActiveResourcesInfo()` `process.setuid/setgid/setegid/seteuid/setgroups()` `process.hasUncaughtExceptionCaptureCallback` `process.initGroups()` `process.report` `process.resourceUsage()`. `process.binding` is partially implemented.

### [`queueMicrotask()`](https://developer.mozilla.org/en-US/docs/Web/API/queueMicrotask)

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"@types/react": "^18.0.25",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0",
"bun-webkit": "0.0.1-4d995edbc44062b251be638818edcd88d7d14dd7"
"bun-webkit": "0.0.1-f8aa36d4737faee92bd2d1e337a2fd01a5437c61"
},
"version": "0.0.0",
"prettier": "./.prettierrc.cjs"
Expand Down
8 changes: 8 additions & 0 deletions packages/bun-types/globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,14 @@ interface Process {
* @param listener The event handler function
*/
listenerCount(eventName: string | symbol, listener?: Function): number;

/**
* Get the constrained memory size for the process.
*
* On Linux, this is the memory limit for the process, accounting for cgroups 1 and 2.
* On other operating systems, this returns `undefined`.
*/
constrainedMemory(): number | undefined;
}

interface MemoryUsageObject {
Expand Down
11 changes: 11 additions & 0 deletions src/bun.js/bindings/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1328,6 +1328,16 @@ static Process* getProcessObject(JSC::JSGlobalObject* lexicalGlobalObject, JSVal
return process;
}

JSC_DEFINE_HOST_FUNCTION(Process_functionConstrainedMemory,
(JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
#if OS(LINUX) || OS(FREEBSD)
return JSValue::encode(jsDoubleNumber(static_cast<double>(WTF::ramSize())));
#else
return JSValue::encode(jsUndefined());
#endif
}

JSC_DEFINE_HOST_FUNCTION(Process_functionCpuUsage,
(JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
Expand Down Expand Up @@ -1864,6 +1874,7 @@ extern "C" void Process__emitDisconnectEvent(Zig::GlobalObject* global)
chdir Process_functionChdir Function 1
config constructProcessConfigObject PropertyCallback
connected processConnected CustomAccessor
constrainedMemory Process_functionConstrainedMemory Function 0
cpuUsage Process_functionCpuUsage Function 1
cwd Process_functionCwd Function 1
debugPort processDebugPort CustomAccessor
Expand Down
114 changes: 58 additions & 56 deletions src/bun.js/bindings/Process.lut.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// File generated via `make static-hash-table` / `make cpp`
static const struct CompactHashIndex processObjectTableIndex[267] = {
{ 47, -1 },
static const struct CompactHashIndex processObjectTableIndex[268] = {
{ 48, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
Expand All @@ -14,9 +14,9 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 20, -1 },
{ 21, -1 },
{ -1, -1 },
{ 49, -1 },
{ 50, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
Expand All @@ -41,14 +41,14 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 34, -1 },
{ 35, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 29, -1 },
{ 13, -1 },
{ 30, -1 },
{ 14, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
Expand All @@ -57,11 +57,11 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 59, -1 },
{ 60, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 55, -1 },
{ 56, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
Expand All @@ -75,36 +75,36 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 43, -1 },
{ 44, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 0, -1 },
{ 28, -1 },
{ 37, -1 },
{ 42, -1 },
{ 29, -1 },
{ 38, -1 },
{ 43, -1 },
{ -1, -1 },
{ 25, -1 },
{ 12, -1 },
{ 26, -1 },
{ 13, -1 },
{ -1, -1 },
{ -1, -1 },
{ 62, -1 },
{ 63, -1 },
{ -1, -1 },
{ -1, -1 },
{ 33, -1 },
{ 44, -1 },
{ 34, -1 },
{ 45, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 26, -1 },
{ 27, -1 },
{ -1, -1 },
{ -1, -1 },
{ 22, -1 },
{ 23, -1 },
{ -1, -1 },
{ 5, -1 },
{ -1, -1 },
{ 64, -1 },
{ 65, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
Expand All @@ -115,19 +115,19 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 27, 261 },
{ 28, 262 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 23, 262 },
{ 24, 263 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 50, 265 },
{ 51, 266 },
{ -1, -1 },
{ 19, -1 },
{ 20, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
Expand All @@ -139,10 +139,10 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 17, 257 },
{ 18, 257 },
{ -1, -1 },
{ 14, -1 },
{ 57, -1 },
{ 15, -1 },
{ 58, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
Expand All @@ -161,37 +161,37 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 3, 266 },
{ 3, 267 },
{ 1, -1 },
{ -1, -1 },
{ 63, -1 },
{ 64, -1 },
{ -1, -1 },
{ 11, -1 },
{ 12, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 56, -1 },
{ 57, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 10, 256 },
{ -1, -1 },
{ 16, 263 },
{ 17, 264 },
{ -1, -1 },
{ 39, -1 },
{ 40, -1 },
{ -1, -1 },
{ 41, -1 },
{ 42, -1 },
{ -1, -1 },
{ 38, -1 },
{ 6, 264 },
{ 11, 260 },
{ 6, 265 },
{ -1, -1 },
{ -1, -1 },
{ 4, -1 },
{ 51, -1 },
{ 52, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
Expand All @@ -205,11 +205,11 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 31, 260 },
{ 32, 261 },
{ -1, -1 },
{ -1, -1 },
{ 48, -1 },
{ 18, 258 },
{ 49, -1 },
{ 19, 258 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
Expand All @@ -219,10 +219,10 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 53, -1 },
{ 54, -1 },
{ -1, -1 },
{ 32, -1 },
{ 24, -1 },
{ 33, -1 },
{ 25, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
Expand All @@ -233,12 +233,12 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 52, -1 },
{ 53, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 15, 259 },
{ 16, 259 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
Expand All @@ -256,20 +256,21 @@ static const struct CompactHashIndex processObjectTableIndex[267] = {
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ 21, -1 },
{ 30, -1 },
{ 35, -1 },
{ 22, -1 },
{ 31, -1 },
{ 36, -1 },
{ 40, -1 },
{ 45, -1 },
{ 37, -1 },
{ 39, -1 },
{ 41, -1 },
{ 46, -1 },
{ 54, -1 },
{ 58, -1 },
{ 60, -1 },
{ 47, -1 },
{ 55, -1 },
{ 59, -1 },
{ 61, -1 },
{ 62, -1 },
};

static const struct HashTableValue processObjectTableValues[65] = {
static const struct HashTableValue processObjectTableValues[66] = {
{ "abort"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, Process_functionAbort, 1 } },
{ "allowedNodeEnvironmentFlags"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, Process_stubEmptySet } },
{ "arch"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, constructArch } },
Expand All @@ -281,6 +282,7 @@ static const struct HashTableValue processObjectTableValues[65] = {
{ "chdir"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, Process_functionChdir, 1 } },
{ "config"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, constructProcessConfigObject } },
{ "connected"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, processConnected, setProcessConnected } },
{ "constrainedMemory"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, Process_functionConstrainedMemory, 0 } },
{ "cpuUsage"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, Process_functionCpuUsage, 1 } },
{ "cwd"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, Process_functionCwd, 1 } },
{ "debugPort"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, processDebugPort, setProcessDebugPort } },
Expand Down Expand Up @@ -338,4 +340,4 @@ static const struct HashTableValue processObjectTableValues[65] = {
};

static const struct HashTable processObjectTable =
{ 65, 255, true, nullptr, processObjectTableValues, processObjectTableIndex };
{ 66, 255, true, nullptr, processObjectTableValues, processObjectTableIndex };
10 changes: 10 additions & 0 deletions test/js/node/process/process.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -487,3 +487,13 @@ it("dlopen args parsing", () => {
expect(() => process.dlopen({ module: { exports: Symbol("123") } }, "/tmp/not-found.so")).toThrow();
expect(() => process.dlopen({ module: { exports: Symbol("123") } }, Symbol("badddd"))).toThrow();
});

it("process.constrainedMemory()", () => {
if (process.platform === "linux") {
// On Linux, it returns 0 if the kernel doesn't support it
expect(process.constrainedMemory() >= 0).toBe(true);
} else {
// On unsupported platforms, it returns undefined
expect(process.constrainedMemory()).toBeUndefined();
}
});

0 comments on commit d1e9b33

Please sign in to comment.