Attempt at expressing location of resources and weak memory accesses #496
+1,562
−481
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
loc_idis a logical location from which you can observe memory,on l psays thatpis true at locationl, locations can be e.g.:on thrid (x |-> y)means that when thread number thrid reads the variablexit will reliably gety)yafter doing a memory fence)ybut only if you do an atomic read on the atomic variable first)placeless pmeans you can unconditionally move them anywhere, e.g.,pure,inv,on, ghost references, etc.is_sync pmeans you can unconditionally move them, but only to threads of the same processis_send pmeans you can move them to threads of the same process, but only after a memory fence operationTo check out the interface, a good place to look is the diff for
Pulse.Lib.Core.fstiandPulse.Lib.SendSync.fsti.The formalization is very, uhhm, "flexifoundational". It basically sets
loc_id = unit, and then everything could be proven. This is not even an empty guarantee, it shows that you can't prove false from these axioms.Pain points:
inv i (on l p)or some variation to make the slprop placeless. I'm playing with having a custom invariant module that automates this to some degree (i.e.better_inv i pwould requireis_sync pand in return you getis_sync (better_inv i p), which would be enough for mutexes etc.)tradeandshift(which requires the closure to be duplicable). This approach would add a lot of other useful restrictions to the mix: sending a trade across threads requires an is_sync closure, sending a trade across devices requires a placeless closure, pulling a trade out of a later requires a timeless closure, etc. Obviously, some might want a duplicable+timeless+is_sync trade too... You can work around this a bit withon, but I foresee a plethora of trade variants.Fun points:
There are still lots of admits everywhere, but this PR should be enough to give a general idea of how the approach works.