Skip to content

Commit

Permalink
fixup! feat(swingset): send to promise avoid trip through run-queue
Browse files Browse the repository at this point in the history
Restore and add comments on refcounts and queues
  • Loading branch information
mhofman committed May 4, 2022
1 parent 6207d22 commit b5d2908
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
10 changes: 9 additions & 1 deletion packages/SwingSet/src/kernel/kernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,9 @@ export default function buildKernel(
let useMeter = false;
let deliverP = null;

// The common action should be delivering events to the vat. Any references
// in the events should no longer be the kernel's responsibility and the
// refcounts should be decremented
if (message.type === 'send') {
useMeter = true;
const route = routeSendEvent(message);
Expand All @@ -890,6 +893,8 @@ export default function buildKernel(
decrementSendEventRefCount(message);
deliverP = processSend(vatID, route.target, message.msg);
} else {
// Message is requeued and stays the kernel's responsibility, do not
// decrement refcounts in this case
kernelKeeper.addMessageToPromiseQueue(route.target, message.msg);
}
}
Expand Down Expand Up @@ -1096,14 +1101,17 @@ export default function buildKernel(
/** @type { PolicyInput } */
const policyInput = ['none'];

// By default we're moving events from one queue to another. Any references
// in the events remain the kernel's responsibility and the refcounts persist
if (message.type === 'send') {
const route = routeSendEvent(message);
if (!route) {
// Message went splat
// Message went splat, no longer the kernel's responsibility
decrementSendEventRefCount(message);
} else {
const { vatID, target } = route;
if (target !== message.target) {
// Message has been re-targeted, other refcounts stay intact
kernelKeeper.decrementRefCount(message.target, `deq|msg|t`);
kernelKeeper.incrementRefCount(target, `enq|msg|t`);
}
Expand Down
17 changes: 17 additions & 0 deletions packages/SwingSet/src/kernel/state/kernelKeeper.js
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,23 @@ export default function makeKernelKeeper(
insistKernelType('promise', kernelSlot);
insistMessage(msg);

// Each message on a promise's queue maintains a refcount to the promise
// itself. This isn't strictly necessary (the promise will be kept alive
// by the deciding vat's clist, or the queued message that holds this
// promise as its result), but it matches our policy with run-queue
// messages (each holds a refcount on its target).
//
// Messages are enqueued on a promise queue in 2 cases:
// - A message routed from the acceptance queue
// - A pipelined message had a decider change while in the run-queue
// Messages are dequeued from a promise queue in 2 cases:
// - The promise is resolved
// - The promise's decider is changed to a pipelining vat
// In all cases the messages are just moved from one queue to another so
// the caller should not need to change the refcounts when moving messages
// sent to promises between queues. Only when re-targeting after resolution
// would the targets refcount be updated (but not the result or slots).

const p = getKernelPromise(kernelSlot);
assert(
p.state === 'unresolved',
Expand Down

0 comments on commit b5d2908

Please sign in to comment.