Page 1 of 1

Timer based task switching

Posted: Fri Sep 26, 2008 6:11 am
by Kieran
Hi guys,
I'm wandering how to get timer based interrupts working correctly.
So far, I have implemented only co-operative multitasking with sched() and yield()

Will tasks still have to do a continuous loop?

I'm having trouble with understanding how this works...

Re: Timer based task switching

Posted: Fri Sep 26, 2008 7:12 am
by bontanu
In simple terms:

1) When the interupt comes it will preemptively stop any task that is currently running.

2) In IRQ code you check the list of tasks / threads available and you choose another task to be executed.

3)Save the context of the current task. Restore the context of the new task that you have chosen to run.

4) IRETD - will return to the new task instead of the old task.

A lot of errors can be made here and the algorithm for choosing the new task to be executed has generated endless disputes but overall this is it.

Re: Timer based task switching

Posted: Fri Sep 26, 2008 8:38 am
by Kieran
Sorry, I think you misunderstood the question.

Code: Select all

1. Timer IRQ Fires
2. Scheduler Suspends current task (Task0) & saves context
3. Sceduler finds next runnable task (Task1)
4. Context Switch (Now in new task) (Task1)
But what happens if there is no loop? I would execute code past the end of the task's code...

Sorry, just realized I didn't need to ask that question, I indeed already knew the answer.

I was thinking that task code would not have a loop, but the task code will follow this process:

Code: Select all

1. Entry point (Task[0]())
2. Initialization code
3. DO
4.   Task Code...
5. LOOP until task is done
6. kill Task[0]

Re: Timer based task switching

Posted: Fri Sep 26, 2008 8:48 am
by kubeos
That's what I'm doing with my tasks. I use a timer to round robin schedule each task. I don't really care about priorities but it shouldn't be hard to impliment if I ever do care. :) Each of my tasks just does a continues do{ ... }while(1); loop and prints it's pid to the screen every second.

Re: Timer based task switching

Posted: Fri Sep 26, 2008 8:55 am
by Kieran
The original thought of this post came when thinking about loading a piece of code.

If I was to load and execute a piece of code written for a single thread environment or indeed i want to run a function in multiple tasks, if that code did not unschedule itself once execution was finished, execution would continue beyond EIP=End of code...

How would I even detect such a thing?

How would I correct once detected?

Re: Timer based task switching

Posted: Fri Sep 26, 2008 9:03 am
by AJ
Hi,

You need an exit() system call.

Generally when starting a task, you have a stub called the runtime that you call as the entry point. This "wraps" the main function of your process and ensures that if main() returns without calling exit(), everything finishes gracefully.

Cheers,
Adam

Re: Timer based task switching

Posted: Fri Sep 26, 2008 10:26 am
by kubeos
In your exit() syscall you have to schedule a new valid context/task so that the task that is exiting is no longer running. I just use a simple flag in my task structure task[pid].used=1 and set it to 0 during my exit syscall. Then I force a switch to my shell context. The timer only switches to tasks that have task[pid].used==1. So far it seems to be working very well (except now I need to figure out mutexes for syscalls that use vm86) #-o

EDIT: If you have an idle task you could switch to that.. I'm still fixing bugs so that's why I switch to my shell context.