Path: csiph.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Niklas Holsti Newsgroups: comp.arch.embedded Subject: Re: Common name for a "Task Loop" Date: Sat, 9 Jul 2016 21:37:46 +0300 Organization: Tidorum Ltd Lines: 96 Message-ID: References: <52krnb9mmrtr1rvf0mc287dk2fvfeip778@4ax.com> <-9ydnaZZCujtUuLKnZ2dnUU7-QmdnZ2d@giganews.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Trace: individual.net sbtKXugfJ2GHqjk+YdpdYQJpjrhlUfpZXWI4hcDIX5DepSv09c Cancel-Lock: sha1:nuEx7/m0sE4pQJtI8A9jSgixGrg= User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 In-Reply-To: Xref: csiph.com comp.arch.embedded:24587 On 16-07-09 00:48 , Les Cargill wrote: > Niklas Holsti wrote: >> On 16-07-08 20:50 , Les Cargill wrote: >>> Tim Wescott wrote: [snips] >>>> I'm not entirely sure, but I think there's a possibility that if your >>>> code _does_ have such an interaction between tasks, then it means that >>>> there's something fundamentally wrong with your software design, or >>>> possibly your system design as a whole. >>> >>> That's kind of what I mean by "dependence on priority is Bad." >> >> That is not how I have understood your dislike of priorities. My current >> project has about 20 tasks. One of these tasks is cyclic with a 2 ms >> period; another is the background task which scrubs RAM with a deadline >> measured in several minutes. These two tasks do not interact at all, >> apart from sharing the same processor. The application depends on the 2 >> ms task having a higher priority than the background task, and I find it >> hard to image how that dependency can be called "bad". >> > > That's a case where it doesn't matter. I've seen cases where > mis-assigning the task priorities caused different behavior. > > That's bad. Mis-assigning priorities is IMO the same kind of programming error as mis-defining the termination condition of a loop. But it would be nonsensical to say that it is bad if an application depends on the termination condition of a loop. I believe I do understand your concern, that changing the priorities should not change the "result" of the program, for example because priorities have been used to control the sharing of data between tasks, such that changing the priorities causes (different) data-access races and thus changes the data-flow in the computation. Mutual exclusion and race-prevention *can* be implemented correctly by priorities (for example using the Immediate Priority Ceiling Inheritance protocol, as in my application), but of course it can also be done incorrectly. However, in a real-time application the behaviour always depends on the timing of the SW actions, even if there are no data races in the SW. For example, if the SW is supposed to sample an ADC at 100 Hz, but the new priorities mean that it is sampled only at 50 Hz, or with a large jitter, inevitably the results will be different, and perhaps useless. (You can say that in this case there is a data-race between the SW and the HW, and I would agree, but that is typical for real-time systems.) > Your situation is simple enough that it's okay. With exactly two > tasks, you will have highly deterministic operation - assuming the > memory scrubber doesn't cause any untoward starvation . I have something like 20 tasks, at multiple priorities and with some complex interactions. I use priorities to gain determinism, not to lose it. > With, say a 100msec time tick that runs the task queue, The kernel in this application (the AdaCore RTS for the LEON2 processor) is tickless. The clock and timer resolution is sub-microsecond. Task switch times are about 50 us on this 86 MHz processor. > But I would also say that having the memory scrubber coded such that > it would behave the same whether the kernel is preemptive or not > would be a better design and implementation. I totally disagree. A non-preemptive system would force me to insert a large number of "yield" calls in all tasks, carefully placed so that the execution time between yields never exceeds the maximum latency I allow for the 2 ms task. Yuck, yuck, triple yuck. > Hopefully, you have a good handle on the jitter for the 2ms task. I believe I do. With the preemptive and tickless kernel, it is limited by the maximum duration of actions at higher priorities. As this task is the highest-priority task, only interrupt handling and other interrupt-level operations (start/stop I/O) can cause jitter. > Ironically, one way I've estimated CPU utilization is to write a "do > nothing" loop at very low priority that only increments a counter, then > something periodically dumps a hi-res clock and the counter. The ever-ready background memory-scrubbing task plays that role in my application; the actual scrubbing rate is an estimate of the CPU load posed by the other, higher-priority tasks. This is a very common design in this domain (satellite on-board SW). If I want to have more detailed measurements, I can use the kernel's task-specific and interrupt-specific CPU-time accounting. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .