!standard 9.4 02-05-24 AC95-00035/01 !class amendment 02-05-24 !status received no action 02-06-07 !subject Protected Block !summary !appendix From: Robin Reagan Sent: Friday, May 24, 2002 9:01 AM Ada community, I would like to propose the addition of a protected block to the Ada language standard. Like a protected object, a protected block would allow the sequence of statements to be executed atomically without the overhead of a separate object. This would allow an uninterruptable (atomic) sequence of statements to be executed without the OS context switching or responding to interrupts. This construct is meant to be used as a means of accessing hardware in an uninterruptable fashion without the overhead of a separately declared protected object. This could be accomplished using dynamic priorities, but I think a language specified construct would be more portable and easier to read. ex: begin -- procedure, function, block ... declare protected -- Implied declaration -- pragma priority( System.Any_Priority'last ); begin -- process hw access statements atomically. end; -- protected block. end; -- procedure, function, block ... **************************************************************** From: Ted Baker Sent: Saturday, May 25, 2002 4:55 PM The proposed construct would be dangerously confusing, because: 1) Because of the similar keyword to protected objects, people are likely to think it is related to a protected operation, but it cannot be, because: 2) It lacks an associated object or other means to specify the other blocks with respect to which mutual exclusion required. Such specification is necessary if you are going to provide any kind of guaranteed mutual exclusion, because: 3) Priority alone does not guarantee there will be no interleaved or parallel (multi-cpu) execution of other similarly protected blocks. Depending on what you really want, there seem to be two reasonable alternative proposals possible: A) Something we considered in the Ada 9X process as an alternative to the current protected objects, e.g., a special lock object. mylock : Protection (System.Any_Priority'last); ... declare protected mylock begin -- process hw access statements atomically. end mylock; This provides mutual exclusion and all the other semantics of protected objects (priority, atc protection). It does not seem there should be any huge challenge to implement it, since it amounts (more or less) to a protected object with anonymout in-line procedures. B) If you just want the priority effect, without mutual exclusion and protection from ATC, then the syntax should spell it out, e.g., a pragma declare pragma Priority (System.Any_Priority'last); begin ... end; **************************************************************** From: Tucker Taft Sent: Sunday, June 9, 2002 8:17 AM An important principle of the protected type is that all synchronization associated with a given set of data is gathered into a single module. This is the so-called "monitor" concept introduced many many years ago, to almost universal acclaim. It dramatically improves the structuring of multi-tasking systems, in my view. Also in my view, Java's "synchronized" blocks are a real step backward. They approximate your suggestion, though as Ted Baker points out, they have an associated object, which is critical. Java has synchronized methods, which are associated with the enclosing class (or an instance thereof), but Java's synchronized blocks can be scattered anywhere, with no modularity whatsoever, and no scoping relation to the associated object. This makes any kind of analysis of potential deadlocks and race conditions much more difficult. **************************************************************** From: Michael Erdman Sent: Sunday, June 9, 2002 2:34 PM I guess this feature may makes sense when you have to control external hardware, e.g. if you are doing polling for some reason and you want to avoid beeing interrupted while your polling loop run. In such a case the overhead of declaring a protected type which represents the external hardware i some way can be to costly. But i am not sure if this rare problem should be handled in the language, since this problem could be solved by an extension of RM C.3, which does not provide a way to mask off interrupt of a certain priority. The feature makes no sense when you intend to protect data, for this purpose protected types are available. **************************************************************** From: Robert Dewar Sent: Sunday, June 9, 2002 8:28 AM > > begin -- procedure, function, block ... > > > > declare protected > > -- Implied declaration > > -- pragma priority( System.Any_Priority'last ); > > begin > > -- process hw access statements atomically. > > end; -- protected block. > > > > end; -- procedure, function, block ... One important aspect of protected operations is that abort is deferred. Since Ada 95 (very foolishly in my opinon :-) made abort a first class citizen by the introduction of asynchronous transfer of control, all code has to worry about being aborted. It is quite hard work to make stuff safe with respect to abort. For example, if you have an in place sort that works with exchanges, and you want the sort to be safe from abort in the sense that if an abort occurs, you want the data intact, just possibly not sorted yet. This means that the exchange has to be protected from abort. There is no nice way in the language to do this right now. The two tecniques are to introduce a protected type, or to do the exchange in a dummy finalization routine. Both of these solutions are really heavy and ugly. In GNAT, we have introduced pragma Abort_Defer to respond to this need, but the above proposal would also solve this. Nevertheless I agree with Tuck that it is certainly open to serious abuse. ****************************************************************