@ai-ecoverse/slicc-kernel 1.17.1 → 1.17.3

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.
@@ -1761,6 +1761,19 @@ function cloexecPipe2(pipe2, deps) {
1761
1761
  return r;
1762
1762
  };
1763
1763
  }
1764
+ function quietTarget(dup3, deps) {
1765
+ return (fd = -1, newfd = -1, flags = 0, ...rest) => {
1766
+ const Fs = deps.fs();
1767
+ const target = fd === newfd || flags !== 0 ? void 0 : Fs?.getStream(newfd);
1768
+ if (target && Fs?.getStream(fd)) {
1769
+ try {
1770
+ Fs.close?.(target);
1771
+ } catch {
1772
+ }
1773
+ }
1774
+ return dup3(fd, newfd, flags, ...rest);
1775
+ };
1776
+ }
1764
1777
  function cloexecByFlag(syscall, flagArg, deps) {
1765
1778
  const mark = marker(deps);
1766
1779
  return (...args) => {
@@ -1777,7 +1790,7 @@ function wrapperFactories(deps) {
1777
1790
  ...timer ? { setitimer: (f) => kernelTimer(f, timer) } : {},
1778
1791
  fcntl: (f) => cloexecFcntl(f, deps),
1779
1792
  pipe2: (f) => cloexecPipe2(f, deps),
1780
- dup3: (f) => cloexecByFlag(f, 2, deps),
1793
+ dup3: (f) => cloexecByFlag(quietTarget(f, deps), 2, deps),
1781
1794
  socket: (f) => cloexecByFlag(f, 1, deps),
1782
1795
  accept4: (f) => cloexecByFlag(f, 3, deps),
1783
1796
  ...pty ? { ioctl: (f) => ptyIoctl(f, { fs: deps.fs, heap: deps.heap, kernel: pty }) } : {}
@@ -2749,7 +2762,7 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
2749
2762
  };
2750
2763
  return node;
2751
2764
  };
2752
- const find = (processes2, target, own) => processes2.find((p) => own ? p.tid === target : p.pid === target || p.tid === target);
2765
+ const find = (processes2, target, own) => (own ? processes2.find((p) => p.tid === target) : void 0) ?? processes2.find((p) => p.pid === target || p.tid === target);
2753
2766
  const infoOf = (target) => find(procList().processes, target, false);
2754
2767
  const pidContent = (target, name, own = false) => () => {
2755
2768
  const listing = procList();
@@ -3358,20 +3371,20 @@ function pathInode(path) {
3358
3371
  }
3359
3372
  return h;
3360
3373
  }
3361
- function cachingBridge(bridge) {
3374
+ function cachingBridge(bridge, now = () => performance.now()) {
3362
3375
  const stats = /* @__PURE__ */ new Map();
3363
3376
  const lstats = /* @__PURE__ */ new Map();
3364
3377
  const cached = (map, path, get) => {
3365
3378
  let hit = map.get(path);
3366
- if (hit === void 0) {
3379
+ if (hit === void 0 || "until" in hit && hit.until <= now()) {
3367
3380
  try {
3368
3381
  hit = get();
3369
3382
  } catch (e) {
3370
- hit = e;
3383
+ hit = { error: e, until: now() + MISS_TTL_MS };
3371
3384
  }
3372
3385
  map.set(path, hit);
3373
3386
  }
3374
- if (hit instanceof Error) throw hit;
3387
+ if ("until" in hit) throw hit.error;
3375
3388
  return hit;
3376
3389
  };
3377
3390
  const invalidate = () => {
@@ -3421,7 +3434,7 @@ function cachingBridge(bridge) {
3421
3434
  invalidate
3422
3435
  };
3423
3436
  }
3424
- var WasiError, FileBuffer, LocalFile;
3437
+ var WasiError, FileBuffer, LocalFile, MISS_TTL_MS;
3425
3438
  var init_wasi_files = __esm({
3426
3439
  "src/process/wasi/wasi-files.ts"() {
3427
3440
  "use strict";
@@ -3550,6 +3563,7 @@ var init_wasi_files = __esm({
3550
3563
  this.buffer.flush();
3551
3564
  }
3552
3565
  };
3566
+ MISS_TTL_MS = 20;
3553
3567
  }
3554
3568
  });
3555
3569
 
@@ -4312,27 +4326,30 @@ function pollOneoff(deps, inPtr, outPtr, nsubs, neventsPtr) {
4312
4326
  const subs = readSubscriptions(mem, inPtr, nsubs, deps.now);
4313
4327
  const { events, read, write } = classify(deps.fds, subs);
4314
4328
  let interrupted = false;
4329
+ const earliest = subs.reduce((min, s) => Math.min(min, s.deadline), Infinity);
4330
+ const expired = () => performance.now() + CLOCK_SLACK_MS >= earliest;
4315
4331
  if (read.length > 0 || write.length > 0 || events.length === 0) {
4316
- const earliest = Math.min(...subs.map((s) => s.deadline));
4317
- let timeoutMs = -1;
4318
- if (events.length > 0) timeoutMs = 0;
4319
- else if (earliest !== Infinity)
4320
- timeoutMs = Math.max(0, Math.ceil(earliest - performance.now()));
4321
- let ready;
4322
- try {
4323
- ready = kernel.call({ op: "fd-select", read, write, timeoutMs });
4324
- } catch (e) {
4325
- if (!deps.interruptWakes || e.code !== "EINTR") throw e;
4326
- interrupted = true;
4327
- ready = { read: [], write: [] };
4328
- }
4329
- events.push(
4330
- ...readyEvents(subs, ready)
4331
- );
4332
+ do {
4333
+ let timeoutMs = -1;
4334
+ if (events.length > 0) timeoutMs = 0;
4335
+ else if (earliest !== Infinity)
4336
+ timeoutMs = Math.max(0, Math.ceil(earliest - performance.now()));
4337
+ let ready;
4338
+ try {
4339
+ ready = kernel.call({ op: "fd-select", read, write, timeoutMs });
4340
+ } catch (e) {
4341
+ if (!deps.interruptWakes || e.code !== "EINTR") throw e;
4342
+ interrupted = true;
4343
+ ready = { read: [], write: [] };
4344
+ }
4345
+ events.push(
4346
+ ...readyEvents(subs, ready)
4347
+ );
4348
+ } while (events.length === 0 && !interrupted && earliest !== Infinity && !expired());
4332
4349
  }
4333
4350
  const after = performance.now();
4334
4351
  for (const s of subs) {
4335
- if (s.type === EVENTTYPE.CLOCK && (interrupted || s.deadline <= after + 0.5)) {
4352
+ if (s.type === EVENTTYPE.CLOCK && (interrupted || s.deadline <= after + CLOCK_SLACK_MS)) {
4336
4353
  events.push({ userdata: s.userdata, error: E.SUCCESS, type: s.type });
4337
4354
  }
4338
4355
  }
@@ -4340,10 +4357,12 @@ function pollOneoff(deps, inPtr, outPtr, nsubs, neventsPtr) {
4340
4357
  mem.view().setUint32(neventsPtr, events.length, true);
4341
4358
  return E.SUCCESS;
4342
4359
  }
4360
+ var CLOCK_SLACK_MS;
4343
4361
  var init_wasi_poll = __esm({
4344
4362
  "src/process/wasi/wasi-poll.ts"() {
4345
4363
  "use strict";
4346
4364
  init_wasi_abi();
4365
+ CLOCK_SLACK_MS = 0.5;
4347
4366
  }
4348
4367
  });
4349
4368
 
@@ -4471,19 +4490,25 @@ var init_wasi_host = __esm({
4471
4490
  ...this.statImports(),
4472
4491
  ...this.pathImports(),
4473
4492
  ...this.socketImports(),
4474
- poll_oneoff: (inPtr, outPtr, n, nevents) => pollOneoff(
4475
- {
4476
- mem: this.mem,
4477
- fds: this.fds,
4478
- kernel: this.o.kernel,
4479
- now: (id) => this.now(id),
4480
- interruptWakes: this.interruptWakes
4481
- },
4482
- inPtr,
4483
- outPtr,
4484
- n,
4485
- nevents
4486
- )
4493
+ poll_oneoff: (inPtr, outPtr, n, nevents) => {
4494
+ try {
4495
+ return pollOneoff(
4496
+ {
4497
+ mem: this.mem,
4498
+ fds: this.fds,
4499
+ kernel: this.o.kernel,
4500
+ now: (id) => this.now(id),
4501
+ interruptWakes: this.interruptWakes
4502
+ },
4503
+ inPtr,
4504
+ outPtr,
4505
+ n,
4506
+ nevents
4507
+ );
4508
+ } finally {
4509
+ this.o.fs.invalidate?.();
4510
+ }
4511
+ }
4487
4512
  });
4488
4513
  return this.cache;
4489
4514
  }