Prev: About the F-22 software bug
Next: Tue Feb 23 Seminar - Ada and SPARK for education and research
From: Alex R. Mosteo on 8 Feb 2010 04:55 Hibou57 (Yannick Duchêne) wrote: > Hi Jeffrey, nice to meet you again, > > On 5 fév, 22:38, "Jeffrey R. Carter" <spam.jrcarter....(a)spam.acm.org> > wrote: >> Technically this is a bounded error: Ada.Text_IO.Put* operations are >> potentially blocking, and should not be called from a protected >> operation. > I did not ever suspected such a requirement. Transitive blocking is > not allowed ? > > So, if blocking operation are not allowed from a protected type, > clients of a given operation have to know it weither or not it's > potentially blocking, and so, this fact must be stated in public part > of specifications, so then, the protected and tasked aspect of a > method must be stated in specifications and I suppose it's not a good > idea to make it private. I have had some headaches not long along because of potentially blocking operations. The short conclusion is that as long as you don't try anything strange, you'll do well. By strange I mean things that may seem "clever" at some point like calling a task from a protected or so. Past versions of gnat where indulging about this, there's now a pragma that won't allow it and that I recommend to use; you'll save further problems with deadlocks. I think is pragma Detect_Blocking. So, if your type is encapsulating a hidden call to a task entry, it would be advisable to document it in the call, because this indeed can raise an exception at runtime if called from a protected op. I think this is a recommendation, but a bounded error in any case. The above pragma enforces its detection. However, I don't think it's recommended design to call from protected ops to foreign, implementation-unknown, subprograms. Protected calls should encapsulate something as well defined and narrow as possible. I make extensive use of protected and task types generally without issue; my problem was that I had to quickly hack a solution for a convoluted tasking subsystem and I was frankly abusing the design. In general, sticking to the client-server model for tasks/protected objects covers 99% of use cases and it's totally safe. > Wrong or right assumptions ? > >> This should not happen. Did you actually experience this? > No, I did not experience it, this was just my imagination : I knew a > task may completes at its own discretion. Thus if may possibly > completes too much soon if its completion condition is not well > designed. > > I will have to check the RM, but I'm pretty sure a completed task > cannot handle any request any more (at least, this seems to be a > reasonable assumption to me, but I will still have to check...). At first I also was reticent of terminate parts, but this is really one of these nice aspects of Ada where something apparently complex is done for you by the language :)
From: Jean-Pierre Rosen on 8 Feb 2010 05:02 Hibou57 (Yannick Duch�ne) a �crit : > So, if blocking operation are not allowed from a protected type, > clients of a given operation have to know it weither or not it's > potentially blocking, and so, this fact must be stated in public part > of specifications, so then, the protected and tasked aspect of a > method must be stated in specifications and I suppose it's not a good > idea to make it private. > > Wrong or right assumptions ? > Right. Thats why there is a rule in AdaControl to check potentially blocking operations called from protected actions. The check is of course pessimistic (if it were really statically checkable, it would be forbidden by langage rules). So it checks for potentially potentially blocking operations ;-) -- --------------------------------------------------------- J-P. Rosen (rosen(a)adalog.fr) Visit Adalog's web site at http://www.adalog.fr
From: Maciej Sobczak on 8 Feb 2010 12:28 On 5 Lut, 22:53, Hibou57 (Yannick Duchêne) <yannick_duch...(a)yahoo.fr> wrote: > I did not ever suspected such a requirement. Transitive blocking is > not allowed ? As far as I understand, there is a careful wording around this subject so that formally speaking protected operations (except for entries) are not themselves "blocking". So, for example, you can call protected operations from other protected operations. The operations that are considered to be blocking in this context are delay statements, entry calls, select statements and... I/O operations. These cannot be called from protected operations. (I'm sure somebody will correct me if I'm off tracks) > So, if blocking operation are not allowed from a protected type, > clients of a given operation have to know it weither or not it's > potentially blocking, That would be nice, yes. But be careful, this approach might blow up the language. What about exception specifications? And so on. But: see RavenSPARK. The problem with blocking in particular is that there is no way to verify whether imported subprograms (from C libraries, for example) are blocking. You can import I/O operations from C libraries and there is no way to verify what they do. -- Maciej Sobczak * www.msobczak.com * www.inspirel.com Database Access Library for Ada: www.inspirel.com/soci-ada
From: Dmitry A. Kazakov on 9 Feb 2010 03:43 On Mon, 8 Feb 2010 09:28:44 -0800 (PST), Maciej Sobczak wrote: > The problem with blocking in particular is that there is no way to > verify whether imported subprograms (from C libraries, for example) > are blocking. You can import I/O operations from C libraries and there > is no way to verify what they do. You do not need that. The default must be "blocking". The programmer overrides the default if he is sure that the imported subprogram is not blocking. This is no different to the parameter profile of an imported procedure. There is no way to verify it. So the programmer just gives his word, and the compiler rely on it. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de
From: Hibou57 (Yannick Duchêne) on 9 Feb 2010 07:07
On 8 fév, 18:28, Maciej Sobczak <see.my.homep...(a)gmail.com> wrote: > As far as I understand, there is a careful wording around this subject > so that formally speaking protected operations (except for entries) > are not themselves "blocking". So, for example, you can call protected > operations from other protected operations. > > The operations that are considered to be blocking in this context are > delay statements, entry calls, select statements and... I/O > operations. These cannot be called from protected operations. > > (I'm sure somebody will correct me if I'm off tracks) Protected types was most the subject of another thread, but as you talked about it here : I don't understand why you've protected operation (I suppose you were talking about procedures, not entries) are not themselves blocking. They grant exclusive read-write access and ensure there is no race. So if another task is currently running the procedure of a protected type, another task cannot enter this procedure if it was to do so and a task switch occurs at the same time. Or is it guaranteed that no task switch can occurs when a task is actually in a procedure of a protected type ? Is the task switch delayed in such a circumstance ? Let temporarily suppose so. But remains another wolf in the wood : what if the application is running in a multiprocessors environment and its thread are not executed on the same CPU ? If one task on CPU#1 was to enter a procedure of a protected object while a task on CPU#2 is actually running a procedure on the same protected object, then, the task running on CPU#1 must be delayed, and thus, the procedure is blocking. Sure a procedure of a protected type or object should be short and quick to execute, but it seems to still remains potentially blocking. |