MultiTrack (Basic): The YieldTask instruction
In the previous lesson I showed you how potentially blocking instructions like WaitOn and Pause will automatically cause a task switch, i.e. cause the task to yield so another task can run. But what if there are no such instructions being executed?
The YieldTask instruction lets you force a task switch anywhere you like in your program. This is something you have to think about, for two reasons:
- If a task never yields, no other task will get a chance to run.
- If a MultiTrack task executes more than 255 instructions without yielding, the controller will suffer a fatal runtime error (we made it that way to force you to do the right thing!)
To illustrate this, copy the following into SPLat/PC and run it:
(Click here for some tips for working around problems with copy and paste out of Internet Explorer and HTML-help (.chm) files)
LaunchTask TaskA
LaunchTask TaskB
RunTasksForever
TaskA: On 0
Pause 1
Off 0
Pause 1
GoTo TaskA
TaskB: IncM 0
GoTo TaskB
The program will “bomb out” after a short while. A YieldTask placed after the IncM instruction will allow it to run properly. Try it!
Here’s an example of a task that uses YieldTask. This task will monitor inputs 2 and 3 simultaneously. If input 2 comes on it increments RAM location Count. If input 3 comes on it decrements Count. Having counted up or down it waits for both inputs to be off, then repeats.
CountFunc: GoIfInOn 2,CountUp
GoIfInOn 3,CountDn
YieldTask ;Give someone else a go
GoTo CountFunc ;Loop and repeat
CountUp: IncM Count
GoTo WaitForBothOff
CountDn: DecM Count
WaitForBothOff: YieldTask
GoIfInOn 2,WaitForBothOff
GoIfInOn 3,WaitForBothOff
GoTo CountFunc
Count: mEQU 10 ;Declare the RAM variable
Exercise 1:
Combine the above task with the dual flasher example in the earlier example and get it running. Take time to study what the YieldTask is doing.
Hint: You can monitor Count at location 10 in the Data Memory window in SPLat/PC (explore the Window menu if this is unfamiliar ground).
Exercise 2:
The first loop of CountFunc (the first 4 instructions) uses one instruction more than necessary. Rearrange it so it only use 3 instructions. Hint: Move the YieldTask to the start of the loop, eliminate the unconditional GoTo and modify the remaining two conditional GoTo‘s so it works. Note: In general you should not stress over minor inefficiencies like this one in your code. In fact, unless you are pushing the limits of available memory, some inefficiencies are a good investment if they make the code easier to read.
Exercise 3:
Consider the following rewritten snippet of code:
WaitForBothOff: WaitOff 2
WaitOff 3
GoTo CountFunc
This would seem to achieve the same result with a saving of 2 lines of code. However, the original will only “trip” when both inputs are off simultaneously. Work out why the the above snippet could “trip” with input 2 on and input 3 off.