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.23k stars 224 forks source link

Get upcoming task #58

Closed jdk27 closed 5 years ago

jdk27 commented 6 years ago

It would be a good idea to be able to find the upcoming task that will be executed given the current task

arkhipenko commented 6 years ago

Hi Josh,

Every task has member pointers to the next and previous task in the evaluation chain, which are currently private, but I can make them available via methods.

However, those are NOT the tasks which will be invoked next! It is practically impossible to say which task will be invoked next because tasks can be triggered by events via Status Request objects, they can be enabled by other tasks, pin interrupt service routines, etc. etc. So if you are asking to predict which task will be active after this one - it is "mission impossible" unfortunately.

Please send me your use case in case I misunderstood your question though.

Best, Anatoli


From: Josh notifications@github.com Sent: Friday, July 20, 2018 5:11 PM To: arkhipenko/TaskScheduler Cc: Subscribed Subject: [arkhipenko/TaskScheduler] Get upcoming task (#58)

It would be a good idea to be able to find the upcoming task that will be executed given the current task

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHubhttps://github.com/arkhipenko/TaskScheduler/issues/58, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AATGTVc2mdImcALmiAFnM9qo1spGD48Pks5uIkd_gaJpZM4VZRp2.

jdk27 commented 6 years ago

Unfortunately I'm trying to get the next task to be invoked. Would there be a way to loop through each task in the evaluation chain passing it to the timeUntilNextIteration() to determine the upcoming task?

arkhipenko commented 6 years ago

It will only work in simple and straightforward cases. What is the problem you are trying to solve? Maybe there is another way.


From: Josh notifications@github.com Sent: Friday, July 20, 2018 6:54 PM To: arkhipenko/TaskScheduler Cc: Anatoli Arkhipenko; Comment Subject: Re: [arkhipenko/TaskScheduler] Get upcoming task (#58)

Unfortunately I'm trying to get the next task to be invoked. Would there be a way to loop through each task in the evaluation chain passing it to the untilNextIterationFunction() to determine the upcoming task?

— You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/arkhipenko/TaskScheduler/issues/58#issuecomment-406746186, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AATGTfjWBQwHDaTKqZ6A054JosO6_eXcks5uIl-7gaJpZM4VZRp2.

jdk27 commented 6 years ago

I'm trying to get my device to sleep between tasks, but I am using the feather M0 so I can't use the idle functionality from the library. Instead I'm using the rtc standbymode and setting the alarm to trigger right before the next task.

GitMoDu commented 6 years ago

Why don't you implement the idle functionality for your M0? It's not that complicated, add a define and to sleep for 1 ms. Then you'll still be sleeping 99% of the unused time, with the just the light overhead of waking, checking scheduler and going to sleep again.

arkhipenko commented 6 years ago

Based on the use case I see how this information could be used: I can envision a scheduler collecting all the differences between current time and next invocation time for each of the tasks in the chain, and in the event when none of the callback methods was invoked, which means there is no way any of the past tasks' execution parameters were changed, the lowest of those values will be the time between now and the next task to be invoked. Which is a time interval the MC could be put to sleep. Any task starting on a pin or other hardware interrupt would wake up the MC, and as long as millis() continued to tick, scheduling should continue.

I need to think how to implement this in a safe manner. I hate to touch the main scheduling code, as it is the core of the library and has been heavily optimized for speed. Really don't want to add cycles to it unless absolutely necessary.

GitMoDu commented 6 years ago

Ah, I know what you mean. I thought about implementing the same thing on the previous scheduler I used. I was having trouble migrating to STM32 so I ended up here :P

The approach you suggest can most definitely work, in fact, I think it was extremely easy to do with ArduinoProcessScheduler because there is already a method called "get next process to run". You are correct about interrupts as well, they do not interfere. There might be some edges cases there if your logic depends on a timer value with no interrupt, for instance, but I don't think that's gonna happen.

Like I said, I had the same idea, until I saw arkhipenko's 1 ms idle sleep. This way, you don't even need to care about timings, next runs, etc... If you sleep for 1 ms, check that there's still no task to run, go back sleep for 1 ms. Now, is your, more complex, alternative going to significantly increase the gains from the Idle 1 ms sleep? Personally I don't think so, but I may be wrong. I mean, possibly saving 13 microseconds in a 1000 is that important?

arkhipenko commented 6 years ago

Completely agree with @GitMoDu, and even more so, I really hate to add anything to the scheduling loop that is not widely used but adds overhead to each evaluation pass. The goal is to minimize overhead as much as possible.

skezo commented 5 years ago

@arkhipenko

Would you consider making the pointers to next and previous task publicly available? This would allow us to loop through all current tasks in the scheduler. For example to find out what task IDs are currently set.

arkhipenko commented 5 years ago

Yes. And I wanted to look at the Scheduler APIs and see what else could be required to manage the task chains.