On Sun, Mar 2, 2014, at 02:29 PM, Michael Haberler wrote: > > Am 02.03.2014 um 15:21 schrieb John Kasunich <[email protected]>: > > > > There are several variables that are used to communicate > > between the two parts. The faster part was written assuming > > that those variables would not change during any single > > execution of the code. Allowing the slower thread to have a > > higher priority (and thus to interrupt) the faster thread would > > break that assumption. > > > I have read up on the data flow in stepgen.c and I found the following for > normal (i.e. not disabled, and setup disregarded): > > make_pulses reads: > stepgen->accum > stepgen->target_addval > stepgen->deltalim > > make_pulses writes: > stepgen->accum > > update_freq reads: > stepgen->accum > > update_freq writes: > stepgen->target_addval > stepgen->deltalim > > Now stepgen->accum can be taken out of the picture for considering > transactions since that is the single scalar value read back by update_freq > (it could be replaced by an atomic 64bit fetch which is supported on all > architectures, but that is a side issue). > > The interesting case are the two values which update_freq writes. I assume > you are referring to those?
I wasn't referring to anything that specific, I haven't looked at that code in years and could not tell you what the variable are or what they are used for (although now that you have listed them I'm starting to remember some parts of it). I would clearly have to study the code to refresh my memory. But that is a detail. I was simply stating that an assumption was made when the code was written. If we are planning to change that assumption now, then every piece of code that relied on the assumption needs to be identified, checked, and if neccessary revised. There are other reasons for retaining rate-monotonic scheduling, such as the latency impact of allowing a slow servo thread to block a faster base thread. I strongly believe that we should preserve rate-monotonic scheduling for multiple reasons. > > I can see how scheduling comes in here the way this is coded, but I think > this is basically a complicated way to achieve an atomic message transmit > from update_freq to make_pulses. How is it complicated? There is no messaging system, there is simply rate-monotonic scheduling, and code written to work properly in that environment. > Assume there were a way to send records from update_freq to make_pulses in an > atomic fashion, and such an update record contains stepgen->target_addval, > and stepgen->deltalim. make_pulses would check if a new record is available; > if so, consume it and base the current calculation on the values contained > therein. If not, it would use the values recorded from the previous update > message, and proceed alike. > > In that case it would become meaningless what threads do in relation to each > other, since the result cannot be influenced by that. > > Note "Assume there were a way" is already present in entirety, it is Pavel's > ringbuffer code which does exactly that, see below. > > This is my hypothesis: > > we can replace thread interaction of compound values like above by > ringbuffer communications, and can forget about this scheduling rate and > priority business altogether. > > Can anybody falsify this hypothesis, and how? Really interested. Atomic transfers from faster threads to slower ones is only one result of rate monotonic scheduling. There are others that are far more important. I've never seen real-time control code that didn't use rate- monotonic scheduling. For example, at my current employer we are working on a motor drive. There is a 33uS thread that does the core current loop, a 500uS thread that does protection and speed loop, a 2.5mS thread for application specific outer loops, and background code for non-time- critical stuff. The background can be interrupted by any of the other threads. The 2.5mS thread can be interrupted by the 500uS and 33uS, and the 500uS can be interrupted by the 33uS. That is absolutely neccessary if the the time critical stuff in the faster threads is to be completed when it should be. I acknowledge that when you start running each thread on a different core, or CPU, or a completely different processor or device, then things get more complicated. In 2003-2005, we "solved" that problem by putting all realtime threads on the same CPU/core, so that the rate-monotonic assumptions would hold true. Maybe in 2014 that solution isn't good enough anymore. But to the extent that threads _might_ be on the same core, fast threads damn well better have priority over slow ones. > - Michael > > the ringbuffer code is here: > http://git.linuxcnc.org/gitweb?p=linuxcnc.git;a=blob;f=src/rtapi/ring.h;h=874c7793fe2d00c1c8002f2a04b1c742e785c02d;hb=refs/heads/unified-build-candidate-3#l266 > > The required operations are: > > record_write_begin() - allocate space for a message in the rb but do not > commit the write yet > record_write_end() - commit the write operation > record_next_size() - check data available and operate on same > record_shift() - consume the record. I didn't spend a lot of time studying that code. But a few things made me cringe. >From the code: /* record_write_begin(): * begin a zero-copy write operation for at least sz bytes. This povides a buffer * to write to within free ringbuffer space. * return 0 if there is sufficient space for the requested size * return EAGAIN if there is currently insufficient space * return ERANGE if the write size exceeds the ringbuffer size. So, tell me what update_freq() should do if the function returns anything other than zero? It seems to me that you MUST be absolutely sure that it will always return zero. And if you are sure (because you allocated the appropriate size buffer, etc,), then the tests are simply wasting time - after all, you made sure they would never fail. I have no doubt that Pavel's ringbuffer code is well thought out and serves the general purpose atomic transfer problem well. But it is overkill (and bloated) if the system has been properly designed to ensure that you never have allocation problems. If you do have allocation problems, then you are screwed in a real-time control application. -- John Kasunich [email protected] ------------------------------------------------------------------------------ Subversion Kills Productivity. Get off Subversion & Make the Move to Perforce. With Perforce, you get hassle-free workflows. Merge that actually works. Faster operations. Version large binaries. Built-in WAN optimization and the freedom to use Git, Perforce or both. Make the move to Perforce. http://pubads.g.doubleclick.net/gampad/clk?id=122218951&iu=/4140/ostg.clktrk _______________________________________________ Emc-developers mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/emc-developers
