Multitasking and a terminated Main()

Started by Tom Becker January 12, 2006
I am puzzled. Below is code in which Main() starts a task and then spins. If the spin includes a Sleep(0), the running task displays 100% (on a BX-24p; adjust the 126 for BX-24 to see 100%), as a benchmark. 100% suggests that the processor is essentially unloaded by Main().

If Main() spins with no Sleep, the displayed BackGround value is 12%, i.e. Main() takes 88%. If Main() is allowed to terminate after starting BackGroundTask, the value is _still_ 12%.

I'd expect that Main() would be marked as halted and the only remaining running task would get all the time the OS doesn't use.

What's going on once Main() terminates with other running tasks?

dim BackGroundTaskStack(1 to 86) as byte
'
sub Main()
CallTask "BackgroundTask", BackGroundTaskStack
'
' try this loop with and without Sleep, and try no loop at all
' (i.e. just start BackGroundTask and allow Main to terminate)
do
call Sleep(0)
loop
end sub
'
sub BackGroundTask()
dim iX as integer, lSpinCount as long, lNow as long, lThen as long
lSpinCount = 0
lThen = Register.RTCTick
Do
For iX = 1 to 10000 'just spin and count
lSpinCount = lSpinCount + 1
Call Sleep(0) ' while foreground functions run
Next
lNow = Register.RTCTick ' get actual elapsed time
' adjust the 126 below as required to yield 100% with no foreground function
debug.print cStr(lSpinCount * 126 \ (lNow - lThen) \ 10) ' show normalized ratio
Loop
end sub
Tom



--- In basicx@basi..., "Tom Becker" <gtbecker@r...> wrote:
>
> I am puzzled. Below is code in which Main() starts a task and
then spins. If the spin includes a Sleep(0), the running task
displays 100% (on a BX-24p; adjust the 126 for BX-24 to see 100%),
as a benchmark. 100% suggests that the processor is essentially
unloaded by Main().
>
> If Main() spins with no Sleep, the displayed BackGround value is
12%, i.e. Main() takes 88%. If Main() is allowed to terminate after
starting BackGroundTask, the value is _still_ 12%.
>
> I'd expect that Main() would be marked as halted and the only
remaining running task would get all the time the OS doesn't use.
>
> What's going on once Main() terminates with other running tasks?
>

I would say that Main can not be terminated. Instead it goes into an
endless loop, therefore giving the same result as when your code
provides the endless loop (without the sleep call).

Ingvar



> I would say that Main [] goes into an endless loop...

A strong possibility.

I went back to fundamentals and wrote a very simple multitasking demo.
Code below, and I'll put up a file, since Yahoo destroys readability of
indented code.

The code runs two identical tasks and Main; eack task flips a
correspinding LED, making the time allocated to each task visible. Try
changing the Sleeps and LockTasks in various combinations. Very
intereseting insight, I thought. dim TaskAStack(1 to 21) as byte
dim TaskBStack(1 to 21) as byte

sub Main()
register.DDRD = register.DDRD or bx1010_0000 'LEDs out
register.PortD = register.PortD or bx1010_0000 'LEDs off
CallTask "TaskA", TaskAStack
CallTask "TaskB", TaskBStack

'call LockTask ' try locked
Do ' try no loop
call Sleep(0) ' try without this Sleep
Loop
end sub

sub TaskA()
dim bX as byte
'call LockTask ' try locked
Do
For bX = 1 to 100 ' spin
Call Sleep(0) ' try without this Sleep
Next
register.PortD = register.PortD xor bx0010_0000 'Green
Loop
end sub

sub TaskB()
dim bX as byte
'call LockTask ' try locked
Do
For bX = 1 to 100 ' spin
Call Sleep(0) ' try without this Sleep
Next
register.PortD = register.PortD xor bx1000_0000 'Red
Loop
end sub
Tom