Prev: About the F-22 software bug
Next: Tue Feb 23 Seminar - Ada and SPARK for education and research
From: Hibou57 (Yannick Duchêne) on 5 Feb 2010 17:09 On 5 fév, 22:40, "Dmitry A. Kazakov" <mail...(a)dmitry-kazakov.de> wrote: > This is illegal, because protected procedure shall not perform potentially > blocking actions (like I/O. As Jeffrey pointed out as well. I will check the RM about it (I have to establish I've missed it). > You do not need to worry about that. Unless you are using pointers, the > task object's scope encloses any calls to its entries. Therefore it simply > cannot terminate due to its finalization before any entry call. **it simply cannot terminate due to its finalization before any entry call** That's clever to notice ! OK, I see. Now I understand Jeffrey's doubts. > If you want garbage collection because of pointers involved then just do > it. Don't break the task interface, make a handle type pointing to the task > object. When the last handle vanishes, deallocate the task. That is. Deallocate the task ? If I want to deallocate, I have to request it to completes, and for the latter, I need it to have a corresponding request entry... which would need to be public (as private entry accessible from implementation is not possible). > Task component does not work in most real-life cases. My words was wrong : I was not to talk about using task as record components, I was to say task may be implementation details, just like record components are. > Yes, an entry call can be syntactically and semantically different than a > call to a procedure. Syntactically : can be wrapped in a procedure call. Semantically : sure if protected objects are required to not invoke blocking operations, this is semantically different. > You can print from the rendezvous. That is not a problem. Some tight > implementations would prefer buffering in the rendezvous in order to > release the caller as soon as possible (minimizing the effect of priority > inversion). I.e. Text is first copied into the task's buffer during the > rendezvous and printed later outside the rendezvous before accepting the > new one. Assuming that the callers run at a higher priority and do not > print very often leaving the processor free most of the time, this would > give better response times in the callers (at the cost of some overall > performance hit). I like this hint (have a taste of real-time design by the way).
From: sjw on 5 Feb 2010 17:57 On Feb 5, 10:09 pm, Hibou57 (Yannick Duchêne) <yannick_duch...(a)yahoo.fr> wrote: > On 5 fév, 22:40, "Dmitry A. Kazakov" <mail...(a)dmitry-kazakov.de> > > If you want garbage collection because of pointers involved then just do > > it. Don't break the task interface, make a handle type pointing to the task > > object. When the last handle vanishes, deallocate the task. That is. > > Deallocate the task ? If I want to deallocate, I have to request > it to completes, and for the latter, I need it to have a corresponding > request entry... which would need to be public (as private entry > accessible from implementation is not possible). You could just abort the task before freeing it. With GNAT (maybe just with older versions, maybe not on all platforms), if you free a task before it has terminated it will silently not do the deallocation. The trick is to loop until 'Terminated is True. I had to create a scavenger task; tasks that had been aborted were placed on a queue for the scavenger task to free when the task had terminated. Fairly gruesome generics involved.
From: Hibou57 (Yannick Duchêne) on 5 Feb 2010 21:20 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. On 5 fév, 22:40, "Dmitry A. Kazakov" <mail...(a)dmitry-kazakov.de> wrote: > This is illegal, because protected procedure shall not perform potentially > blocking actions (like I/O. Here is the reference (for any other peoples who read this thread) : First occurrence of this requirement appears as an example in [ARM 9.5(4.e)] : procedure Op2 is begin Op1; -- An internal call. Pt.Op1; -- Another internal call. PO.Op1; -- An external call. It the current instance is PO, then -- this is a bounded error (see 9.5.1). Other_Object.Some_Op; -- An external call. end Op2; Then formally stated at [ARM 9.5.1(8)] : During a protected action, it is a bounded error to invoke an operation that is potentially blocking. (follows a list of operations defined to be potentially blocking) And later in [ARM 9.5.1(17)] : If the bounded error is detected, Program_Error is raised. If not detected, the bounded error might result in deadlock or a (nested) protected action on the same target object. So it is not guaranteed to be a bounded error, as nested protected action may succeed. By as soon as it is said it is a potential error, ... all is said.
From: Hibou57 (Yannick Duchêne) on 5 Feb 2010 21:23 On 6 fév, 03:20, Hibou57 (Yannick Duchêne) <yannick_duch...(a)yahoo.fr> wrote: > By as soon as it is said it is a potential error, ... all is said. Tipo mistake : But as soon instead of By as soon
From: Jeffrey R. Carter on 5 Feb 2010 22:29
Hibou57 (Yannick Duch�ne) wrote: > > � If the bounded error is detected, Program_Error is raised. If not > detected, the bounded error might result in deadlock or a (nested) > protected action on the same target object. � > > So it is not guaranteed to be a bounded error, as nested protected > action may succeed. No, it is a bounded error. A bounded error has a finite set of possible effects. One of the possible effects of this particular bounded error is that the operation will complete normally. See also pragma Detect_Blocking (ARM H.5); without it an implementation may choose to never detect potentially blocking operations and never raise Program_Error. This seems to be the way GNAT handles these. -- Jeff Carter "He didn't get that nose from playing ping-pong." Never Give a Sucker an Even Break 110 |