You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently permissions are merely names. However, Ward could be made significantly more powerful by extending the permission language with some notion of parameterisation on source program identifiers. To make this concrete, let's say we have some datastructure (call it Capability, drawing on the concept from GHC) which embeds a lock:
structCapability {
Mutexlock;
intsome_state;
};
We want to expose a function which can change some_state of a Capability yet only if the caller holds its lock. To do this we might define the following:
Where argument must be either a global variable or an identifier bound in the function's argument list. For simplicity, call sites of functions with such permissions would be restricted to only "trivial" parameters (e.g. just identifiers). This would allow permissions to be easily propagated from the call-site to the definition site. For instance,
WARD(need(may_take_capability_lock(cap))
voidset_state_to_zero(Capability*the_cap) {
acquire_capability_lock(the_cap);
// We now have holds_capability_lock(the_cap) in our contextset_state(the_cap, 0);
// By the definition given above, the above call requires that we// have holds_capability_lock(the_cap), which we indeed have.release_capability_lock(the_cap);
}
The arity of a capability is fixed in the configuration. For instance the Ward configuration for the above might look like:
holds_capability_lock(cap) "The given capability's lock is held";
may_take_capability_lock(cap) "The may take the given capability's lock";
Note that under this proposal arguments are untyped. That is, one is free to write seemingly nonsensical things like,
Additionally, the fact that permissions may take multiple arguments allows to represent relations between runtime values. For instance in GHC Tasks can "own" Capability's, allowing us to do some things in a lock-free manner,
__thread structTaskmy_task; // the current thread's taskWARD(need(task_owns_capability(my_task, cap)))
voiddo_something(Capability*cap) { /* ... */ }
Limitations
There are, of course, many cases that this minimal proposal is not able to cover. For instance,
voidset_all_to_zero(intn, Capabilities*caps[n]) {
for (inti=0; i<n; i++)
set_state_to_zero(caps[i]);
}
We sadly have no way to express the permission requirements of this function. To handle this we need the ability to embed permission actions in function bodies:
One could imagine further extending the permission syntax with:
argument := term [ '[' integer_literal ']' ]
term := c_identifier
| 'return'
which would allow a few more patterns to be captured. For instance, output parameters:
WARD(grant(may_take_capability_lock(cap[0])))
voidget_a_capability(Capability**cap) { /* cap is an output */*cap= ...;
}
Implementation
My suspicion is that nothing of the above should be particularly difficult to implement. The only non-trivial aspect the proposal is the argument renaming necessary at call-sites but this is a simple mechanical rewrite.
The text was updated successfully, but these errors were encountered:
Sounds good to me. IIRC I had this in mind to support the “domain locks” in Mono, where each MonoDomain has its own associated global lock. It’s just a matter of getting around to it…
I like the idea of supporting return to annotate the result value of a function, although it might be kinda fiddly to propagate that info up the call tree.
Have to check if this is allowed, but for annotations pertaining to parameters, I wonder if we could support attributes on the parameters themselves, e.g.:
Have to check if this is allowed, but for annotations pertaining to parameters, I wonder if we could support attributes on the parameters themselves, e.g.:
I think I would actually prefer to keep the annotation on the function. Afterall, a permission may in fact have more than one parameter, allowing one to represent relations between multiple terms in the source program (e.g. the Task/Capability example given in the description).
Currently permissions are merely names. However, Ward could be made significantly more powerful by extending the permission language with some notion of parameterisation on source program identifiers. To make this concrete, let's say we have some datastructure (call it
Capability
, drawing on the concept from GHC) which embeds a lock:We want to expose a function which can change
some_state
of aCapability
yet only if the caller holds its lock. To do this we might define the following:Here we have extended the permission language as follows:
Where
argument
must be either a global variable or an identifier bound in the function's argument list. For simplicity, call sites of functions with such permissions would be restricted to only "trivial" parameters (e.g. just identifiers). This would allow permissions to be easily propagated from the call-site to the definition site. For instance,The arity of a capability is fixed in the configuration. For instance the Ward configuration for the above might look like:
Note that under this proposal
argument
s are untyped. That is, one is free to write seemingly nonsensical things like,Additionally, the fact that permissions may take multiple arguments allows to represent relations between runtime values. For instance in GHC
Task
s can "own"Capability
's, allowing us to do some things in a lock-free manner,Limitations
There are, of course, many cases that this minimal proposal is not able to cover. For instance,
We sadly have no way to express the permission requirements of this function. To handle this we need the ability to embed permission actions in function bodies:
This of course makes
set_all_to_zero
part of the trusted codebase.Extensions
Return terms
We could do slightly better on the above case by extending our permission syntax with:
Where the
return
keyword denotes the return value of the function. This allows us to write:Allowing indexing
One could imagine further extending the permission syntax with:
which would allow a few more patterns to be captured. For instance, output parameters:
Implementation
My suspicion is that nothing of the above should be particularly difficult to implement. The only non-trivial aspect the proposal is the argument renaming necessary at call-sites but this is a simple mechanical rewrite.
The text was updated successfully, but these errors were encountered: