* Periodic tasks - organization @ 2008-07-13 21:47 Maciej Sobczak 2008-07-13 23:35 ` tmoran ` (2 more replies) 0 siblings, 3 replies; 13+ messages in thread From: Maciej Sobczak @ 2008-07-13 21:47 UTC (permalink / raw) Consider a program that has a couple of periodic tasks. Let's say there are two tasks, one with a period of 3s and another with a period of 4s. Let's say that exact triggering is not required. The simplest way to do it is to just have appropriate delay statements in main loops of these tasks. The advantage of such a setup is that the tasks are completely self-contained and independent on any other program entity. The disadvantage is that they are bound to the way their periodicity is implemented. Another way is to have additional task that will serve as a clock, "ticking" two protected objects that are countdown counters with single entry that waits for the counter to reach zero. In this case the tick would be 1s, as the greatest common divisor of two periods. The working tasks can then wait on respective entries in these protected objects, which are released when the counters reach zero. The advantage of this approach is that the notion of time is extracted from the working tasks themselves and can be easily changed to something else, like waiting on a different kind of clock or an interrupts or whatever without disturbing main working tasks. The disadvantage is that there are more program entities (+ two protected countdowns + 1 ticking task) to handle. What can you say about these two approaches? Which would you recommend and when? -- Maciej Sobczak * www.msobczak.com * www.inspirel.com ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Periodic tasks - organization 2008-07-13 21:47 Periodic tasks - organization Maciej Sobczak @ 2008-07-13 23:35 ` tmoran 2008-07-14 3:52 ` george.priv 2008-07-14 9:08 ` Alex R. Mosteo 2 siblings, 0 replies; 13+ messages in thread From: tmoran @ 2008-07-13 23:35 UTC (permalink / raw) >What can you say about these two approaches? Which would you recommend >and when? If the task is inherently periodic (updating a wall clock display, for instance), use the simple periodic form. If the task responds to some, not necessarily periodic, event, then program it that way. The only legitimate reason to force the program into an unnatural form would be if some so-far-unmentioned constraint (e.g. other interfaces to the task, or performance, or management decree) required that. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Periodic tasks - organization 2008-07-13 21:47 Periodic tasks - organization Maciej Sobczak 2008-07-13 23:35 ` tmoran @ 2008-07-14 3:52 ` george.priv 2008-07-14 9:08 ` Alex R. Mosteo 2 siblings, 0 replies; 13+ messages in thread From: george.priv @ 2008-07-14 3:52 UTC (permalink / raw) On Jul 13, 5:47 pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote: > Consider a program that has a couple of periodic tasks. Let's say > there are two tasks, one with a period of 3s and another with a period > of 4s. Let's say that exact triggering is not required. If you are not concerned about those two oscillators drifting out of phase then independent tasks will be fine. If you do then simpler seems to be using delay until construct. > > The simplest way to do it is to just have appropriate delay statements > in main loops of these tasks. The advantage of such a setup is that > the tasks are completely self-contained and independent on any other > program entity. The disadvantage is that they are bound to the way > their periodicity is implemented. > > Another way is to have additional task that will serve as a clock, > "ticking" two protected objects that are countdown counters with > single entry that waits for the counter to reach zero. In this case > the tick would be 1s, as the greatest common divisor of two periods. > The working tasks can then wait on respective entries in these > protected objects, which are released when the counters reach zero. > The advantage of this approach is that the notion of time is extracted > from the working tasks themselves and can be easily changed to > something else, like waiting on a different kind of clock or an > interrupts or whatever without disturbing main working tasks. The > disadvantage is that there are more program entities (+ two protected > countdowns + 1 ticking task) to handle. > > What can you say about these two approaches? Which would you recommend > and when? > > -- > Maciej Sobczak *www.msobczak.com*www.inspirel.com George ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Periodic tasks - organization 2008-07-13 21:47 Periodic tasks - organization Maciej Sobczak 2008-07-13 23:35 ` tmoran 2008-07-14 3:52 ` george.priv @ 2008-07-14 9:08 ` Alex R. Mosteo 2008-07-14 15:31 ` Anh Vo 2 siblings, 1 reply; 13+ messages in thread From: Alex R. Mosteo @ 2008-07-14 9:08 UTC (permalink / raw) Maciej Sobczak wrote: > Consider a program that has a couple of periodic tasks. Let's say > there are two tasks, one with a period of 3s and another with a period > of 4s. Let's say that exact triggering is not required. > > The simplest way to do it is to just have appropriate delay statements > in main loops of these tasks. The advantage of such a setup is that > the tasks are completely self-contained and independent on any other > program entity. The disadvantage is that they are bound to the way > their periodicity is implemented. > > Another way is to have additional task that will serve as a clock, > "ticking" two protected objects that are countdown counters with > single entry that waits for the counter to reach zero. In this case > the tick would be 1s, as the greatest common divisor of two periods. > The working tasks can then wait on respective entries in these > protected objects, which are released when the counters reach zero. > The advantage of this approach is that the notion of time is extracted > from the working tasks themselves and can be easily changed to > something else, like waiting on a different kind of clock or an > interrupts or whatever without disturbing main working tasks. The > disadvantage is that there are more program entities (+ two protected > countdowns + 1 ticking task) to handle. > > What can you say about these two approaches? Which would you recommend > and when? I would use "delay until", which prevents any drift and still avoids using extra machinery. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Periodic tasks - organization 2008-07-14 9:08 ` Alex R. Mosteo @ 2008-07-14 15:31 ` Anh Vo 2008-07-16 21:38 ` Simon Wright 0 siblings, 1 reply; 13+ messages in thread From: Anh Vo @ 2008-07-14 15:31 UTC (permalink / raw) On Jul 14, 2:08 am, "Alex R. Mosteo" <devn...@mailinator.com> wrote: > Maciej Sobczak wrote: > > Consider a program that has a couple of periodic tasks. Let's say > > there are two tasks, one with a period of 3s and another with a period > > of 4s. Let's say that exact triggering is not required. > > > The simplest way to do it is to just have appropriate delay statements > > in main loops of these tasks. The advantage of such a setup is that > > the tasks are completely self-contained and independent on any other > > program entity. The disadvantage is that they are bound to the way > > their periodicity is implemented. > > > Another way is to have additional task that will serve as a clock, > > "ticking" two protected objects that are countdown counters with > > single entry that waits for the counter to reach zero. In this case > > the tick would be 1s, as the greatest common divisor of two periods. > > The working tasks can then wait on respective entries in these > > protected objects, which are released when the counters reach zero. > > The advantage of this approach is that the notion of time is extracted > > from the working tasks themselves and can be easily changed to > > something else, like waiting on a different kind of clock or an > > interrupts or whatever without disturbing main working tasks. The > > disadvantage is that there are more program entities (+ two protected > > countdowns + 1 ticking task) to handle. > > > What can you say about these two approaches? Which would you recommend > > and when? > > I would use "delay until", which prevents any drift and still avoids using > extra machinery.- Hide quoted text - > > - Show quoted text - It is even better to use periodic timers built on top Ada.Real_Time.Timing_Events. Then, explicit tasks are not needed. Anh Vo ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Periodic tasks - organization 2008-07-14 15:31 ` Anh Vo @ 2008-07-16 21:38 ` Simon Wright 2008-07-16 22:47 ` Anh Vo 0 siblings, 1 reply; 13+ messages in thread From: Simon Wright @ 2008-07-16 21:38 UTC (permalink / raw) Anh Vo <anhvofrcaus@gmail.com> writes: > It is even better to use periodic timers built on top > Ada.Real_Time.Timing_Events. Then, explicit tasks are not needed. Only 'better' if that solution meets a need that's not met by the straightforward approach. I see that Timing Event Handlers are meant to be executed directly by the protected handler operation (http://www.adaic.com/standards/05rm/html/RM-D-15.html 25/2), so clearly the intent is that some task should be released by the action of the handler (similar to interrupts). So you still need explicit tasks! just replacing a delay with a blocking wait on the PO which will be triggered by the timing event -- a lot of complication. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Periodic tasks - organization 2008-07-16 21:38 ` Simon Wright @ 2008-07-16 22:47 ` Anh Vo 2008-07-17 19:31 ` Simon Wright 0 siblings, 1 reply; 13+ messages in thread From: Anh Vo @ 2008-07-16 22:47 UTC (permalink / raw) On Jul 16, 2:38 pm, Simon Wright <simon.j.wri...@mac.com> wrote: > Anh Vo <anhvofrc...@gmail.com> writes: > > It is even better to use periodic timers built on top > > Ada.Real_Time.Timing_Events. Then, explicit tasks are not needed. > > Only 'better' if that solution meets a need that's not met by the > straightforward approach. > > I see that Timing Event Handlers are meant to be executed directly by > the protected handler operation > (http://www.adaic.com/standards/05rm/html/RM-D-15.html25/2), so > clearly the intent is that some task should be released by the action > of the handler (similar to interrupts). So you still need explicit > tasks! just replacing a delay with a blocking wait on the PO which > will be triggered by the timing event -- a lot of complication. Making two explicit tasks involves overhead for sure. It is true that using PO construct is more complex than using two independent tasks. Furthermore, an explicit task is not needed once the timer is started initially. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Periodic tasks - organization 2008-07-16 22:47 ` Anh Vo @ 2008-07-17 19:31 ` Simon Wright 2008-07-18 15:31 ` Anh Vo 0 siblings, 1 reply; 13+ messages in thread From: Simon Wright @ 2008-07-17 19:31 UTC (permalink / raw) Anh Vo <anhvofrcaus@gmail.com> writes: > On Jul 16, 2:38�pm, Simon Wright <simon.j.wri...@mac.com> wrote: >> Anh Vo <anhvofrc...@gmail.com> writes: >> > It is even better to use periodic timers built on top >> > Ada.Real_Time.Timing_Events. Then, explicit tasks are not needed. >> >> Only 'better' if that solution meets a need that's not met by the >> straightforward approach. >> >> I see that Timing Event Handlers are meant to be executed directly by >> the protected handler operation >> (http://www.adaic.com/standards/05rm/html/RM-D-15.html25/2), so >> clearly the intent is that some task should be released by the action >> of the handler (similar to interrupts). So you still need explicit >> tasks! just replacing a delay with a blocking wait on the PO which >> will be triggered by the timing event -- a lot of complication. > > Making two explicit tasks involves overhead for sure. It is true that > using PO construct is more complex than using two independent tasks. > Furthermore, an explicit task is not needed once the timer is started > initially. But there are limits on what is permissible within a protected procedure, are there not? Not sure what you mean by "once the timer is started initially", timing events are one-shot (once the event fires, it's cleared). In the code below (my first try, excuse any stupidities & the need for 'Unresricted_Access) I reckon there are 11 extra logical LOC ... with Ada.Real_Time.Timing_Events; with Ada.Text_IO; use Ada.Text_IO; procedure Periodic is protected Po is procedure Handler (E : in out Ada.Real_Time.Timing_Events.Timing_Event); entry Wait; private Released : Boolean := False; end Po; protected body Po is procedure Handler (E : in out Ada.Real_Time.Timing_Events.Timing_Event) is begin Released := True; end Handler; entry Wait when Released is begin Released := False; end Wait; end Po; Ev : Ada.Real_Time.Timing_Events.Timing_Event; task T is end T; task body T is begin Put_Line ("setting the Event"); New_Line; Ada.Real_Time.Timing_Events.Set_Handler (Ev, In_Time => Ada.Real_Time.To_Time_Span (1.0), Handler => Po.Handler'Unrestricted_Access); Po.Wait; Put_Line ("t released."); end T; begin null; end Periodic; ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Periodic tasks - organization 2008-07-17 19:31 ` Simon Wright @ 2008-07-18 15:31 ` Anh Vo 2008-07-18 16:22 ` Dmitry A. Kazakov 0 siblings, 1 reply; 13+ messages in thread From: Anh Vo @ 2008-07-18 15:31 UTC (permalink / raw) On Jul 17, 12:31 pm, Simon Wright <simon.j.wri...@mac.com> wrote: > Anh Vo <anhvofrc...@gmail.com> writes: > > On Jul 16, 2:38 pm, Simon Wright <simon.j.wri...@mac.com> wrote: > >> Anh Vo <anhvofrc...@gmail.com> writes: > >> > It is even better to use periodic timers built on top > >> > Ada.Real_Time.Timing_Events. Then, explicit tasks are not needed. > > >> Only 'better' if that solution meets a need that's not met by the > >> straightforward approach. > > >> I see that Timing Event Handlers are meant to be executed directly by > >> the protected handler operation > >> (http://www.adaic.com/standards/05rm/html/RM-D-15.html25/2), so > >> clearly the intent is that some task should be released by the action > >> of the handler (similar to interrupts). So you still need explicit > >> tasks! just replacing a delay with a blocking wait on the PO which > >> will be triggered by the timing event -- a lot of complication. > > > Making two explicit tasks involves overhead for sure. It is true that > > using PO construct is more complex than using two independent tasks. > > Furthermore, an explicit task is not needed once the timer is started > > initially. > > But there are limits on what is permissible within a protected > procedure, are there not? > > Not sure what you mean by "once the timer is started initially", > timing events are one-shot (once the event fires, it's cleared). > > In the code below (my first try, excuse any stupidities & the need for > 'Unresricted_Access) I reckon there are 11 extra logical LOC ... > > with Ada.Real_Time.Timing_Events; > with Ada.Text_IO; use Ada.Text_IO; > > procedure Periodic is > > protected Po is > procedure Handler (E : in out Ada.Real_Time.Timing_Events.Timing_Event); > entry Wait; > private > Released : Boolean := False; > end Po; > protected body Po is > procedure Handler (E : in out Ada.Real_Time.Timing_Events.Timing_Event) > is > begin > Released := True; > end Handler; > entry Wait when Released is > begin > Released := False; > end Wait; > end Po; > > Ev : Ada.Real_Time.Timing_Events.Timing_Event; > > task T is end T; > task body T is > begin > Put_Line ("setting the Event"); > New_Line; > Ada.Real_Time.Timing_Events.Set_Handler > (Ev, > In_Time => Ada.Real_Time.To_Time_Span (1.0), > Handler => Po.Handler'Unrestricted_Access); > Po.Wait; > Put_Line ("t released."); > end T; > > begin > null; > end Periodic;- Hide quoted text - > > - Show quoted text - My design is completely different from yours. Indeed, an explicit task is not needed. See Gem #15, Timers, for details. http://www.adacore.com/2007/10/29/ada-gem-15/ A. Vo ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Periodic tasks - organization 2008-07-18 15:31 ` Anh Vo @ 2008-07-18 16:22 ` Dmitry A. Kazakov 2008-07-19 1:37 ` Anh Vo 2008-07-20 9:46 ` Simon Wright 0 siblings, 2 replies; 13+ messages in thread From: Dmitry A. Kazakov @ 2008-07-18 16:22 UTC (permalink / raw) On Fri, 18 Jul 2008 08:31:29 -0700 (PDT), Anh Vo wrote: > On Jul 17, 12:31�pm, Simon Wright <simon.j.wri...@mac.com> wrote: >> But there are limits on what is permissible within a protected >> procedure, are there not? [...] > My design is completely different from yours. Indeed, an explicit task > is not needed. See Gem #15, Timers, for details. > http://www.adacore.com/2007/10/29/ada-gem-15/ Hmm, but it is exactly the design presented by Simon. The problem with it is that the action fired upon a timer event is called from a protected procedure. This is IMO not what Maciej wanted, because as Simon has pointed out protected procedures are very limited in what they allowed do and in how they do it. Another point is that even if that were the context of a task (which is not), it still would be an unsatisfactory design, because simultaneously triggered actions would block each other when overlapping. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Periodic tasks - organization 2008-07-18 16:22 ` Dmitry A. Kazakov @ 2008-07-19 1:37 ` Anh Vo 2008-07-19 10:22 ` Dmitry A. Kazakov 2008-07-20 9:46 ` Simon Wright 1 sibling, 1 reply; 13+ messages in thread From: Anh Vo @ 2008-07-19 1:37 UTC (permalink / raw) On Jul 18, 9:22 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> wrote: > On Fri, 18 Jul 2008 08:31:29 -0700 (PDT), Anh Vo wrote: > > On Jul 17, 12:31�pm, Simon Wright <simon.j.wri...@mac.com> wrote: > >> But there are limits on what is permissible within a protected > >> procedure, are there not? > > [...] > > > My design is completely different from yours. Indeed, an explicit task > > is not needed. See Gem #15, Timers, for details. > >http://www.adacore.com/2007/10/29/ada-gem-15/ > > Hmm, but it is exactly the design presented by Simon. The problem with it > is that the action fired upon a timer event is called from a protected > procedure. I hope you already looked at ada-gem-15 and see the difference. > This is IMO not what Maciej wanted, because as Simon has pointed out > protected procedures are very limited in what they allowed do and in how > they do it. Why is Protected Procedure limited for this purpose? > Another point is that even if that were the context of a task (which is > not), it still would be an unsatisfactory design, because simultaneously > triggered actions would block each other when overlapping. Again, look at the full code in Ada-Gem-15. There is no overlap action at all. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Periodic tasks - organization 2008-07-19 1:37 ` Anh Vo @ 2008-07-19 10:22 ` Dmitry A. Kazakov 0 siblings, 0 replies; 13+ messages in thread From: Dmitry A. Kazakov @ 2008-07-19 10:22 UTC (permalink / raw) On Fri, 18 Jul 2008 18:37:23 -0700 (PDT), Anh Vo wrote: > On Jul 18, 9:22�am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> > wrote: >> This is IMO not what Maciej wanted, because as Simon has pointed out >> protected procedures are very limited in what they allowed do and in how >> they do it. > > Why is Protected Procedure limited for this purpose? Because it is executed inside a protected action, see RM 9.5.1. In particular, ada-gem-15 is a bounded error, because it calls to Put_Line from a declared protected action. Note that Put_Line is potentially blocking. Even if Put_Line does not block, its execution time is unacceptable for a protected action. Protected actions are thought having *semantically* zero execution time. [Yes, GNAT allows Put_Line in protected actions for debugging purpose, but to do it in production code would be a very bad idea.] >> Another point is that even if that were the context of a task (which is >> not), it still would be an unsatisfactory design, because simultaneously >> triggered actions would block each other when overlapping. > > Again, look at the full code in Ada-Gem-15. There is no overlap action > at all. It would be if there *officially* existed a task doing the notification callbacks. *Unofficially*, depending on the implementation, the compiler might use one task for all instances of Timing_Event or system services (like waitable timers). In both cases you would have one system thread servicing all callbacks one after another. Certainly, an implementation could choose to use one task per each Timing_Event instance, but it would rather be surprising, because there is no reason to do that, as the callback is declared to fit into a protected action. Well, having said that, on a multi-core CPU it could make sense to start one timer task for each core, but I doubt that any Ada vendor would really care. There seems to be little use in Ada.Real_Time.Timing_Events except for bare boards with hardware timer interrupts mapped directly to Timing_Events. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Periodic tasks - organization 2008-07-18 16:22 ` Dmitry A. Kazakov 2008-07-19 1:37 ` Anh Vo @ 2008-07-20 9:46 ` Simon Wright 1 sibling, 0 replies; 13+ messages in thread From: Simon Wright @ 2008-07-20 9:46 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > On Fri, 18 Jul 2008 08:31:29 -0700 (PDT), Anh Vo wrote: > >> On Jul 17, 12:31�pm, Simon Wright <simon.j.wri...@mac.com> wrote: > >>> But there are limits on what is permissible within a protected >>> procedure, are there not? > > [...] > >> My design is completely different from yours. Indeed, an explicit >> task is not needed. See Gem #15, Timers, for details. >> http://www.adacore.com/2007/10/29/ada-gem-15/ > > Hmm, but it is exactly the design presented by Simon. The problem with > it is that the action fired upon a timer event is called from a > protected procedure. > > This is IMO not what Maciej wanted, because as Simon has pointed out > protected procedures are very limited in what they allowed do and in > how they do it. And further, they are called at interrupt priority (I haven't read up enough to understand D-15 14/2, but see 25/2: 'executed directly by the real-time clock interrupt mechanism'), so there are going to be interesting issues related to shared variable access. If you aren't running on an RTOS, why are you bothering with the added complexity? and if you are, won't the standard Ada mechanisms (delay until, etc) do the trick? (they do for us with VxWorks). I don't quite buy the notion that RTOS => use timers (at least, not without supporting them as a variation on the general notion of event, so that some events can be scheduled to happen in the furure). Some thoughts on this here -- http://coldframe.sourceforge.net/coldframe/event-modelling.html ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2008-07-20 9:46 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-07-13 21:47 Periodic tasks - organization Maciej Sobczak 2008-07-13 23:35 ` tmoran 2008-07-14 3:52 ` george.priv 2008-07-14 9:08 ` Alex R. Mosteo 2008-07-14 15:31 ` Anh Vo 2008-07-16 21:38 ` Simon Wright 2008-07-16 22:47 ` Anh Vo 2008-07-17 19:31 ` Simon Wright 2008-07-18 15:31 ` Anh Vo 2008-07-18 16:22 ` Dmitry A. Kazakov 2008-07-19 1:37 ` Anh Vo 2008-07-19 10:22 ` Dmitry A. Kazakov 2008-07-20 9:46 ` Simon Wright
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox