From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.182.130.200 with SMTP id og8mr8590378obb.18.1399302604021; Mon, 05 May 2014 08:10:04 -0700 (PDT) Path: border2.nntp.dca.giganews.com!nntp.giganews.com!c1no1679715igq.0!news-out.google.com!dz10ni31687qab.1!nntp.google.com!peer01.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!post01.iad.highwinds-media.com!fx17.iad.POSTED!not-for-mail From: Brad Moore User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Thunderbird/24.5.0 MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: Safety of unprotected concurrent operations on constant objects References: <7403d130-8b42-43cd-a0f1-53ba34b46141@googlegroups.com> <6c2cd5d4-a44c-4c18-81a3-a0e87d25cd9e@googlegroups.com> In-Reply-To: Message-ID: NNTP-Posting-Host: 68.145.219.148 X-Complaints-To: internet.abuse@sjrb.ca X-Trace: 1399302603 68.145.219.148 (Mon, 05 May 2014 15:10:03 UTC) NNTP-Posting-Date: Mon, 05 May 2014 15:10:03 UTC Date: Mon, 05 May 2014 09:11:05 -0600 X-Received-Bytes: 6691 X-Received-Body-CRC: 2865195456 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Original-Bytes: 6609 Xref: number.nntp.dca.giganews.com comp.lang.ada:186242 Date: 2014-05-05T09:11:05-06:00 List-Id: On 05/05/2014 2:39 AM, Simon Wright wrote: > Shark8 writes: > >> On 05-May-14 15:23, Brad Moore wrote: >>> In GNAT any read or write operations on a container that set tamper >>> flags are ironically not task safe >> >> That seems very... odd. > > Rationale 05 8.1 [1] says (last para) > > "The general rule is given in paragraph 3 of Annex A which says "The > implementation shall ensure that each language defined subprogram is > reentrant in the sense that concurrent calls on the same subprogram > perform as specified, so long as all parameters that could be passed > by reference denote nonoverlapping objects." So in other words we > have to protect ourselves by using the normal techniques such as > protected objects when container operations are invoked concurrently > on the same object from multiple tasks even if the operations are > only reading from the container. Except for containers that are already task safe (Ada.Containers.Synchronized_Queue_Interfaces) These paragraph's are actually being revised and are being passed from the ARG to WG9 for approval at the June WG9 meeting. If approved, (and most likely will be), then the changes apply to the Ada 2012 standard as a binding inteterpretation. The changes are mostly clarification to the existing intent. The existing wording suggested it only applies to calls to the *same* language defined program, whereas the new wording applies to calls to *any* language supplied program. Text_IO was also a special case when involving standard output. The file parameter is assumed to exist, and implicit, so the rule applies to those calls as well. The new wording is; 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 parameters that could be passed by reference denote nonoverlapping objects. For the purpose of determining whether concurrent calls on text input-output subprograms are required to perform as specified above, when calling a subprogram within Text_IO or its children that implicitly operates on one of the default input/output files, the subprogram is considered to have a parameter of Current_Input or Current_Output (as appropriate). In addition, the following new AARM notes will be added. " AARM Ramification: So long as the parameters are disjoint, concurrent calls on the same language-defined subprogram, and concurrent calls on two different language-defined subprograms are required to work. But concurrent calls operating on overlapping objects (be they of the same or different language-defined subprograms) are NOT required to work (being erroneous use of shared variables) unless both subprograms are required to pass the associated parameter by-copy. This rule applies to all language-defined subprograms, including those defined in packages that manage some global state (like environment variables or the current directory). Unless specified above, such subprograms need to work when the explicit parameters are not overlapping; in particular, the existence of the global state is not considered. Packages with global state may require some locking in order to avoid violating this rule." > > AARM12 A.18 (5.m) [2] says > > "If containers with similar functionality (but different performance > characteristics) are provided (by the implementation or by a > secondary standard), we suggest that a prefix be used to identify the > class of the functionality: [...] "Ada.Containers.Protected_Maps" > (for a map which can be accessed by multiple tasks at one time); > [...]" Another relevant RM paragraph is; RM 9.10(11-15) which starts; "Given an action of assigning to an object, and an action of reading or updating a part of the same object (or of a neighboring object if the two are not independently addressable), then the execution of the actions is erroneous unless the actions are sequential." > > Personally I'd like to see the implication (that a standard-compliant > implementation of Containers need not be task-safe unless the Standard > specifies that it must be) made more visible. > > [1] http://www.adaic.org/resources/add_content/standards/05rat/html/Rat-8-1.html > [2] http://www.ada-auth.org/standards/12aarm/html/AA-A-18.html#p5.m > The synchronized keyword in the visible part of the specification of Ada.Containers.Synchronous_Queue_Interfaces provides the cue to the programmer that the container is task safe. I'm thinking I'd actually like to see something like a Task_Safe aspect that could be applied to type declarations, and subprograms, that would make this more clear to users. Having it in the RM is good, but having it in the package spec would be even better. Eg. For Ada.Containers.Vectors... type Vector is tagged private with Constant_Indexing => Constant_Reference, Variable_Indexing => Reference, Default_Iterator => Iterate, Iterator_Element => Element_Type, Task_Safe => False; Then programmers could apply the aspect to their own abstractions, which better defines the contract of the subprogram or type.