arkhipenko / TaskScheduler

Cooperative multitasking for Arduino, ESPx, STM32, nRF and other microcontrollers
http://playground.arduino.cc/Code/TaskScheduler
BSD 3-Clause "New" or "Revised" License
1.33k stars 243 forks source link

Way to shutoff the catchup #103

Closed glennramalho closed 4 years ago

glennramalho commented 4 years ago

I would suggest to add a new feature. We would need a dontCatchup bool and a function setDontCatchup(). Then change line 1014 of the TaskScheduler.h to say:

if (dontCatchup) iCurrent->iPreviousMilis = m + iCurrent->iDelay; else iCurrent->iPreviousMillis += iCurrent->iDelay;

The reason is I have been using the task scheduler on an ESP and I was having some trouble with delays in a task. Yes, I know, tasks should not have delays, but sometimes they do. I can't always get around it. So, when a task delays, then, as you know, the scheduler tries to catchup by issuing all tasks that should have already run. On my program though, all tasks are periodical, so I would prefer to loose the extra tasks. I have tried using a hack where I scan the list for overrun tasks, set delay(0) and then clear the iOverrun variable, but it is a bit messy. The above feature I would think would be a clean way to support this kind of task.

arkhipenko commented 4 years ago

Not the first time this is requested - I am thinking about it...

arkhipenko commented 4 years ago

ok. just pushed version 3.2.0 update to the testing branch - please test if you have time. Refer to example 26 for functionality for now (no documentation yet)

If you compile with this #define _TASK_SCHEDULING_OPTIONS // Support for multiple scheduling options you have 3 scheduling options for every task:

Here is the output with explanations:

Scheduling Options: setup()
1033: t1 start time
1043: t2 start time
1053: t3 start time
1386: 333 ms delay ended

three tasks are scheduled with a 10 ms space between them, each runs 10 times with 100 ms interval. there is a 333 ms delay before first invokation

1386: t1CB()
1396: t2CB()
1406: t3CB()

all tasks start as soon as possible

1416: t1CB()
1426: t1CB()
1436: t1CB()

t1 tries to catch upi immediately

1446: t2CB()

t2 tries to maintain an original schedule (s/b 1443), but is pushed a little by t1

1456: t1CB()

likewise, t1 is trying to run at 1433, but is pushed by t2

1506: t3CB()

t3, with priority for the interval, not schedule, runs at 1506 (1406 + 100 ms) as scheduled

1533: t1CB()
1543: t2CB()
1606: t3CB()

finally, all tasks are caught up with their respective schedules (t1 at x33, t2 at x43 and t3 at x06)

1633: t1CB()
1643: t2CB()
1706: t3CB()
1733: t1CB()
1743: t2CB()
1806: t3CB()
1833: t1CB()
1843: t2CB()
1906: t3CB()
1933: t1CB()
1943: t2CB()
2006: t3CB()

t1 finishes early because of the "catch-up"

2043: t2CB()
2106: t3CB()
2143: t2CB()
2206: t3CB()
2243: t2CB()
2306: t3CB()

rest of the tasks finish their 10 iterations later because they skipped "catch up".

glennramalho commented 4 years ago

Looks good. I just tested it and it worked. Thanks.