I don’t understand busy modes of a timer object
TL;DR: What is the difference between timers using the BusyMode options drop and queue, and the ExecutionMode options fixedDelay and fixedRate? Different parts of the documentation seem to say different things.
I am trying to understand the details of how the timer object works, but am having trouble. I am using the timer help page, and the more detailed article "Handling Timer Queuing Conflicts".
https://www.mathworks.com/help/releases/R2022b/matlab/ref/timer.html
https://www.mathworks.com/help/releases/R2022b/matlab/matlab_prog/handling-timer-queuing-conflicts.html
I understand that ExecutionMode="fixedSpacing" effectively adds the execution time of the timer callback to the timer period*, which also means that the callback can never be called while the callback is running. I also understand that when ExecutionMode="fixedRate", I need to use BusyMode to prevent callbacks colliding, and that I can use BusyMode="error" to throw an error (or take another action) if that would happen.
However, I am confused by the other two BusyModes, drop and queue, and how they compare to ExecutionMode="fixedDelay".
The timer help page says that BusyMode="drop" will "drop" the new task "when a timer has to execute TimerFcn before the completion of previous execution of the TimerFcn" and that "skipping of TimerFcn calls" is possible. To me, this suggests that an instance of TimerFcn will be skipped and that the timer period immediately begins afresh.
In contrast, BusyMode="queue" will "wait for [the execution] queue to clear, and then enter task in queue", and "adjusts Period property to manage tasks in execution queue". To me, this suggests that the new TimerFcn will start as soon as the old one finishes, and that it will increase its period (perhaps hidden from the user) to avoid having too many instances of TimerFcn in the queue.
When I look at the "Handling Timer Queuing Conflicts" article for more information, however, it gives an example where drop and queue behave identically! Both examples set a timer to run five times, with period 1s and a timer function that takes 1.6s to run. What I expect: when BusyMode="queue", the timer callback occurs every 1.6s; when BusyMode="drop", the timer callback occurs every 2s (the odd-numbered tasks being dropped, because the callback is running). What actually happens: in both cases, the timer callback occurs every 1.6s. This isn’t just a bug in my version of Matlab – the actual article has a table describing what should happen, and although a few of the internal details are different, it clearly shows TimerFcn being started every 1.6s (+ queue lag). The description of what happens within the timer doesn’t help all that much, since there are some details that I am sure must be mistakes (e.g. for drop, the 4th and 5th calls of the timer function are dropped twice each).
About ExecutionMode="fixedDelay", the timer help page says that the timer period starts "when the timer function callback restarts execution after a time lag due to delays in the MATLAB execution queue" (contrasting with "immediately after the timer callback function is added to the MATLAB execution queue" for ExecutionMode="fixedRate"). I would take this description to mean that fixedDelay works much like fixedRate, except that the timing is less precise because fixedDelay includes an unknown amount of queue delay. However, in the BusyMode section, the page also says, "for other values of ExecutionMode [other than fixedRate], there cannot be overlapping attempts to execute the timer callback function because the delay between executions is always relative to the completion of the previous execution". I don’t see how this can be true unless Matlab deliberately adjusts the queue lag to make this happen. Even more confusingly, the diagram actually shows fixedDelay’s timer function starting just before the previous call finishing (although it is so close that I’m sure that wasn’t intentional). When I test fixedDelay, it seems to operate identically to the fixedRate tests described above (within a few milliseconds for the queue lag). I have attached those demos to this file (run testTimers.m to demonstrate them, first with a period less than the timer function time; then with a period greater than the timer function time).
I may just have completely missed something completely obvious, but I would very much welcome enlightenment!
*Although some aspects of fixedSpacing do still puzzle me!TL;DR: What is the difference between timers using the BusyMode options drop and queue, and the ExecutionMode options fixedDelay and fixedRate? Different parts of the documentation seem to say different things.
I am trying to understand the details of how the timer object works, but am having trouble. I am using the timer help page, and the more detailed article "Handling Timer Queuing Conflicts".
https://www.mathworks.com/help/releases/R2022b/matlab/ref/timer.html
https://www.mathworks.com/help/releases/R2022b/matlab/matlab_prog/handling-timer-queuing-conflicts.html
I understand that ExecutionMode="fixedSpacing" effectively adds the execution time of the timer callback to the timer period*, which also means that the callback can never be called while the callback is running. I also understand that when ExecutionMode="fixedRate", I need to use BusyMode to prevent callbacks colliding, and that I can use BusyMode="error" to throw an error (or take another action) if that would happen.
However, I am confused by the other two BusyModes, drop and queue, and how they compare to ExecutionMode="fixedDelay".
The timer help page says that BusyMode="drop" will "drop" the new task "when a timer has to execute TimerFcn before the completion of previous execution of the TimerFcn" and that "skipping of TimerFcn calls" is possible. To me, this suggests that an instance of TimerFcn will be skipped and that the timer period immediately begins afresh.
In contrast, BusyMode="queue" will "wait for [the execution] queue to clear, and then enter task in queue", and "adjusts Period property to manage tasks in execution queue". To me, this suggests that the new TimerFcn will start as soon as the old one finishes, and that it will increase its period (perhaps hidden from the user) to avoid having too many instances of TimerFcn in the queue.
When I look at the "Handling Timer Queuing Conflicts" article for more information, however, it gives an example where drop and queue behave identically! Both examples set a timer to run five times, with period 1s and a timer function that takes 1.6s to run. What I expect: when BusyMode="queue", the timer callback occurs every 1.6s; when BusyMode="drop", the timer callback occurs every 2s (the odd-numbered tasks being dropped, because the callback is running). What actually happens: in both cases, the timer callback occurs every 1.6s. This isn’t just a bug in my version of Matlab – the actual article has a table describing what should happen, and although a few of the internal details are different, it clearly shows TimerFcn being started every 1.6s (+ queue lag). The description of what happens within the timer doesn’t help all that much, since there are some details that I am sure must be mistakes (e.g. for drop, the 4th and 5th calls of the timer function are dropped twice each).
About ExecutionMode="fixedDelay", the timer help page says that the timer period starts "when the timer function callback restarts execution after a time lag due to delays in the MATLAB execution queue" (contrasting with "immediately after the timer callback function is added to the MATLAB execution queue" for ExecutionMode="fixedRate"). I would take this description to mean that fixedDelay works much like fixedRate, except that the timing is less precise because fixedDelay includes an unknown amount of queue delay. However, in the BusyMode section, the page also says, "for other values of ExecutionMode [other than fixedRate], there cannot be overlapping attempts to execute the timer callback function because the delay between executions is always relative to the completion of the previous execution". I don’t see how this can be true unless Matlab deliberately adjusts the queue lag to make this happen. Even more confusingly, the diagram actually shows fixedDelay’s timer function starting just before the previous call finishing (although it is so close that I’m sure that wasn’t intentional). When I test fixedDelay, it seems to operate identically to the fixedRate tests described above (within a few milliseconds for the queue lag). I have attached those demos to this file (run testTimers.m to demonstrate them, first with a period less than the timer function time; then with a period greater than the timer function time).
I may just have completely missed something completely obvious, but I would very much welcome enlightenment!
*Although some aspects of fixedSpacing do still puzzle me! TL;DR: What is the difference between timers using the BusyMode options drop and queue, and the ExecutionMode options fixedDelay and fixedRate? Different parts of the documentation seem to say different things.
I am trying to understand the details of how the timer object works, but am having trouble. I am using the timer help page, and the more detailed article "Handling Timer Queuing Conflicts".
https://www.mathworks.com/help/releases/R2022b/matlab/ref/timer.html
https://www.mathworks.com/help/releases/R2022b/matlab/matlab_prog/handling-timer-queuing-conflicts.html
I understand that ExecutionMode="fixedSpacing" effectively adds the execution time of the timer callback to the timer period*, which also means that the callback can never be called while the callback is running. I also understand that when ExecutionMode="fixedRate", I need to use BusyMode to prevent callbacks colliding, and that I can use BusyMode="error" to throw an error (or take another action) if that would happen.
However, I am confused by the other two BusyModes, drop and queue, and how they compare to ExecutionMode="fixedDelay".
The timer help page says that BusyMode="drop" will "drop" the new task "when a timer has to execute TimerFcn before the completion of previous execution of the TimerFcn" and that "skipping of TimerFcn calls" is possible. To me, this suggests that an instance of TimerFcn will be skipped and that the timer period immediately begins afresh.
In contrast, BusyMode="queue" will "wait for [the execution] queue to clear, and then enter task in queue", and "adjusts Period property to manage tasks in execution queue". To me, this suggests that the new TimerFcn will start as soon as the old one finishes, and that it will increase its period (perhaps hidden from the user) to avoid having too many instances of TimerFcn in the queue.
When I look at the "Handling Timer Queuing Conflicts" article for more information, however, it gives an example where drop and queue behave identically! Both examples set a timer to run five times, with period 1s and a timer function that takes 1.6s to run. What I expect: when BusyMode="queue", the timer callback occurs every 1.6s; when BusyMode="drop", the timer callback occurs every 2s (the odd-numbered tasks being dropped, because the callback is running). What actually happens: in both cases, the timer callback occurs every 1.6s. This isn’t just a bug in my version of Matlab – the actual article has a table describing what should happen, and although a few of the internal details are different, it clearly shows TimerFcn being started every 1.6s (+ queue lag). The description of what happens within the timer doesn’t help all that much, since there are some details that I am sure must be mistakes (e.g. for drop, the 4th and 5th calls of the timer function are dropped twice each).
About ExecutionMode="fixedDelay", the timer help page says that the timer period starts "when the timer function callback restarts execution after a time lag due to delays in the MATLAB execution queue" (contrasting with "immediately after the timer callback function is added to the MATLAB execution queue" for ExecutionMode="fixedRate"). I would take this description to mean that fixedDelay works much like fixedRate, except that the timing is less precise because fixedDelay includes an unknown amount of queue delay. However, in the BusyMode section, the page also says, "for other values of ExecutionMode [other than fixedRate], there cannot be overlapping attempts to execute the timer callback function because the delay between executions is always relative to the completion of the previous execution". I don’t see how this can be true unless Matlab deliberately adjusts the queue lag to make this happen. Even more confusingly, the diagram actually shows fixedDelay’s timer function starting just before the previous call finishing (although it is so close that I’m sure that wasn’t intentional). When I test fixedDelay, it seems to operate identically to the fixedRate tests described above (within a few milliseconds for the queue lag). I have attached those demos to this file (run testTimers.m to demonstrate them, first with a period less than the timer function time; then with a period greater than the timer function time).
I may just have completely missed something completely obvious, but I would very much welcome enlightenment!
*Although some aspects of fixedSpacing do still puzzle me! timer, executionmode, busymode MATLAB Answers — New Questions