Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new device model #26

warner opened this issue Apr 23, 2019 · 4 comments


None yet
2 participants
Copy link

commented Apr 23, 2019

@dtribble and I walked through a new device model this morning, and I think it makes enough sense to implement eventually:

  • devices are represented by a new slot type, so {type: 'device', id}
  • these are Vat imports just like promises and exports of other vats
  • they can be shared with other Vats by including them as an argument in syscall.send, etc
  • they are not valid as a target of syscall.send
  • a new syscall.invoke(deviceImport, args, slots) -> (args, slots) is used instead

syscall.invoke is like syscall.send but it is synchronous: the device is invoked immediately, and it can return an arbitrary immediate value (whereas send only returns a promiseID). This lets it be used for synchronous table lookup or modification.

For the inbound-comms-vat use case, we were thinking that devices are allowed to put deliveries onto a special queue that gets handled before the regular run-queue.

The bootstrap vat would get all configured devices as arguments of the iniital bootstrap() call, just like it currently gets references to the root object of all pre-configured vats. It could then share these with other vats as it sees fit. This means both the bootstrap vat and the recipient vat are sharing access, which makes Dean nervous, so he'd like to see some sort of getExclusive call. We might implement this by adding a method to each device that returns a new device handle (and revokes access from any old ones). He was also somewhat concerned about authenticity: if we're going to handle devices like we do Purses (where deposit is sort of a "get exclusive"), then it'd be nice if vats had access to the Issuer, so they could check that the device handle they received is really from the Issuer they know. But I thought that if we add a special pathway for them to get the Issuer, we could just give them the device directly, and all Vats are already relying upon the bootstrap vat anyways.

The API of a Vat is still pure data, so I don't think this will make migration any more difficult. And it removes the current raw-JS-object endowment pattern, which should make it easier. It means devices are only slightly more powerful than regular references: the one thing they add is synchronous invocation.


This comment has been minimized.

Copy link

commented Apr 23, 2019

We must be very careful with synchronous effects, as the turn within which they happen may subsequently abort. In that case, all effects should be as-if never happened. Also, all synchronous perceiving of effects must be deterministically replayable.


This comment has been minimized.

Copy link
Member Author

commented Apr 23, 2019

For the latter, we currently record all syscalls (and their return results) in the transcript. Specifically, we record all kernel-to-userspace dispatch calls, within which we record the list of syscalls made by userspace back into the kernel while that dispatch was active.

When we restore a vat from the saved state, we replay the dispatch calls but replace the syscall object with one that compares-and-ignores (and also returns the same recorded return value as before), so the kernel won't observe any outputs from the vat during the playback. But the Vat shouldn't be able to distinguish the replay from the original.

By routing userspace-to-device access through the syscall API, we get this same deterministic replay for free. The vat won't be interacting with the real device during replay, but it will get the same return values that it got the first time around. Any since the device-to-userspace pathway goes through the run-queue (albeit a higher-priority one that should always be empty in a checkpoint), all those messages are effectively captured in the vat's transcript.

Of course, the device itself must be restored to the same state too. Devices, like the kernel, will add their own state into the machine-wide state vector, right next to the vat transcripts. I think that will be sufficient, as long as we have some interlocks to prevent the device from e.g. submitting any vat messages before we've replayed all the vat transcripts.

I haven't thought so much about turn aborts. I expect this is the spot where devices must promise to buffer their effects until a checkpoint has been taken.

warner added a commit that referenced this issue Apr 29, 2019

rename device files in anticipation of changes
A new device model is on the way in #26, so make room for it.

warner added a commit that referenced this issue Apr 30, 2019

implement first phase of new device model
This adds machine-wide "device nodes", which are references to objects
exported by some named "device". Devices are a lot like Vats, with slots and
import/export tables, except:

* vats can invoke device nodes synchronously
* devices do not participate in Promises

All device nodes are provided to the bootstrap function, which can
disseminate them to other vats at its discretion.

Only basic zero-argument invocation has been tested so far. Still to do:

* passing interesting arguments
* passing device nodes between vats
* device state management
* vat state management in the presence of device calls
* devices adding calls to the run queue
* liveSlots wrappers for device nodes
* a new 'deviceSlots' helper for writing devices

refs #26

@dckc dckc referenced this issue Apr 30, 2019


It's About Time #99

0 of 6 tasks complete

warner added a commit that referenced this issue May 1, 2019


This comment has been minimized.

Copy link
Member Author

commented May 1, 2019

Remaining tasks:

  • test one device invocation returning a new device node
  • test passing device nodes between vats
  • liveSlots wrappers for device nodes: retval = D(devnode).method(args)
  • add deviceSlots helper for writing devices
  • devices can add calls to the run queue (sendOnly())
  • device state management
  • test vat state management in the presence of device calls

warner added a commit that referenced this issue May 1, 2019

Merge branch '26-devices'
* add SO(presence) to let device code sendOnly() to vats
* more tests

refs #26

warner added a commit that referenced this issue May 2, 2019


This comment has been minimized.

Copy link
Member Author

commented May 2, 2019

Ok, I think that should get us started.

@warner warner closed this May 2, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.