@ai-ecoverse/slicc-kernel 1.66.1 → 1.67.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/driver-worker.js.map +2 -2
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +282 -38
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-driver-worker.js.map +2 -2
- package/dist/node-process-worker.js +67 -20
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +282 -38
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +149 -102
- package/dist/process-worker.js.map +4 -4
- package/package.json +1 -1
package/dist/node.js
CHANGED
|
@@ -5535,11 +5535,11 @@ var ChildTable = class {
|
|
|
5535
5535
|
return [...this.children.keys()];
|
|
5536
5536
|
}
|
|
5537
5537
|
captured(pid, slot2) {
|
|
5538
|
-
const
|
|
5539
|
-
const chunks2 =
|
|
5540
|
-
if (!
|
|
5541
|
-
|
|
5542
|
-
if (
|
|
5538
|
+
const slots2 = this.leftovers.get(pid);
|
|
5539
|
+
const chunks2 = slots2?.get(slot2);
|
|
5540
|
+
if (!slots2 || !chunks2) return new Uint8Array(0);
|
|
5541
|
+
slots2.delete(slot2);
|
|
5542
|
+
if (slots2.size === 0) this.leftovers.delete(pid);
|
|
5543
5543
|
return concat2(chunks2);
|
|
5544
5544
|
}
|
|
5545
5545
|
};
|
|
@@ -7011,7 +7011,9 @@ async function dispatchOne(entry, req) {
|
|
|
7011
7011
|
|
|
7012
7012
|
// src/realm/sync-sab-wire.ts
|
|
7013
7013
|
var SAB_HEADER_I32 = 16;
|
|
7014
|
-
var
|
|
7014
|
+
var SAB_CLOCK_OFFSET = SAB_HEADER_I32 * 4;
|
|
7015
|
+
var SAB_CLOCK_I64 = 3;
|
|
7016
|
+
var SAB_HEADER_BYTES = SAB_CLOCK_OFFSET + SAB_CLOCK_I64 * 8;
|
|
7015
7017
|
var SAB_I_STATE = 0;
|
|
7016
7018
|
var SAB_I_SEQ = 1;
|
|
7017
7019
|
var SAB_I_STATUS = 2;
|
|
@@ -7161,6 +7163,146 @@ function attachSyncSabResponder(port, sab, token, opts) {
|
|
|
7161
7163
|
};
|
|
7162
7164
|
}
|
|
7163
7165
|
|
|
7166
|
+
// src/kernel/cpu-clock.ts
|
|
7167
|
+
var IDLE_OPS = /* @__PURE__ */ new Set([
|
|
7168
|
+
"fd-select",
|
|
7169
|
+
"proc-wait",
|
|
7170
|
+
"proc-exec",
|
|
7171
|
+
"sig-pause",
|
|
7172
|
+
"sock-accept",
|
|
7173
|
+
"sock-connect"
|
|
7174
|
+
]);
|
|
7175
|
+
var SYS_CAP_US = 2e4;
|
|
7176
|
+
var LOCAL = SAB_CLOCK_OFFSET;
|
|
7177
|
+
var IDLE = 1;
|
|
7178
|
+
function epochMicros() {
|
|
7179
|
+
return Math.floor((performance.timeOrigin + performance.now()) * 1e3);
|
|
7180
|
+
}
|
|
7181
|
+
function slots(sab) {
|
|
7182
|
+
return new BigInt64Array(sab, LOCAL, SAB_CLOCK_I64);
|
|
7183
|
+
}
|
|
7184
|
+
var rawWait = Atomics.wait.bind(Atomics);
|
|
7185
|
+
function localIdle(sab, now) {
|
|
7186
|
+
const state = Number(Atomics.load(slots(sab), IDLE));
|
|
7187
|
+
if (state >= 0) return { idle: state, waiting: false };
|
|
7188
|
+
return { idle: Math.max(0, now + state), waiting: true };
|
|
7189
|
+
}
|
|
7190
|
+
var CpuClock = class {
|
|
7191
|
+
start;
|
|
7192
|
+
sys = 0;
|
|
7193
|
+
idle = 0;
|
|
7194
|
+
since = 0;
|
|
7195
|
+
kind = "sys";
|
|
7196
|
+
stopped = false;
|
|
7197
|
+
last = { utime: 0, stime: 0 };
|
|
7198
|
+
sab;
|
|
7199
|
+
now;
|
|
7200
|
+
constructor(sab, now = epochMicros) {
|
|
7201
|
+
this.sab = sab;
|
|
7202
|
+
this.now = now;
|
|
7203
|
+
this.start = now();
|
|
7204
|
+
}
|
|
7205
|
+
enter(op) {
|
|
7206
|
+
this.since = this.now();
|
|
7207
|
+
this.kind = this.stopped || IDLE_OPS.has(op) ? "idle" : "sys";
|
|
7208
|
+
}
|
|
7209
|
+
leave() {
|
|
7210
|
+
if (this.since === 0) return;
|
|
7211
|
+
this.add((this.frozen ?? this.now()) - this.since);
|
|
7212
|
+
this.since = 0;
|
|
7213
|
+
}
|
|
7214
|
+
stop(stopped) {
|
|
7215
|
+
if (stopped === this.stopped) return;
|
|
7216
|
+
this.stopped = stopped;
|
|
7217
|
+
if (this.since === 0 || !stopped || this.frozen !== void 0) return;
|
|
7218
|
+
const now = this.now();
|
|
7219
|
+
this.add(now - this.since);
|
|
7220
|
+
this.since = now;
|
|
7221
|
+
this.kind = "idle";
|
|
7222
|
+
}
|
|
7223
|
+
frozen;
|
|
7224
|
+
freeze() {
|
|
7225
|
+
this.frozen ??= this.now();
|
|
7226
|
+
}
|
|
7227
|
+
running() {
|
|
7228
|
+
if (this.frozen !== void 0) return false;
|
|
7229
|
+
const now = this.now();
|
|
7230
|
+
const busy = this.since === 0 || this.kind === "sys" && now - this.since < SYS_CAP_US;
|
|
7231
|
+
return busy && !localIdle(this.sab, now).waiting;
|
|
7232
|
+
}
|
|
7233
|
+
times() {
|
|
7234
|
+
const now = this.frozen ?? this.now();
|
|
7235
|
+
const open = this.since === 0 ? 0 : Math.max(0, now - this.since);
|
|
7236
|
+
const busy = this.kind === "sys" ? Math.min(open, SYS_CAP_US) : 0;
|
|
7237
|
+
const sys = this.sys + busy;
|
|
7238
|
+
const idle = this.idle + (open - busy) + localIdle(this.sab, now).idle;
|
|
7239
|
+
const user = Math.max(0, now - this.start - sys - idle);
|
|
7240
|
+
this.last = {
|
|
7241
|
+
utime: Math.max(this.last.utime, Math.floor(user / 1e3)),
|
|
7242
|
+
stime: Math.max(this.last.stime, Math.floor(sys / 1e3))
|
|
7243
|
+
};
|
|
7244
|
+
return this.last;
|
|
7245
|
+
}
|
|
7246
|
+
add(micros) {
|
|
7247
|
+
const spent = Math.max(0, micros);
|
|
7248
|
+
const busy = this.kind === "sys" ? Math.min(spent, SYS_CAP_US) : 0;
|
|
7249
|
+
this.sys += busy;
|
|
7250
|
+
this.idle += spent - busy;
|
|
7251
|
+
}
|
|
7252
|
+
};
|
|
7253
|
+
var ProcessClocks = class {
|
|
7254
|
+
main;
|
|
7255
|
+
threads = /* @__PURE__ */ new Map();
|
|
7256
|
+
ended = { utime: 0, stime: 0 };
|
|
7257
|
+
enabled;
|
|
7258
|
+
constructor(sab, enabled = true, states) {
|
|
7259
|
+
this.main = new CpuClock(sab);
|
|
7260
|
+
this.enabled = enabled;
|
|
7261
|
+
states?.onState((state) => this.stop(state === "stopped"));
|
|
7262
|
+
}
|
|
7263
|
+
thread(tid, sab) {
|
|
7264
|
+
const clock = new CpuClock(sab);
|
|
7265
|
+
this.threads.set(tid, clock);
|
|
7266
|
+
return clock;
|
|
7267
|
+
}
|
|
7268
|
+
threadEnded(tid) {
|
|
7269
|
+
const spent = this.threads.get(tid)?.times();
|
|
7270
|
+
this.threads.delete(tid);
|
|
7271
|
+
if (!spent) return;
|
|
7272
|
+
this.ended.utime += spent.utime;
|
|
7273
|
+
this.ended.stime += spent.stime;
|
|
7274
|
+
}
|
|
7275
|
+
stop(stopped) {
|
|
7276
|
+
for (const c of this.all()) c.stop(stopped);
|
|
7277
|
+
}
|
|
7278
|
+
freeze() {
|
|
7279
|
+
for (const c of this.all()) c.freeze();
|
|
7280
|
+
}
|
|
7281
|
+
times() {
|
|
7282
|
+
if (!this.enabled) return void 0;
|
|
7283
|
+
const sum = { ...this.ended };
|
|
7284
|
+
for (const c of this.all()) {
|
|
7285
|
+
const t = c.times();
|
|
7286
|
+
sum.utime += t.utime;
|
|
7287
|
+
sum.stime += t.stime;
|
|
7288
|
+
}
|
|
7289
|
+
return sum;
|
|
7290
|
+
}
|
|
7291
|
+
running() {
|
|
7292
|
+
return this.enabled ? this.all().filter((c) => c.running()).length : 0;
|
|
7293
|
+
}
|
|
7294
|
+
timed(clock, dispatch2) {
|
|
7295
|
+
const c = clock ?? this.main;
|
|
7296
|
+
return (req) => {
|
|
7297
|
+
c.enter(req.op);
|
|
7298
|
+
return dispatch2(req).finally(() => c.leave());
|
|
7299
|
+
};
|
|
7300
|
+
}
|
|
7301
|
+
all() {
|
|
7302
|
+
return [this.main, ...this.threads.values()];
|
|
7303
|
+
}
|
|
7304
|
+
};
|
|
7305
|
+
|
|
7164
7306
|
// src/kernel/net/loopback-names.ts
|
|
7165
7307
|
var HOST_LOOPBACK = "host.slicc.internal";
|
|
7166
7308
|
var HOST_LOOPBACK_ADDRESS = [10, 0, 2, 2];
|
|
@@ -7472,8 +7614,8 @@ function pidStat(info, boot) {
|
|
|
7472
7614
|
0,
|
|
7473
7615
|
0,
|
|
7474
7616
|
0,
|
|
7475
|
-
0,
|
|
7476
|
-
0,
|
|
7617
|
+
ticks(info.utime ?? 0),
|
|
7618
|
+
ticks(info.stime ?? 0),
|
|
7477
7619
|
0,
|
|
7478
7620
|
0,
|
|
7479
7621
|
20,
|
|
@@ -7567,19 +7709,23 @@ function systemFile(name2, listing, now, memory) {
|
|
|
7567
7709
|
if (name2 === "meminfo") {
|
|
7568
7710
|
return memoryInfo(
|
|
7569
7711
|
memory,
|
|
7570
|
-
listing.processes.reduce((
|
|
7712
|
+
listing.processes.reduce((sum2, p) => sum2 + p.memory, 0)
|
|
7571
7713
|
);
|
|
7572
7714
|
}
|
|
7573
7715
|
const live = listing.processes.filter((p) => p.state !== "Z");
|
|
7574
7716
|
if (name2 === "loadavg") {
|
|
7575
7717
|
const last = Math.max(0, ...listing.processes.map((p) => p.pid));
|
|
7576
|
-
|
|
7718
|
+
const [one, five, fifteen] = (listing.load ?? [0, 0, 0]).map((n) => n.toFixed(2));
|
|
7719
|
+
return `${one} ${five} ${fifteen} 1/${live.length} ${last}
|
|
7577
7720
|
`;
|
|
7578
7721
|
}
|
|
7579
|
-
const
|
|
7722
|
+
const sum = (key) => listing.cpu?.[key] ?? listing.processes.reduce((n, p) => n + (p[key] ?? 0), 0);
|
|
7723
|
+
const user = ticks(sum("utime"));
|
|
7724
|
+
const system = ticks(sum("stime"));
|
|
7725
|
+
const idle = listing.cpu ? ticks(listing.cpu.idle) : Math.max(0, ticks(now - listing.boot) - user - system);
|
|
7580
7726
|
return [
|
|
7581
|
-
`cpu
|
|
7582
|
-
`cpu0
|
|
7727
|
+
`cpu ${user} 0 ${system} ${idle} 0 0 0 0 0 0`,
|
|
7728
|
+
`cpu0 ${user} 0 ${system} ${idle} 0 0 0 0 0 0`,
|
|
7583
7729
|
"intr 0",
|
|
7584
7730
|
"ctxt 0",
|
|
7585
7731
|
`btime ${Math.floor(listing.boot / 1e3)}`,
|
|
@@ -10172,8 +10318,8 @@ function ptySyscall(req, ctx) {
|
|
|
10172
10318
|
var RUN_CAPTURE_CAP = 64 * 1024 * 1024;
|
|
10173
10319
|
var RUN_MAX_BUFFER = 1024 * 1024;
|
|
10174
10320
|
function capLimit(maxBuffer) {
|
|
10175
|
-
const asked = maxBuffer ===
|
|
10176
|
-
return Math.
|
|
10321
|
+
const asked = typeof maxBuffer === "number" && maxBuffer >= 0 ? maxBuffer : RUN_MAX_BUFFER;
|
|
10322
|
+
return Math.min(asked, RUN_CAPTURE_CAP);
|
|
10177
10323
|
}
|
|
10178
10324
|
function slot(how, n, extra) {
|
|
10179
10325
|
if (how === "inherit") return { fd: n };
|
|
@@ -10199,6 +10345,7 @@ async function reaped(deps, pid) {
|
|
|
10199
10345
|
}
|
|
10200
10346
|
}
|
|
10201
10347
|
async function runChild(req, deps) {
|
|
10348
|
+
if (!isSignal(req.killSignal)) throw new KernelError("EINVAL");
|
|
10202
10349
|
const max = capLimit(req.maxBuffer);
|
|
10203
10350
|
let failure;
|
|
10204
10351
|
let pid = 0;
|
|
@@ -12039,6 +12186,9 @@ function killThread(thread, caught, sig) {
|
|
|
12039
12186
|
blocked.abort();
|
|
12040
12187
|
return true;
|
|
12041
12188
|
}
|
|
12189
|
+
function threadSignalsOf(sab) {
|
|
12190
|
+
return { header: new Int32Array(sab, 0, SAB_HEADER_I32), interrupt: new AbortController() };
|
|
12191
|
+
}
|
|
12042
12192
|
function threadCancel(thread) {
|
|
12043
12193
|
return Atomics.load(thread.header, SAB_I_SIGNALS) !== 0 ? AbortSignal.abort() : thread.interrupt.signal;
|
|
12044
12194
|
}
|
|
@@ -12164,6 +12314,22 @@ function processOptions(opts, header4, hooks, created3) {
|
|
|
12164
12314
|
...opts.program.abi === "wasi" || opts.program.abi === "js" ? { pendingBits: () => Atomics.load(header4, SAB_I_SIGNALS) } : {}
|
|
12165
12315
|
};
|
|
12166
12316
|
}
|
|
12317
|
+
function threadInit(opts, program, sab, cred, thread) {
|
|
12318
|
+
return {
|
|
12319
|
+
type: WASM_THREAD_INIT,
|
|
12320
|
+
pid: opts.shownPid ?? opts.pid,
|
|
12321
|
+
program,
|
|
12322
|
+
argv0: opts.argv0,
|
|
12323
|
+
args: opts.args,
|
|
12324
|
+
env: opts.env,
|
|
12325
|
+
cwd: opts.cwd,
|
|
12326
|
+
sab,
|
|
12327
|
+
cred: copyCred(cred),
|
|
12328
|
+
owners: opts.owners === true,
|
|
12329
|
+
...opts.ppid !== void 0 ? { ppid: opts.ppid } : {},
|
|
12330
|
+
thread
|
|
12331
|
+
};
|
|
12332
|
+
}
|
|
12167
12333
|
function spawnWasmProcess(opts) {
|
|
12168
12334
|
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
12169
12335
|
const header4 = new Int32Array(sab, 0, SAB_HEADER_I32);
|
|
@@ -12196,7 +12362,10 @@ function spawnWasmProcess(opts) {
|
|
|
12196
12362
|
const worker = opts.createWorker();
|
|
12197
12363
|
const dying = new Dying();
|
|
12198
12364
|
const dispatch2 = (req) => dying.serving(() => isWasmSyscall(req) ? process2.syscall(req) : dispatchSyncFs(req));
|
|
12199
|
-
const
|
|
12365
|
+
const clocks = new ProcessClocks(sab, opts.program.abi !== "js", process2);
|
|
12366
|
+
const responder = attachSyncSabResponder(worker, sab, token, {
|
|
12367
|
+
dispatch: clocks.timed(void 0, dispatch2)
|
|
12368
|
+
});
|
|
12200
12369
|
const lane = opts.program.abi === "js" ? openLane(token, dispatch2) : void 0;
|
|
12201
12370
|
const { promise: exited, resolve: settle } = Promise.withResolvers();
|
|
12202
12371
|
let done4 = false;
|
|
@@ -12204,6 +12373,7 @@ function spawnWasmProcess(opts) {
|
|
|
12204
12373
|
const finish = (code, sig) => {
|
|
12205
12374
|
if (done4) return;
|
|
12206
12375
|
done4 = true;
|
|
12376
|
+
clocks.freeze();
|
|
12207
12377
|
dying.clear();
|
|
12208
12378
|
endedBy = sig ?? process2.execTermsig;
|
|
12209
12379
|
worker.removeEventListener("message", onMessage);
|
|
@@ -12244,6 +12414,7 @@ function spawnWasmProcess(opts) {
|
|
|
12244
12414
|
const endThread = (tid) => {
|
|
12245
12415
|
const end = threads.get(tid);
|
|
12246
12416
|
threads.delete(tid);
|
|
12417
|
+
clocks.threadEnded(tid);
|
|
12247
12418
|
process2.threadEnded(tid);
|
|
12248
12419
|
end?.();
|
|
12249
12420
|
};
|
|
@@ -12257,15 +12428,14 @@ function spawnWasmProcess(opts) {
|
|
|
12257
12428
|
}
|
|
12258
12429
|
const tsab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
12259
12430
|
const tw = opts.createWorker();
|
|
12260
|
-
const tsignals =
|
|
12261
|
-
header: new Int32Array(tsab, 0, SAB_HEADER_I32),
|
|
12262
|
-
interrupt: new AbortController()
|
|
12263
|
-
};
|
|
12431
|
+
const tsignals = threadSignalsOf(tsab);
|
|
12264
12432
|
threadSignals.set(thread.tid, tsignals);
|
|
12265
12433
|
const tdispatch = (req) => dying.serving(
|
|
12266
12434
|
() => isWasmSyscall(req) ? process2.syscall(req, threadCancel(tsignals)) : dispatchSyncFs(req)
|
|
12267
12435
|
);
|
|
12268
|
-
const tresponder = attachSyncSabResponder(tw, tsab, token, {
|
|
12436
|
+
const tresponder = attachSyncSabResponder(tw, tsab, token, {
|
|
12437
|
+
dispatch: clocks.timed(clocks.thread(thread.tid, tsab), tdispatch)
|
|
12438
|
+
});
|
|
12269
12439
|
const onThreadMessage = (event) => {
|
|
12270
12440
|
const data = event.data;
|
|
12271
12441
|
if (data?.type === WASM_THREAD_EXIT) endThread(thread.tid);
|
|
@@ -12280,21 +12450,7 @@ function spawnWasmProcess(opts) {
|
|
|
12280
12450
|
tresponder.dispose();
|
|
12281
12451
|
tw.terminate();
|
|
12282
12452
|
});
|
|
12283
|
-
|
|
12284
|
-
type: WASM_THREAD_INIT,
|
|
12285
|
-
pid: opts.shownPid ?? opts.pid,
|
|
12286
|
-
program,
|
|
12287
|
-
argv0: opts.argv0,
|
|
12288
|
-
args: opts.args,
|
|
12289
|
-
env: opts.env,
|
|
12290
|
-
cwd: opts.cwd,
|
|
12291
|
-
sab: tsab,
|
|
12292
|
-
cred: copyCred(process2.cred),
|
|
12293
|
-
owners: opts.owners === true,
|
|
12294
|
-
...opts.ppid !== void 0 ? { ppid: opts.ppid } : {},
|
|
12295
|
-
thread
|
|
12296
|
-
};
|
|
12297
|
-
tw.postMessage(tinit);
|
|
12453
|
+
tw.postMessage(threadInit(opts, program, tsab, process2.cred, thread));
|
|
12298
12454
|
};
|
|
12299
12455
|
worker.postMessage(
|
|
12300
12456
|
processInit(opts, sab, process2.umask, copyCred(process2.cred), lane?.lane),
|
|
@@ -12319,7 +12475,9 @@ function spawnWasmProcess(opts) {
|
|
|
12319
12475
|
signalMasks: () => process2.signalMasks(),
|
|
12320
12476
|
umask: () => process2.umask,
|
|
12321
12477
|
cred: () => copyCred(process2.cred),
|
|
12322
|
-
writesBack: () => opts.program.abi === "wasi" && !done4
|
|
12478
|
+
writesBack: () => opts.program.abi === "wasi" && !done4,
|
|
12479
|
+
times: () => clocks.times(),
|
|
12480
|
+
running: () => clocks.running()
|
|
12323
12481
|
};
|
|
12324
12482
|
}
|
|
12325
12483
|
|
|
@@ -14738,6 +14896,8 @@ var LAYOUT = [
|
|
|
14738
14896
|
["/usr", 493],
|
|
14739
14897
|
["/usr/local", 493]
|
|
14740
14898
|
];
|
|
14899
|
+
var LOAD_SAMPLE_MS = 5e3;
|
|
14900
|
+
var LOAD_WINDOWS_MS = [6e4, 3e5, 9e5];
|
|
14741
14901
|
var encoder3 = new TextEncoder();
|
|
14742
14902
|
var USERS_MODES = ["off", "report", "enforce"];
|
|
14743
14903
|
function usersMode(mode = "off") {
|
|
@@ -15266,6 +15426,7 @@ var Launcher = class {
|
|
|
15266
15426
|
return this.jobs.sessionOf(pgid);
|
|
15267
15427
|
}
|
|
15268
15428
|
start(req) {
|
|
15429
|
+
this.sampling();
|
|
15269
15430
|
if (req.pgid !== void 0 && this.jobs.sessionOf(req.pgid) === void 0) {
|
|
15270
15431
|
throw fsError("ESRCH", `no process group ${req.pgid}`);
|
|
15271
15432
|
}
|
|
@@ -15306,7 +15467,12 @@ var Launcher = class {
|
|
|
15306
15467
|
forker: this.forker(pid, req),
|
|
15307
15468
|
kill: (target, sig) => this.kill(target, sig, this.credOf(pid), pid),
|
|
15308
15469
|
writesBack: (target) => this.processes.get(target)?.writesBack() === true,
|
|
15309
|
-
processes: () => ({
|
|
15470
|
+
processes: () => ({
|
|
15471
|
+
boot: this.boot,
|
|
15472
|
+
processes: this.list(this.credOf(pid)),
|
|
15473
|
+
load: this.loadAverage(),
|
|
15474
|
+
cpu: this.cpuTotal()
|
|
15475
|
+
}),
|
|
15310
15476
|
sudo: (call, signal) => this.sudo(pid, call, signal),
|
|
15311
15477
|
openFiles: this.openFiles,
|
|
15312
15478
|
nodes: this.nodes,
|
|
@@ -15340,7 +15506,14 @@ var Launcher = class {
|
|
|
15340
15506
|
started: Date.now()
|
|
15341
15507
|
});
|
|
15342
15508
|
void handle.exited.then(() => {
|
|
15509
|
+
const spent = handle.times?.();
|
|
15510
|
+
if (spent) this.spent.set(pid, spent);
|
|
15343
15511
|
this.processes.delete(pid);
|
|
15512
|
+
if (this.processes.size === 0) {
|
|
15513
|
+
clearInterval(this.sampler);
|
|
15514
|
+
this.sampler = void 0;
|
|
15515
|
+
this.idleSince = Date.now();
|
|
15516
|
+
}
|
|
15344
15517
|
this.settling.settled(pid);
|
|
15345
15518
|
if (req.ppid === void 0 || this.orphans.delete(pid)) this.forget(pid);
|
|
15346
15519
|
else this.zombies.add(pid);
|
|
@@ -15356,6 +15529,12 @@ var Launcher = class {
|
|
|
15356
15529
|
forget(pid) {
|
|
15357
15530
|
this.jobs.remove(pid);
|
|
15358
15531
|
this.described.delete(pid);
|
|
15532
|
+
const spent = this.spent.get(pid);
|
|
15533
|
+
if (spent) {
|
|
15534
|
+
this.reapedTimes.utime += spent.utime;
|
|
15535
|
+
this.reapedTimes.stime += spent.stime;
|
|
15536
|
+
}
|
|
15537
|
+
this.spent.delete(pid);
|
|
15359
15538
|
this.creds.delete(pid);
|
|
15360
15539
|
this.tags.delete(pid);
|
|
15361
15540
|
this.granted.delete(pid);
|
|
@@ -15364,6 +15543,70 @@ var Launcher = class {
|
|
|
15364
15543
|
if (this.zombies.delete(pid)) this.forget(pid);
|
|
15365
15544
|
else this.orphans.add(pid);
|
|
15366
15545
|
}
|
|
15546
|
+
load = [0, 0, 0];
|
|
15547
|
+
sampler;
|
|
15548
|
+
reapedTimes = { utime: 0, stime: 0 };
|
|
15549
|
+
idleAt = { wall: this.boot, busy: 0, idle: 0 };
|
|
15550
|
+
cpuTotal(now = Date.now()) {
|
|
15551
|
+
const total = { ...this.reapedTimes };
|
|
15552
|
+
const add = (t) => {
|
|
15553
|
+
total.utime += t?.utime ?? 0;
|
|
15554
|
+
total.stime += t?.stime ?? 0;
|
|
15555
|
+
};
|
|
15556
|
+
for (const handle of this.processes.values()) add(handle.times?.());
|
|
15557
|
+
for (const t of this.spent.values()) add(t);
|
|
15558
|
+
const busy = total.utime + total.stime;
|
|
15559
|
+
const at = this.idleAt;
|
|
15560
|
+
at.idle += Math.max(0, now - at.wall - (busy - at.busy));
|
|
15561
|
+
at.wall = Math.max(at.wall, now);
|
|
15562
|
+
at.busy = Math.max(at.busy, busy);
|
|
15563
|
+
return { ...total, idle: at.idle };
|
|
15564
|
+
}
|
|
15565
|
+
loadAverage() {
|
|
15566
|
+
return this.load;
|
|
15567
|
+
}
|
|
15568
|
+
sampledAt = Date.now();
|
|
15569
|
+
sampleLoad(now = Date.now()) {
|
|
15570
|
+
let running = 0;
|
|
15571
|
+
for (const handle of this.processes.values()) running += handle.running?.() ?? 0;
|
|
15572
|
+
const elapsed = Math.max(LOAD_SAMPLE_MS, now - this.sampledAt);
|
|
15573
|
+
this.sampledAt = Math.max(this.sampledAt, now);
|
|
15574
|
+
this.load = this.load.map((avg, i) => {
|
|
15575
|
+
const window = LOAD_WINDOWS_MS[i];
|
|
15576
|
+
const fresh2 = 1 - Math.exp(-LOAD_SAMPLE_MS / window);
|
|
15577
|
+
return avg * Math.exp(-elapsed / window) + running * fresh2;
|
|
15578
|
+
});
|
|
15579
|
+
}
|
|
15580
|
+
idleSince;
|
|
15581
|
+
sampling() {
|
|
15582
|
+
if (this.sampler) return;
|
|
15583
|
+
if (this.idleSince !== void 0) {
|
|
15584
|
+
const empty = Math.max(0, Date.now() - this.idleSince);
|
|
15585
|
+
this.load = this.load.map(
|
|
15586
|
+
(avg, i) => avg * Math.exp(-empty / LOAD_WINDOWS_MS[i])
|
|
15587
|
+
);
|
|
15588
|
+
}
|
|
15589
|
+
this.sampledAt = Date.now();
|
|
15590
|
+
this.sampler = setInterval(() => this.sampleLoad(), LOAD_SAMPLE_MS);
|
|
15591
|
+
this.sampler.unref?.();
|
|
15592
|
+
}
|
|
15593
|
+
spent = /* @__PURE__ */ new Map();
|
|
15594
|
+
timesAt(pid) {
|
|
15595
|
+
return this.processes.get(pid)?.times?.() ?? this.spent.get(pid);
|
|
15596
|
+
}
|
|
15597
|
+
timesOf(member, members) {
|
|
15598
|
+
let utime = 0;
|
|
15599
|
+
let stime = 0;
|
|
15600
|
+
let timed2 = false;
|
|
15601
|
+
for (let at = member; at; at = members.get(at.execParent ?? -1)) {
|
|
15602
|
+
const t = this.timesAt(at.pid);
|
|
15603
|
+
if (!t) continue;
|
|
15604
|
+
timed2 = true;
|
|
15605
|
+
utime += t.utime;
|
|
15606
|
+
stime += t.stime;
|
|
15607
|
+
}
|
|
15608
|
+
return timed2 ? { utime, stime } : {};
|
|
15609
|
+
}
|
|
15367
15610
|
list(viewer = ROOT) {
|
|
15368
15611
|
const members = new Map(this.jobs.list().map((member) => [member.pid, member]));
|
|
15369
15612
|
const rootOf = (member) => {
|
|
@@ -15395,6 +15638,7 @@ var Launcher = class {
|
|
|
15395
15638
|
started: (this.described.get(root.pid) ?? described2).started,
|
|
15396
15639
|
state: this.processes.has(member.pid) ? "S" : "Z",
|
|
15397
15640
|
memory: this.processes.get(member.pid)?.memory() ?? 0,
|
|
15641
|
+
...this.timesOf(member, members),
|
|
15398
15642
|
umask: this.umaskOf(member.pid),
|
|
15399
15643
|
cred,
|
|
15400
15644
|
...this.signalMasksOf(member.pid)
|