monte-language / typhon

A virtual machine for Monte.
Other
66 stars 10 forks source link

It's About Time #99

Open MostAwesomeDude opened 8 years ago

MostAwesomeDude commented 8 years ago

Timing effects generated by the tokenBucket and loopingCall modules are terrible. When I try to reason about their behavior, I'm rapidly blocked by a lack of clear semantics for Timer and other clocks. How Timer interacts with vat scheduling is possibly a problem as well.

I am relatively sure that my current complaints with Timer are driven by the fact that it's currently tricky to put things into their own vats. However, at the same time, knowing how vat scheduling works, I'm not sure how to get Timer to be sufficiently fair.

How does Erlang schedule? Their timers are unsafe but their scheduling is surely worth examining.

Current suggestions for what to build/design:

libuv uv_hrtime gives us a high-resolution monotonic timestamp. We can cache it at the beginning of the turn on each vat. Python time.time() gives us a high-resolution wall-clock timestamp, and we can also cache that.

washort commented 8 years ago

I don't think we need to worry about unsafety of timers, so long as their outputs are loggable (I expect it'll be a while before we build a loggable-determinism version of the runtime though)

Erlang does preemptive scheduling, with context switch points embedded in every loop of every builtin function, etc. We'd need a preemptible stack for that.

dckc commented 8 years ago

Timer has safe and unsafe methods, right? That seems awkward, to me. I'd much rather have separate objects. Yes, somebody could make a facet, but it's better to be safe by default, no? That is: it's better to make the easy thing the safe thing.

dckc commented 8 years ago

I'm looking at the help... "An unsafe nondeterministic clock." er... that seems overly scary. The fromNow and sendTimestamp methods are no more unsafe than file or network I/O. And the fact the a clock is nondeterministic seems self-evident.

The unsafeNow() method lets you observe two different times in the same turn, which can screw with the whole deterministic fail-stop goal. I'd rather it were hung on a totally different object. Putting it on the currentRuntime would work for me.

washort commented 8 years ago

Observing two different times in the same turn is fine. A system built for deterministic replay could replay the exact same timestamps.

dckc commented 8 years ago

Then why can't we have synchronous file I/O? I thought I/O had to be between turns. Surely reading the clock is I/O.

washort commented 8 years ago

Under normal operation the clock is read-only and monotonic, whereas files are mutable.

zarutian commented 8 years ago

I have no idea if this adds to the discussion or not but I am going to leave it here anyway.

washort commented 7 years ago

Disregard the above, I was clearly too optimistic.

The crucial problem with the idea of logging timer outputs is that it only needs to be done when a turn crashes, and that's when you can't guarantee it can be logged.

There are two purposes to determinism relevant here: Accurate debugging, and inward bit confinement.

When replaying code for debugging, it's important to have the same behavior as when it ran the first time. If the vat crashed before the log could be written, there's no way to determine that with an accurate timer.

When running confined code, accurate timers could make wall-banging easier, increasing the data rate of side channels.

Therefore I think we need a safe-scope object that provides a timestamp from the start of the turn, and an unsafe-scope object that provides accurate timing.

MostAwesomeDude commented 7 years ago

This was an excellent IRC discussion. I agree. Of the suggestions, I like M.now() the best. It would presumably carry a POSIX UTC timestamp, in seconds, as a Double. Or something like that.

dckc commented 5 years ago

The agoric folks are talking about a "device model" with synchronous invocation. https://github.com/Agoric/SwingSet/issues/26

seems fraught with peril, to me