comp.lang.ada
 help / color / mirror / Atom feed
From: Brad Moore <brad.moore@shaw.ca>
Subject: Re: Safety of unprotected concurrent operations on constant objects
Date: Wed, 07 May 2014 22:12:13 -0600
Date: 2014-05-07T22:12:13-06:00	[thread overview]
Message-ID: <xtDav.68151$7X2.15124@fx19.iad> (raw)
In-Reply-To: <83ha6vuynrzs.1jk08faxb8mnl.dlg@40tude.net>

On 06/05/2014 2:11 AM, Dmitry A. Kazakov wrote:
> On Tue, 06 May 2014 00:00:40 -0600, Brad Moore wrote:
>
>> On 05/05/2014 10:36 AM, Dmitry A. Kazakov wrote:
>>> On Mon, 05 May 2014 09:11:05 -0600, Brad Moore wrote:
>>>
>>>> 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.
>>>
>>> Task safety is not a type property. Even for a tagged type an unsafe
>>> operation can be defined later on. For non-tagged types it is even less
>>> clear which operations must be safe and which not.
>>>
>>> Furthermore, task-safety cannot be inherited or composed. At least not
>>> without massive overhead to prevent deadlocking when two safe types meet as
>>> mutable parameters of a safe subprogram.
>>
>> I agree that such a property is not likely inheritable or composable,
>> and I don't think we'd want it to be.  I think conceivably it could
>> apply to a type, however. It may be that such an aspect could only be
>> applicable to tagged types, and only would apply to the primitive
>> subprograms of that type. The aspect, if true would become false for any
>> derivations of that type, unless those derived types also explicitly set
>> the aspect to True.
>
> If you limit it to primitive operations then much simpler to do this:
>
>     type My_Container is tagged ...; -- All operations are unsafe
>
>     type My_Safe_Container is protected new My_Container with null record;

