CVS difference for ai12s/ai12-0267-1.txt

Differences between 1.5 and version 1.6
Log of other versions for file ai12s/ai12-0267-1.txt

--- ai12s/ai12-0267-1.txt	2018/07/15 00:01:46	1.5
+++ ai12s/ai12-0267-1.txt	2018/07/15 00:18:55	1.6
@@ -1,9 +1,9 @@
-!standard 9.5(57/5)                                  18-06-23  AI12-0267-1/04
-!standard 9.5.1(7/4)
+!standard 5.1(1)                                      18-07-08  AI12-0267-1/05
+!standard 9.5(57/5)
 !standard 9.10(11)
 !standard 9.10(15)
-!standard 9.10.1(0)
 !standard 11.5(19.2/2)
+!standard H.5(0)
 !standard H.5(1/2)
 !standard H.5(5/5)
 !standard H.5(6/2)
@@ -15,11 +15,9 @@
 !subject Data race and non-blocking checks for parallel constructs
 !summary
 
-Data race and non-blocking checks for parallel constructs are defined.
-Mechanisms to enable and disable data race checks are based
-on Suppress/Unsuppress for Conflict_Check, plus an overall
-Detect_Conflicts configuration pragma.  Note that some of the data-race
-checks also apply to concurrency introduced by Ada tasking.
+Restrictions against potential data races and blocking are defined for
+parallel constructs are defined. A policy-based mechanism is provided to
+control what level of restrictions are imposed for potential data races.
 
 !problem
 
@@ -30,11 +28,11 @@
 should provide the compiler with semantic information to facilitate detection
 of these errors, but additional checking may be needed to determine if a
 parallelism construct is data-race free. The focus of this AI is to consider
-any additional checks that may be needed to support these features. Similarly,
-if a compiler cannot determine if the parallelismn is safe, then there ought to
-be a way for the programmer to explicitly override the conservative approach of
-the compiler and insist that parallelism should be applied, even if data races
-or deadlocking problems can potentially occur.
+any additional restrictions that may be needed to support these features.
+Similarly, if a compiler cannot determine if the parallelism is safe, then
+there ought to be a way for the programmer to explicitly override the
+conservative approach of the compiler and insist that parallelism should be
+applied, even if data races or deadlocking problems can potentially occur.
 
 Ada needs mechanisms whereby the compiler is given the necessary semantic
 information to enable the implicit and explicit parallelization of code.
@@ -42,26 +40,26 @@
 it is semantically neutral (see 1.1.4(18) and 11.6(3/3)) or explicitly
 in the code as a task.
 
-We distinguish "data race" from the more general term "race condition"
-where "data race" refers to the case where two concurrent activities
-attempt to access the same data object without appropriate
+!proposal
+
+This proposal depends on the facilities for aspect Global (AI12-0079-1) and
+for aspect Nonblocking (AI12-0064-2). Those proposals allow the compiler to
+statically determine where parallelism may be introduced without introducing
+data races or deadlocking.
+
+Note that we distinguish "data race" from the more general term "race
+condition" where "data race" refers to the case where two concurrent
+activities attempt to access the same data object without appropriate
 synchronization, where at least one of the accesses updates the object.
 Such "conflicting" concurrent activities are considered erroneous in
 Ada, per section 9.10 of the reference manual. The more general term
 "race condition" includes other kinds of situations where the effect
 depends on the precise ordering of the actions of concurrent activities.
-Race conditions can be benign, or even intentional, and cannot easily
-be detected in many cases. We make no particular attempt to prevent the
+Race conditions can be benign, or even intentional, and cannot easily be
+detected in many cases.  We make no particular attempt to prevent the
 more general notion of "race conditions," but we do hope to minimize
 data races.
 
-!proposal
-
-This proposal depends on the facilities for aspect Global (AI12-0079-1) and
-for aspect Nonblocking (AI12-0064-2). Those proposals allow the compiler to
-statically determine where parallelism may be introduced without introducing
-data races or deadlocking.
-
 An important part of this model is that the compiler will complain if
 it is not able to verify that the parallel computations are independent
 (See AI12-0079-1 and AI12-0064-1 for ways on how this can happen).
@@ -70,20 +68,21 @@
 potential data race (herein called a "potential conflict") occurs
 (following the rules for access to shared variables as specified in
 9.10, and point out where objects cannot be guaranteed to be
-independently addressable. If not determinable at compile-time, the
-compiler will insert run-time checks to detect data overlap if the
-Detect_Conflicts pragma is in force.
+independently addressable. We considered using run-time checks to detect
+data overlap when compile-time checks were not feasible, but the
+consensus was that better would be to define a range of compile-time
+levels of checking, and forego any use of run-time checks. Parallel
+constructs are only useful if they speed up a program, and complex
+run-time checks are almost certain to undermine any attempt at a speedup.
 
 This model also disallows potentially blocking operations within
 parallel block statements, parallel loop statements, and parallel reduce
 attributes, to simplify the implementation of these constructs, and to
 eliminate possibilities of deadlocking from occurring.
 
-We propose a Detect_Conflicts (configuration) pragma to complement the
-Detect_Blocking pragma to enforce data-race detection in cases where a
-compile-time check is not feasible.  The checks associated with a
-Detect_Conflicts pragma can be suppressed by suppressing Conflict_Check
-in scopes where a true data-race is not believed to occur.
+We propose a Conflict_Check_Policy pragma to control the level of
+compile-time checking performed for potentially conflicting accesses
+to shared data.
 
 !wording
 
@@ -95,22 +94,6 @@
   Nonblocking aspect is statically False, nor shall it contain any of
   the following:
 
-Add after 9.5.1(7/4):
-
-  If a parallel construct occurs within a protected action, no new logical
-  threads of control are created.  Instead, all parts of the parallel
-  construct execute using the same logical thread of control as that
-  of the protected action.
-
-  AARM Rationale: It would be feasible to allow multiple logical
-  threads of control within a protected action, but it would significantly
-  complicate the definition of "sequential" and "concurrent" actions,
-  since we generally presume that everthing occuring within protected
-  actions of a given protected object is sequential.  We could simply
-  disallow any use of parallel constructs, but that seems unnecessary,
-  particularly as a parallel construct might be buried within a
-  subprogram that is declared Nonblocking.
-
 Between 9.10(10) and 9.10(11):
   Remove "Erroneous Execution" subtitle (it will re-appear later).
 
@@ -164,26 +147,36 @@
     pragma Conflict_Check_Policy (/policy_/identifier);
 
   A pragma Conflict_Check_Policy is allowed only immediately within a
-  declarative_part or as a configuration pragma.
+  declarative_part, a package_specification, or as a configuration pragma.
 
     Legality Rules
 
-  The /policy_/identifier shall be either Unchecked, Known_Conflict_Checks,
+  The /policy_/identifier shall be one of Unchecked, Known_Conflict_Checks,
   Parallel_Conflict_Checks, All_Conflict_Checks, or an implementation-defined
   conflict check policy.
 
     Static Semantics
 
-  The conflict check policy in effect at any point is determined by
-  the pragma Conflict_Check_Policy in the nearest enclosing declarative
-  region or compilation unit having such a pragma, or if none, by the
-  default policy of Parallel_Conflict_Checks (see below).
+  A pragma Conflict_Check_Policy given in a declarative_part or
+  immediately within a package_specification applies from the place of
+  the pragma to the end of the innermost enclosing declarative region.
+  The region for a pragma Conflict_Check_Policy given as a configuration
+  pragma is the declarative region for the entire compilation unit (or
+  units) to which it applies.
+
+  If a pragma Conflict_Check_Policy applies to a generic_instantiation,
+  then the pragma Assertion_Policy applies to the entire instance.
+
+  If multiple Conflict_Check_Policy pragmas apply to a given
+  construct, the conflict check policy is determined by the one in the
+  innermost enclosing region. If no such Conflict_Check_Policy pragma exists,
+  the policy is Parallel_Conflict_Checks (see below).
 
       Implementation Requirements
 
   The implementation shall impose restrictions related to possible
   concurrent conflicting actions, according to which conflict check
-  policies are in effect at the place where the action or actions occur,
+  policies apply at the place where the action or actions occur,
   as follows:
 
   * Unchecked
@@ -191,24 +184,35 @@
 
   * Known_Conflict_Checks
     If this policy applies to two concurrent actions, they are
-    disallowed if they are known to refer to the same object (see 6.4.1)
-    with uses that potentially conflict.
+    disallowed if they are known to denote the same object (see 6.4.1)
+    with uses that potentially conflict. For the purposes of this
+    check, any parallel loop may be presumed to involve multiple
+    concurrent iterations, and any task type may be presumed to have
+    multiple instances.
 
   * Parallel_Conflict_Checks
-    This policy disallows a parallel construct from reading or
-    updating a variable that is global to the construct, unless
-    it is a synchronized object, or unless the construct is
-    a parallel loop, and the global variable is an element of
-    an array with an index that is the loop parameter of
-    the loop_parameter_specification or the chunk index
-    parameter of the parallel loop.
+    This policy disallows a parallel construct from reading or updating
+    a variable that is global to the construct, unless it is a
+    synchronized object, or unless the construct is a parallel loop, and
+    the global variable is a part of a component of an array denoted by
+    an indexed component with at least one index expression that
+    statically denotes the loop parameter of the
+    loop_parameter_specification or the chunk index parameter of the
+    parallel loop.
 
   * All_Conflict_Checks
     This policy includes the restrictions imposed by the
-    Parallel_Conflict_Checks policy, and in addition disalllows a task
+    Parallel_Conflict_Checks policy, and in addition disallows a task
     body from reading or updating a variable that is global to the task
     body, unless it is a synchronized object.
 
+      Implementation Permissions
+
+  When the applicale conflict check policy is Known_Conflict_Checks, the
+  implementation may disallow two concurrent actions if the
+  implementation can prove they will at run-time denote the same object
+  with uses that potentially conflict.
+
 Modify H.5(1/2):
   The following pragma [forces] {requires} an implementation to detect
   potentially blocking operations [within] {during the execution of} a
@@ -294,20 +298,6 @@
 
 !appendix
 
-
-!ASIS
-
-** TBD.
-
-
-!ACATS test
-
-ACATS B- and C-Tests are needed to check that the new capabilities are
-supported.
-
-
-!appendix
-
 From: Brad Moore
 Sent: Wednesday, March 28, 2018  12:12 AM
 
@@ -946,7 +936,7 @@
 From: Jean-Pierre Rosen
 Sent: Saturday, June 30, 2018  12:57 AM
 
->      procedure Write is   -- Globals out: A 	
+>      procedure Write is   -- Globals out: A
 >                           -- Globals in: B
 >                           -- Globals in out: Ready
 >       begin
@@ -966,10 +956,10 @@
 := False, I guess
 >       end;
 >
-> This code does not have a data race, not even a general race 
+> This code does not have a data race, not even a general race
 > condition.
 
-Hmmm... as long as you can prove there is only one task calling Read, and one 
+Hmmm... as long as you can prove there is only one task calling Read, and one
 task calling Write
 
 ****************************************************************
@@ -980,7 +970,7 @@
 ...and the error demonstrates just how hard it is to get these things right.
 And this is only toy code. It's often much harder in real situations.
 
-Yes, these errors will cause some pain. That's not unlike the pain caused by 
+Yes, these errors will cause some pain. That's not unlike the pain caused by
 other Ada errors and checks (strong typing; strong hiding; range checks).
 Ada programmers soon learn that the gain is worth the pain. The same is likely
 to be true here - reducing thread communication means code that is more easily
@@ -997,19 +987,19 @@
 
 > No one but a true tasking guru can prove that.
 
-No. In more than 10 years of analyzing code that is running in cars, I have 
+No. In more than 10 years of analyzing code that is running in cars, I have
 not seen a single use of a construct like a semaphore, mutex, and alike. And
-it is not just single programmers, it is an entire application domain that 
+it is not just single programmers, it is an entire application domain that
 works this way.
 
 The programmers are not gurus and yet our cars work (mostly).
 
-They manage to write the code in such a way that a deadlock is provably 
+They manage to write the code in such a way that a deadlock is provably
 impossible, since there are no primitives used that could cause them.
-(The possibility of livelooks is blissfully ignored or dealt with a code 
+(The possibility of livelooks is blissfully ignored or dealt with a code
 review levels.)
 
-The synchronization is done either via flags (as in my example) or, more 
+The synchronization is done either via flags (as in my example) or, more
 often, via states in the path predicates (the system cannot be in states
 15 and 31 at the same time) plus appropriate state management.
 
@@ -1018,9 +1008,9 @@
 From: Erhard Ploedereder
 Sent: Sunday, July 1, 2018  5:58 AM
 
->> This code does not have a data race, not even a general race 
+>> This code does not have a data race, not even a general race
 >> condition.
-> Hmmm... as long as you can prove there is only one task calling Read, 
+> Hmmm... as long as you can prove there is only one task calling Read,
 > and one task calling Write
 
 I stand corrected wrt the comment in the code.
@@ -1032,15 +1022,15 @@
 
 ...
 > Example 2: do the rules prevent legitimate programs?
-> 
-> The following idiom (minus the B, which I added just for fun) to 
+>
+> The following idiom (minus the B, which I added just for fun) to
 > protect the uses of A gets taught in C++ classes:
-> 
+>
 >   Ready: Boolean := False with Atomic, Volatile;
 >         -- I never remember which one implies the other in Ada
 >   -- A and B of arbitrary type, here Integer
 >   A, B: Integer := 0;
-> 
+>
 >     procedure Write is   -- Globals out: A
 >                          -- Globals in: B
 >                          -- Globals in out: Ready
@@ -1049,7 +1039,7 @@
 >         A := 42 + B;
 >         Ready := False;
 >      end Write;
-> 
+>
 >      procedure Read is  -- with Globals out: B
 >                         -- Globals in: A
 >                         -- Globals in out: Ready
@@ -1058,23 +1048,23 @@
 >         B := A - 42;
 >         Ready := True;
 >      end;
-> 
+>
 > This code does not have a data race, not even a general race condition.
-> Illegal in Ada? or legal only, if all ckecks are off ??? Neither will 
+> Illegal in Ada? or legal only, if all ckecks are off ??? Neither will
 > be good advertising for Ada.
 
-I'm not sure I understand the purpose of this example. It appears that one of 
-these two routines, if called, will exit without changing the state of Ready 
+I'm not sure I understand the purpose of this example. It appears that one of
+these two routines, if called, will exit without changing the state of Ready
 (but assigning it a confirming value), and the other one is guaranteed to get
 caught in an infinite loop if called.
 
-Or did you intend Write to set Ready to True, and Read to set Ready to False? 
-I suspect this is the case, in which case as Jean-Pierre suggests, this only 
+Or did you intend Write to set Ready to True, and Read to set Ready to False?
+I suspect this is the case, in which case as Jean-Pierre suggests, this only
 works for a single reader + single writer scenario. If this is the case, it is
 a case in point (logic bug not easily spotted) for showing better support for
 using safer constructs such as protected objects, as Randy was suggesting.
 
-Or are you suggesting or asking if the rules of the AI should detect this 
+Or are you suggesting or asking if the rules of the AI should detect this
 logic problem?
 
 Or am I missing something?
@@ -1087,8 +1077,8 @@
 > ..and the error demonstrates just how hard it is to get these things right.
 > And this is only toy code. It's often much harder in real situations.
 
-Well, it was not an error. It was an idiom for a one-to-one situation that 
-would indeed not work in a many-to-one/many situation. For many-to-X you 
+Well, it was not an error. It was an idiom for a one-to-one situation that
+would indeed not work in a many-to-one/many situation. For many-to-X you
 normally need CAS and family, or else higher-level constructs.
 
 ****************************************************************
@@ -1096,24 +1086,24 @@
 From: Randy Brukardt
 Sent: Sunday, July 1, 2018  9:33 PM
 
-Getting the True and False flags reversed is an error! Moral: use protected 
-objects, not "idioms". 
+Getting the True and False flags reversed is an error! Moral: use protected
+objects, not "idioms".
 
 ****************************************************************
 
 From: Erhard Ploedereder
 Sent: Sunday, July 1, 2018  9:06 PM
 
-> Or did you intend Write to set Ready to True, and Read to set Ready to 
+> Or did you intend Write to set Ready to True, and Read to set Ready to
 > False? I suspect this is the case, in which case as Jean-Pierre suggests,
 > this only works for a single reader + single writer scenario.
 
 Yes, indeed. So, I messed up the coding by inverting the two assignments.
 
-But the point remains that code like that (without stupid coding mistakes) 
-does work for the one-to-one purpose intended, and that the automotive 
+But the point remains that code like that (without stupid coding mistakes)
+does work for the one-to-one purpose intended, and that the automotive
 community has traditionally not been using higher level constructs. Ramming
-them down their throat will not help. We need to allow such code without 
+them down their throat will not help. We need to allow such code without
 poo-pooing it.
 
 That was the purpose of the example.
@@ -1123,19 +1113,19 @@
 From: Randy Brukardt
 Sent: Sunday, July 1, 2018  9:46 PM
 
-But are these sorts of organizations really customers for Ada? You can write 
-low-level code (that may or may not work) in any language -- the benefits of 
+But are these sorts of organizations really customers for Ada? You can write
+low-level code (that may or may not work) in any language -- the benefits of
 Ada aren't really available for such code in any case. To get the benefits of
-Ada, one has to write higher-level code in a different style than they're 
+Ada, one has to write higher-level code in a different style than they're
 accustomed. Is there any benefit to advertising that Ada is no more safe than
 any other language?
 
-If some organization wants to write unchecked Ada code, they can by setting 
+If some organization wants to write unchecked Ada code, they can by setting
 the policy appropriately. They won't get any benefit from using Ada this way,
 but perhaps they'll find some benefit in other existing parts of Ada.
-For the rest of us, that aren't capable of correctly writing tasking 
-communication using idioms (which apparently includes you :-), there is a 
-default safe mode. Seems like a win-win to me. (And maybe the "automotive 
+For the rest of us, that aren't capable of correctly writing tasking
+communication using idioms (which apparently includes you :-), there is a
+default safe mode. Seems like a win-win to me. (And maybe the "automotive
 community" will learn something about structuring multi-threaded code. But I'm
 skeptical.)
 
@@ -1144,20 +1134,20 @@
 From: Tucker Taft
 Sent: Monday, July 2, 2018  2:39 PM
 
-I have lost the thread here, I fear, but I believe it is important that Ada 
-provide low-level coding primitives, including unsafe ones (at least under 
+I have lost the thread here, I fear, but I believe it is important that Ada
+provide low-level coding primitives, including unsafe ones (at least under
 some kind of "Unchecked" banner), because it is much more painful to be forced
 to write such low-level stuff in some other language (e.g. C) when most of the
-system is written in Ada, because you then end up having to worry about 
-multiple compilers, potentially incompatible calling conventions, etc.  Ada 
-certainly has better-than-average "import" and "export" capabilities, but 
+system is written in Ada, because you then end up having to worry about
+multiple compilers, potentially incompatible calling conventions, etc.  Ada
+certainly has better-than-average "import" and "export" capabilities, but
 having to get multiple compilers working smoothly together, potentially across
 multiple targets, with your build system and run-time libraries, can be a real
-pain, and they will often be upgraded on different schedules, etc. 
+pain, and they will often be upgraded on different schedules, etc.
 
-Clearly smart users will minimize and isolate their use of low-level coding, 
+Clearly smart users will minimize and isolate their use of low-level coding,
 which is simpler in Ada due to its good modularization and information hiding,
-but we shoot ourselves in the foot if we get too insistent that all portable 
+but we shoot ourselves in the foot if we get too insistent that all portable
 Ada code must be completely safe and high level.
 
 ****************************************************************
@@ -1168,10 +1158,10 @@
 Exactly my point and view.
 
 My mails are/were about the possible consequence:
-"If you want your "unsafe" program compiled, you must delete the Global specs, 
+"If you want your "unsafe" program compiled, you must delete the Global specs,
 or repent and use the "safe" concepts instead."
 
-I believe we resolved this in Lisbon in principle by adding a "do not check 
+I believe we resolved this in Lisbon in principle by adding a "do not check
 race conds based on Global specs"-option. (The examples were written prior to
 that resolution.)
 
@@ -1180,8 +1170,8 @@
 From: Peter Chapin
 Sent: Tuesday, July 3, 2018  12:06 PM
 
-i don't have any experience in the automotive industry, but i have to say that 
-it disturbs me a little to learn that automotive software developers routinely 
+i don't have any experience in the automotive industry, but i have to say that
+it disturbs me a little to learn that automotive software developers routinely
 use such low level methods to manage multi-tasking!
 
 ****************************************************************
@@ -1189,7 +1179,7 @@
 From: Jeff Cousins
 Sent: Saturday, July 7, 2018  4:15 PM
 
-Some minor comments that I didn’t raise at the meeting as the AI was going 
+Some minor comments that I didn’t raise at the meeting as the AI was going
 back for a re-write anyway...
 
 !proposal
@@ -1210,7 +1200,7 @@
 
 Modify 5.5.2(8/3) first and last sentences
 
-I would prefer to change “constant” to a plural to keep the word as a noun 
+I would prefer to change “constant” to a plural to keep the word as a noun
 rather than changing to using it as an adjective.
 
 Modify A.18.2(230.2/3)
@@ -1237,7 +1227,7 @@
 
 Modify A.18.10(159/4)
 
-I would prefer to change “a loop parameter” to “the loop parameters” rather 
+I would prefer to change “a loop parameter” to “the loop parameters” rather
 than “loop parameters”.
 
 !discussion

Questions? Ask the ACAA Technical Agent