!standard A(3/4) 17-04-24 AI12-0200-1/05 !class binding interpretation 16-08-11 !status Amendment 1-2012 16-11-09 !status WG9 Approved 17-06-16 !status ARG Approved 10-1-1 (By Letter Ballot) 16-12-27 !status work item 16-12-05 !status ARG Approved 9-0-1 16-10-08 !status work item 16-08-11 !status received 16-06-12 !priority Low !difficulty Easy !qualifier Clarification !subject Improve reentrancy requirements for language-defined subprograms !summary Clarify that the reentrancy requirements for language-defined subprograms apply to any two language-defined subprograms with overlapping parameters. !question The wording in A(3/4) doesn't clearly state two (obvious?) requirements: 1) The requirement applies to calls to any pair of such subprograms, not just to two calls to the same subprogram. 2) The requirement applies in the case where the overlapping occurs between parameters of two different calls, not between two parameters of one call. Should this be clarified? (Yes.) !recommendation (See Summary.) !wording Replace A(3/4) by: The implementation shall ensure that concurrent calls on any two (possibly the same) language-defined subprograms perform as specified, so long as all pairs of objects (one from each call) that are either denoted by parameters that could be passed by reference, or are designated by parameters of an access type, are nonoverlapping. !discussion Point (1) was in fact one of the purposes of AI12-0052-1, changing the wording to "any language-defined subprogram" rather than "the same subprogram". We've simplified the wording to remove the use of the word "reentrant", as that doesn't seem to add anything other than making a long paragraph longer. !corrigendum A(3/4) @drepl The implementation shall ensure that each language-defined subprogram is reentrant in the sense that concurrent calls on any language-defined subprogram perform as specified, so long as all objects that are denoted by parameters that could be passed by reference or designated by parameters of an access type are nonoverlapping. @dby The implementation shall ensure that concurrent calls on any two (possibly the same) language-defined subprograms perform as specified, so long as all pairs of objects (one from each call) that are either denoted by parameters that could be passed by reference, or are designated by parameters of an access type, are nonoverlapping. !ASIS No ASIS effect. !ACATS test The absence of race conditions isn't directly testable; tests can depend on this property which may indirectly test for correct implementation. !appendix From: Randy Brukardt Sent: Tuesday, November 22, 2016 6:05 PM In his review of the minutes (aside: should be posted soon), Jeff notes that the AI12-0200-1 "doesn't flow". The approved wording is: The implementation shall ensure that each language-defined subprogram is reentrant in the sense that concurrent calls on any two (possibly the same) language-defined subprograms perform as specified, so long as all pairs of objects (one from each call) that {either} are denoted by parameters that could be passed by reference{,} or designated by parameters of an access type are nonoverlapping. --- The problem here is that the "are nonoverlapping" applies to both kinds of parameters; the inserted comma tends to make it read as if that only applies to the second part. Jeff suggested adding an "are" and another comma, thus: The implementation shall ensure that each language-defined subprogram is reentrant in the sense that concurrent calls on any two (possibly the same) language-defined subprograms perform as specified, so long as all pairs of objects (one from each call) that {either} are denoted by parameters that could be passed by reference{,} or {are} designated by parameters of an access type{,} are nonoverlapping. But I don't think that helps; now "are nonoverlapping" is completely hanging in space. The usual fix for such dangling items is to pull them to the front part: The implementation shall ensure that each language-defined subprogram is reentrant in the sense that concurrent calls on any two (possibly the same) language-defined subprograms perform as specified, so long as all pairs of objects (one from each call) {are nonoverlapping} that {either} are denoted by parameters that could be passed by reference{,} or {are} designated by parameters of an access type[ are nonoverlapping]. The "that" doesn't make much sense here, perhaps "if" would be better: The implementation shall ensure that each language-defined subprogram is reentrant in the sense that concurrent calls on any two (possibly the same) language-defined subprograms perform as specified, so long as all pairs of objects (one from each call) {are nonoverlapping if either} [that] are denoted by parameters that could be passed by reference{,} or {are} designated by parameters of an access type[ are nonoverlapping]. But this doesn't seem to have the right meaning (it seems to say that it applies if either parameter meets these requirements, the rule applies, while we want it to apply only if both parameters meet the requirements. I'm out of ideas at this point. Any better suggestions??? **************************************************************** From: Jeff Cousins Sent: Wednesday, November 23, 2016 4:32 AM > The implementation shall ensure that each language-defined subprogram is > reentrant in the sense that concurrent calls on any two (possibly the same) > language-defined subprograms perform as specified, so long as all pairs of > objects (one from each call) {are nonoverlapping if either} [that] are denoted > by parameters that could be passed by reference{,} or {are} designated by > parameters of an access type[ are nonoverlapping]. > But this doesn't seem to have the right meaning (it seems to say that it > applies if either parameter meets these requirements, the rule applies, while > we want it to apply only if both parameters meet the requirements. > I'm out of ideas at this point. Any better suggestions??? It's getting rather long for a single sentence, but here's another attempt: The implementation shall ensure that each language-defined subprogram is reentrant in the sense that concurrent calls on any two (possibly the same) language-defined subprograms perform as specified, so long as all pairs of objects (one from each call) {are nonoverlapping if both objects of such a pair are either} [that are] denoted by {a }parameter[s] that could be passed by reference or designated by {a }parameter[s] of an access type[ are nonoverlapping]. **************************************************************** From: John Barnes Sent: Wednesday, November 23, 2016 5:42 AM I don't think that putting "are overlapping" earlier helps at all. I think that Jeff's suggestion is not bad. However, I suggest reversing "either" and "are" so we end up with: The implementation shall ensure that each language-defined subprogram is reentrant in the sense that concurrent calls on any two (possibly the same) language-defined subprograms perform as specified, so long as all pairs of objects (one from each call) that are either denoted by parameters that could be passed by reference, or are designated by parameters of an access type, are nonoverlapping. I find it helps to remove square and curly brackets so that the result is clearer and then when satisified to put them back for the record. **************************************************************** From: Tullio Vardanega Sent: Wednesday, November 23, 2016 7:17 AM I like this version, both for formulation and absense of brackets. **************************************************************** From: Tucker Taft Sent: Wednesday, November 23, 2016 3:06 PM Johns version works for me. Next approach would probably be bullets, but John's seems good enough without them. **************************************************************** From: Randy Brukardt Sent: Wednesday, November 23, 2016 8:20 PM I prefer Jeff's (Wednesday) suggestion to Jeff's (Monday) suggestion as modified by John. But it appears that I'm outnumbered, so I'll shut up (at least until we have someone who can't understand it - that may be a while, since Adam isn't around anymore). **************************************************************** From: Erhard Ploedereder Sent: Thursday, November 24, 2016 8:56 PM I was on the verge of sending a long message about this being a really bad use or definition for reentrancy, which then made me think about the wording some more. I am sure that the words can be shortened to say: The implementation shall ensure that concurrent calls on any two (possibly the same) language-defined subprograms perform as specified, so long as all pairs of objects (one from each call) that are either denoted by parameters that could be passed by reference, or are designated by parameters of an access type, are nonoverlapping. one of the old versions for reference: > The implementation shall ensure that each language-defined subprogram is > reentrant in the sense that concurrent calls on any two (possibly the > same) language-defined subprograms perform as specified, so long as > all pairs of objects (one from each call) that are either denoted by > parameters that could be passed by reference, or are designated by > parameters of an access type, are nonoverlapping. I believe that this has very little to do with reentrancy in the first place. At the same time, I am not sure that you are not asking for too much. What about shared memory at the next level of reference, i.e. overlapping graphs. This then is supposed to work, as long as the entrances are disjoint? Nice, but do we want to promise that? Or are we sure that there are no such cases in language-defined packages ever, now and in the future? **************************************************************** From: Tucker Taft Sent: Friday, November 25, 2016 6:46 AM > I believe that this has very little to do with reentrancy in the first > place. Getting rid of the word "reentrant" does seem like a useful change, since we have argued about the meaning of "reentrant" but in fact that isn't particularly relevant to what we are trying to guarantee. > At the same time, I am not sure that you are not asking for too much. > What about shared memory at the next level of reference, i.e. > overlapping graphs. This then is supposed to work, as long as the > entrances are disjoint? Nice, but do we want to promise that? Or are we > sure that there are no such cases in language-defined packages ever, now > and in the future? Once you get to the second level, we can't make general statements any more, so perhaps we need to say "unless specified otherwise for a particular language-defined subprogram" or some such thing, though of course that makes the sentence even longer! **************************************************************** From: Erhard Ploedereder Sent: Sunday, November 27, 2016 4:32 PM > Once you get to the second level, we can't make general statements any > more, so perhaps we need to say "unless specified otherwise for a > particular language-defined subprogram" or some such thing, though of > course that makes the sentence even longer! Well, it is the globals of these subprograms, too. So, if any predefined package has state, that state is to be thread-safe by definition? The sentence seems to say so. **************************************************************** From: Tucker Taft Sent: Sunday, November 27, 2016 6:31 PM > Well, it is the globals of these subprograms, too. So, if any > predefined package has state, that state is to be thread-safe by > definition? The sentence seems to say so. Yes, I agree that is the intent. Local state should not be a concern of the user of a language-defined package, except for the special cases of Standard Input/Output/Error which are implicitly referenced by certain Text I/O ops. **************************************************************** From: Randy Brukardt Sent: Monday, November 28, 2016 12:29 AM That's not really in question, since we discussed this extensively in AI12-0052-1 and then added a Ramification (A (3.b.1/4)) which states as much. I hate rehashing decided topics... **************************************************************** From: Randy Brukardt Sent: Monday, November 28, 2016 12:40 AM >... > At the same time, I am not sure that you are not asking for too much. > What about shared memory at the next level of reference, i.e. > overlapping graphs. This then is supposed to work, as long as the > entrances are disjoint? Nice, but do we want to promise that? Yes, I don't think we have a choice. A programmer can avoid top-level overlapping objects, but they have no way to look inside of the implementation of the objects. (Nor should they be dependent on such implementation choices.) So implementations have to guarantee that and users of the predefined libraries should be able to depend on it. (I would say that implementations need to avoid second-level stuff that might be conflicting.) That is precisely how task-safety in Claw works -- we intended to follow the same rules as for the predefined library (they seemed to be the best trade-off of performance and safety). And second-level overlaps are locked as needed (that's how one passes a Claw object to a task - the task makes a clone of the original object which then can be used safely in the task). In general, we try to avoid such overlaps in order to avoid the need for locking overhead. I certainly think the same is the case for the language-defined packages. Else the A(3) rule would be worthless; one could never portably use any language-defined library such that it might be accessed by multiple tasks (there always might be some second-level item that isn't task safe). If there is some example where we really think that causes a hardship, we can consider making a special exception (as we did for Text_IO and global state). But the general case has to be task-safety so long as the A(3) rule is satisfied (no obvious overlap). **************************************************************** From: Randy Brukardt Sent: Monday, November 28, 2016 5:08 PM > > I believe that this has very little to do with reentrancy in the > > first place. > > Getting rid of the word "reentrant" does seem like a useful change, > since we have argued about the meaning of "reentrant" > but in fact that isn't particularly relevant to what we are trying to > guarantee. I don't feel strongly about this either way, but it does seem like more than an editorial change to me. Thus I think that we'll have to take a letter ballot on this newly proposed wording. (Since our next meeting isn't until June, we have plenty of time to do that and hopefully we don't have to use meeting time to discuss this topic again.) Before I do that, I'd like to hear from more than two ARG members. In particular, does anyone object to this change? **************************************************************** From: Tullio Vardanega Sent: Tuesday, November 29, 2016 12:10 AM Erhard's cut at the sentence works for me. I am not sure I want to argue whether this has little or more to do with reentrancy, but the sentence can surely do without the word reentrant. **************************************************************** From: Jeff Cousins Sent: Tuesday, November 29, 2016 1:40 AM So is Erhard's proposal (of the several) the one on the table? It's ok with me, getting rid of the word reentrant seems a good thing. **************************************************************** From: Randy Brukardt Sent: Tuesday, November 29, 2016 2:11 PM I treated the Jeff/John proposal as an editorial correction that everyone seemed to be happy with, and closed this topic. Erhard then reopened it with his proposal to remove a significant amount of the text. Since no one has opposed it yet, it seems that it ought to be pursued (less text is usually preferable). That's significant enough of a change that I think it has to be formally approved by the whole group. If such approval failed, we'd revert to the editorial changes only most likely (but we'd have to discuss that at a meeting). **************************************************************** From: Randy Brukardt Sent: Tuesday, December 27, 2016 9:41 PM [A partial response to a thread filed in AI12-0196-1 - Editor.] > I suspect Randy will be a bit annoyed you didn't mention this issue > earlier! I would have been, but luckily his vote doesn't matter. The vote was Approve (with or without changes): Baird, Barnes, Brukardt, Burns, Cousins, Dismukes, Ploedereder, Rosen, Taft, and Vardanega. Reject: Moore. Abstain: Duff. Thus we have a vote of 10-1-1. Given our new procedures, we require a majority of the responding members (12 here) to vote for it (that would mean at least 7 approve votes in this case); and no more than 17% rejection votes (that's 2.04 votes in this case). All of these are clearly met, so this vote passes. ****************************************************************