There's quite a difference from what you propose and what I was 
suggesting. In a nutshell, your idea is to *prescribe* an implementation 
(by wrapping an existing implementation in mutexes, whereas my wish is 
to be better able to *describe* an implementation.
There are lots of ways to provide a task safe implementation, and lots 
of different flavours of task-safe it seems.

Also, the main driver behind what I was suggesting was not to apply the 
aspect to a type, but rather to apply it to a subprogram specification. 
Any subprogram specification, whether its a primitive of a tagged type 
or not.

I only suggested applying the aspect to the primitives of a tagged type, 
as an extension to the idea, as a shorthand for putting the same aspect 
on every primitive subprogram. That part of the idea could be dropped if 
it is too problematic. When the aspect is applied to a type rather than 
a subprogram, I suspect that it would be problematic to apply to 
non-tagged types. If you imagine a function that takes a parameter of a 
task safe type, and another of a non-task safe type type, would the 
function be task safe or not? It seems
clearer that the aspect could work on a tagged type, and only apply to 
the primitives of the tagged type.

As a better example of my main concern, consider the following function.

     type Foo_Range is range 1 .. 1000;

     function Foo (X : Foo_Range) return Integer;

Looking at this, can someone tell me if the function is task-safe or 
not? Who knows? The function might internally use X to update some 
unprotected global statistic variable recording the max, min, and 
average values of all calls for the value of X.

Calling Foo with any combination of arguments concurrently for such a 
case would be dangerous, regardless the values of X.

Now consider that Foo instead uses X as an index to update the value in
some global unprotected array.

In this case, calling Foo from multiple tasks is task-safe, so long as 
two tasks do not call Foo concurrently with the same values of X.

Finally, the function may be task-safe, declaring any state on the stack 
without updating any global variables.

Whether or not such a function can be called concurrently is a pretty 
basic question, but Ada currently doesn't help the reader here.

If you are quite lucky, the programmer might have specified this
in the comments associated with the function. If you are unlucky, the 
programmer didn't later modify the implementation to become task 
un-safe, but neglected to update the comment.

Now that Ada has the new contract capabilities in Ada 2012, it seems 
like a large hole that there is no way to specify the task safety in the 
contract as well, so I am wondering about what can be done to improve 
that situation.

In response to your protected new suggestion. I think there is an idea 
there that could be explored, but I suspect there could be significant 
difficulties in having such an auto-generated protection scheme added to 
Ada. When it comes to task-safety, one size does not fit all.

For example, someone interested in processing a Vector container in 
parallel would likely not want to use such a feature, because it applies 
a mutex to every access to the container, when a much more efficient 
implementation would break the index range into chunks, and
a group of worker tasks could process each chunk of the array without 
any synchronization.

In other cases, moving from a single task design to a multiple task 
design changes the design. A producer/consumer type of usage for a 
bounded container would likely want blocking introduced to calls when 
the container is full, or empty. Simply putting a mutex around all the 
calls is not the best design in that case.

A worry I'd have is that such a feature might encourage programmers to 
become lazy and start writing poorer abstractions in lieu of taking the 
time to write a better one, in respect to functionality, readability, 
safety, etc.

>
> When inherited from, the compiler would override each primitive operation
> and wrap it with a reentrant mutex taken. When an operation gets overridden
> its new body is wrapped. Calling operation within a protected action would
> be bounded error. At least the compiler would be able to maintain mutexes
> of such objects, e.g. order them to prevent deadlocks.
>
> [Better of course, would be to have a decent delegation support]
>
>>> And, just how this contract is supposed to be verified?
>>
>> I see it more as a contract or promise made by the implementer to the
>> users of that subprogram that concurrent calls to the subprogram will
>> work.
>
> You can use this contract no more you can verify it. Because the compiler
> does not know if a call is concurrent or not.
>
>> At this point, I have doubts that the compiler could 100% guarantee that
>> a subprogram call is task safe, but there are likely rules and
>> restrictions that could be applied that would allow the compiler to
>> catch many problems.
>>
>> In particular, the aspect could restrict the associated subprogram to
>> disallow:
>>
>> (1) Calls on other non-protected subprograms that are not Pure or
>>       Task_Safe;
>
> But calling a task-safe subprogram from another task-safe subprogram were a
> much bigger problem than calling a non-safe subprogram. Protected
> operations specifically forbid to do exactly this.

That's not correct. Protected procedure's and protected functions are 
not potentially blocking. A protected procedure of one PO can call 
another protected procedure of another PO.

You could call another
> task-safe operation only on the same object and only if the implementation
> deploys reentrant locking.



>
> The rules you propose actually are good only for lock-free concurrency.

There's million's of simple functions and procedures that do not involve 
any locking. Integer "+" for example, is completely task safe.

> Unfortunately only few things can be done lock-free, and most types of
> containers certainly not.
>

Containers maybe not in general, but a constant container object without 
tamper checks could easily be made to be task safe, for functions that 
query the container, as per the original OP's request.

Regards, Brad

  parent reply	other threads:[~2014-05-08  4:12 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-02  8:42 Safety of unprotected concurrent operations on constant objects Natasha Kerensikova
2014-05-03 13:43 ` sbelmont700
2014-05-03 20:54   ` Natasha Kerensikova
2014-05-03 21:40     ` Simon Wright
2014-05-04  0:28       ` Jeffrey Carter
2014-05-04  7:46         ` Natasha Kerensikova
2014-05-04  8:06           ` Dmitry A. Kazakov
2014-05-04 15:18           ` sbelmont700
2014-05-04 15:57             ` Natasha Kerensikova
2014-05-04 18:30               ` sbelmont700
2014-05-04 19:34                 ` Dmitry A. Kazakov
2014-05-05 19:04               ` Brad Moore
2014-05-05 21:23                 ` Brad Moore
2014-05-04 21:44                   ` Shark8
2014-05-05  8:39                     ` Simon Wright
2014-05-05 15:11                       ` Brad Moore
2014-05-05 16:36                         ` Dmitry A. Kazakov
2014-05-06  6:00                           ` Brad Moore
2014-05-06  8:11                             ` Dmitry A. Kazakov
2014-05-06  8:48                               ` Alejandro R. Mosteo
2014-05-06  9:49                                 ` G.B.
2014-05-06 12:19                                   ` Dmitry A. Kazakov
2014-05-06 12:58                                     ` G.B.
2014-05-06 15:00                                       ` Dmitry A. Kazakov
2014-05-06 16:24                                         ` G.B.
2014-05-06 19:14                                           ` Dmitry A. Kazakov
2014-05-07  6:49                                             ` Georg Bauhaus
2014-05-07  7:40                                               ` Dmitry A. Kazakov
2014-05-07 11:25                                                 ` G.B.
2014-05-07 12:14                                                   ` Dmitry A. Kazakov
2014-05-07 13:45                                                     ` G.B.
2014-05-07 14:08                                                       ` Dmitry A. Kazakov
2014-05-07 17:45                                                   ` Simon Wright
2014-05-07 18:28                                                     ` Georg Bauhaus
2014-05-07  4:59                                         ` J-P. Rosen
2014-05-07  7:30                                           ` Dmitry A. Kazakov
2014-05-07  8:26                                             ` J-P. Rosen
2014-05-07  9:09                                               ` Dmitry A. Kazakov
2014-05-07 11:29                                                 ` J-P. Rosen
2014-05-07 12:36                                                   ` Safety of unprotected concurrent operations on constant objects (was: Safety of unprotected concurrent operations on constant objects) Dmitry A. Kazakov
2014-05-07 14:04                               ` Safety of unprotected concurrent operations on constant objects G.B.
2014-05-08  4:12                               ` Brad Moore [this message]
2014-05-08  8:20                                 ` Dmitry A. Kazakov
2014-05-08 10:30                                   ` G.B.
2014-05-09 13:14                                   ` Brad Moore
2014-05-09 19:00                                     ` Dmitry A. Kazakov
2014-05-10 12:30                                       ` Brad Moore
2014-05-10 20:27                                         ` Dmitry A. Kazakov
2014-05-11  6:56                                           ` Brad Moore
2014-05-11 18:01                                           ` Brad Moore
2014-05-12  8:13                                             ` Dmitry A. Kazakov
2014-05-13  4:50                                               ` Brad Moore
2014-05-13  8:56                                                 ` Dmitry A. Kazakov
2014-05-13 15:01                                                   ` Brad Moore
2014-05-13 15:38                                                     ` Brad Moore
2014-05-13 16:46                                                       ` Simon Wright
2014-05-13 19:15                                                         ` Dmitry A. Kazakov
2014-05-13 16:08                                                     ` Dmitry A. Kazakov
2014-05-13 20:27                                                       ` Randy Brukardt
2014-05-14  4:30                                                         ` Shark8
2014-05-14 21:37                                                           ` Randy Brukardt
2014-05-14 21:56                                                             ` Robert A Duff
2014-05-15  1:21                                                               ` Shark8
2014-05-14 14:30                                                         ` Brad Moore
2014-05-15  8:03                                                         ` Dmitry A. Kazakov
2014-05-15 13:21                                                           ` Robert A Duff
2014-05-15 14:27                                                             ` Dmitry A. Kazakov
2014-05-15 15:53                                                               ` Robert A Duff
2014-05-15 16:30                                                                 ` Dmitry A. Kazakov
2014-10-26 17:11                                                                   ` Jacob Sparre Andersen
2014-05-08 19:52                                 ` Randy Brukardt
2014-05-06 16:22                             ` Robert A Duff
2014-05-06 19:07                               ` Dmitry A. Kazakov
2014-05-08  5:03                                 ` Brad Moore
2014-05-08 12:03                                   ` Brad Moore
2014-05-08 19:57                                     ` Randy Brukardt
2014-05-09  2:58                                       ` Brad Moore
2014-05-05 20:29                         ` Natasha Kerensikova
2014-05-08  3:41                           ` Randy Brukardt
2014-05-08  9:07                             ` Natasha Kerensikova
2014-05-08 19:35                               ` Randy Brukardt
2014-05-08  3:12                       ` Randy Brukardt
2014-05-05 22:30                     ` Brad Moore
2014-05-04 16:04             ` Peter Chapin
2014-05-04 18:07               ` Natasha Kerensikova
2014-05-04 18:55           ` Jeffrey Carter
2014-05-04 19:36             ` Simon Wright
2014-05-04 20:29               ` Jeffrey Carter
2014-05-05 22:46             ` Brad Moore
2014-05-04 20:25           ` Shark8
2014-05-04 23:33             ` sbelmont700
2014-05-05  7:38             ` Dmitry A. Kazakov
2014-05-08  3:45               ` Randy Brukardt
2014-05-08  3:19 ` Randy Brukardt
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox