-
Notifications
You must be signed in to change notification settings - Fork 4
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
mutex(opA) not defined in language manual #27
Comments
Yes, you're right, it doesn't make this clear and it should. Thanks for raising it. @tomooda ? |
I agree to make it clearer, and I have one question: |
Hmm. Well, who knows what the "rules" are here, but both VDMJ and VDMTools don't allow
|
I recall from many lightyears ago when I did some operational specification of VDM++ that mutex is indeed a bit peculiar and in fact no more than a bit of syntactic sugar to express the relationship between the number of times an operation has been called and exited. Intuitively mutex should of course not be allowed to recurse. Its like Engering a critical section with a binary semaphore at operation calling level.But it is so long ago that I might be mistaken..... Op 26 jan. 2023 10:30 schreef Nick Battle ***@***.***>:
Hmm. Well, who knows what the "rules" are here, but both VDMJ and VDMTools don't allow mutex(op) to recurse:
class A
operations
public op: nat ==> nat
op(a) == if a = 0 then return 1 else return a * op(a-1);
sync
mutex(op)
end A
p new A().op(5)
Exception: DEADLOCK detected
> p new A().op(5)
No precise position information available:
Run-Time Error 263: Deadlock is detected
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
Traditionally, mutex is a pair of atomic counting operations of in/out as @nlmave commented. These days some languages/libraries also provide recursive mutex (e.g. std::recursive_mutex in C++) for synchronization allowing recursion. Considering that the current description in the LRM goes along the syntactic definition
|
@tomooda please correct me if I am wrong. But is your suggestion not a bit misleading, as writing As I understand it, the behavior of |
@mortenhaahr Oh, I didn't know the difference in the semantics between a single operation and multiple operations specified. Indeed it shows complex behavior. With multiple operations specified in a mutex, self-recursion is OK, but mutual recursion between two operations makes deadlock. Hmm.
> p new A().op(5) |
Hmm... as Marcel said, the mutex is syntactic sugar, and is translated into a permission predicate over the operation(s) concerned. I think this is in line with what the LRM says in section 14.1, though perhaps there is something missing? In the example above, each operation gets a predicate like So yes, with multiple operations in the mutex you are allowed to recurse, in VDMJ. But is that as intended? I note that VDMTools has a different interpretation, deadlocking a recursion too. @tomooda, can you find out how this is translated into per-clauses?
|
Maybe |
That makes some sense, but it's not what the example translation in the LRM says/implies. Can/did you check the actual VDMTools translation? |
VDMTools/spec/cg-spec/mod_conc.vdm seems to define the translation.
I also found a PDF document on vice (in Japanese) telling that
will be translated into the below
|
Interesting. Thanks for looking this up, Tomo. The example from the VDM spec makes sense, but it doesn't explicitly cover the single operation case - though surely it would just say The PDF example is more interesting because it is almost the same as the LRM example, except the translations include the "LHS" of each operation, whereas the LRM does not. So it looks like VDMJ is implementing the LRM scheme (probably based on the earlier CSK documentation), whereas VDMTools is implementing the example above. Ironically, it would be easier to do things the VDMTools way, because there is no special case for a single operation. I think the only difference is the case of recursion? Do we have any other sources for the correct VDM++ semantics here? |
Using #mutex(Op) should definitely not allow Op to recurse since this should be syntactic sugar for: per Op => #active(Op) = 0 |
Thanks Peter. What do you think the translations of |
class A sync end A should be a shorthand for: class A sync end A |
OK, that's what the LRM says and VDMJ implements, but VDMTools (including its documents and spec) is slightly different, including the LHS operation in each #active - so |
Please correct if I say wrong. Does the current VDMJ allow multiple threads to execute |
The #active count is across all threads for one object instance. So Hmm. So it's a sort of concurrent mutex, as things stand. I haven't actually tried this! Presumably the VDMTools interpretation only allows one thread to be calling op1 or op2? That is closer to what I thought a mutex should be doing, I must admit. The wording in the LRM is not clear at all, unfortunately. |
I think we understand the problem, but I don't see a single obvious solution. The definition in the LRM is incomplete because it does not cover a mutex on a single operation and also has a tricky difference from mutex used in other languages. VDMJ's implementation agrees with the LRM's mutex expansion rule and shares the same difference from the common mutex. VDMTools' implementation agrees with other languages' mutex but breaks compatibility with VDM10's semantics. |
Well in the VDM++ book from 2005 in the chapter on concurrency it is VERY clear what mutex(Op1) means on page 285. IMHO there should be NO need to have a RC for something that has been clear since then! |
Okay, I confirmed that So, as @mortenhaahr proposed at the very beginning, adding a complementary explanation and an example would be enough. How about the below?
@mortenhaahr , thank you for raising this issue. I might have messed up quite a bit, but this was really a good learning opportunity for me :-) |
I think the suggested addition looks great. And no worries @tomooda, it led to a very interesting discussion. In addition to what you proposed, I also suggest changing the introductory line as indicated in the beginning. I.e., changing the line: to: |
@mortenhaahr , yes, that addition is also helpful. Thank you for reminding me of it! |
add explanations of mutex as discussed in #27
Okay, I made a PR #28 and merged it into the editing branch. |
Great! I am closing this issue. |
Hi,
When I was studying for my exam I noticed that the language manual does not define the behavior of writing
mutex(opA)
as a permission predicate, i.e., thatopA
is to be executed mutually exclusively to itself.I suggest changing the line:
"A mutex predicate allows the user to specify either that all operations of the class are to be executed mutually exclusive, or that a list of operations are to be executed mutually exclusive to each other."
to:
"A mutex predicate allows the user to specify either that all operations of the class are to be executed mutually exclusive, an operation is to be executed mutually exclusive to itself, or that a list of operations is to be executed mutually exclusive to each other."
Furthermore, I suggest editing the example below the paragraph to include
mutex(opA)
(and changing the translated permission predicate accordingly).The text was updated successfully, but these errors were encountered: