CS452 - Real-Time Programming - Fall 2008
Lecture 8 - Scheduling
Questions & Comments
- Changing the GDT register
Scheduling
When to schedule
Whenever we leave the kernel. When do we enter the kernel?
- Tasks run to completion
- Event-driven pre-emption
- internal events, like Pass( ), or Send( ), which occur when a task
gets to a particular point in its code
- external events
- Time-slicing
- re-schedule only when the slice-timer times out
- on internal events
- two problems
- slices are too big => bad response
- slices are too small => kernel runs too much = bad
response
Who to Schedule
- active task decides = co-processes
- round robin
- everybody gets the same chance
- but usually long running time = unimportant
- priorities
- fixed at compile time
- fixed when task is created
- re-fixed every time task is scheduled
- Do you have a good algorithm
- hybrid
- round robin queues for each priority
- determined by type of kernel entry
- Send wakes Receiver
- interrupt wakes interrupt destination
What God has Decided
Hybrid
What you decide
- How many priorities
- Which task should have which priority
- How to implement the queues
- one queue per priority
- fast insertion, but needs back pointer
- slow activation, but use a highest priority pointer
- one sorted queue
- slow insertion, but can be speeded up
- fast activation
Create
Pid = Create( char *name, int priority )
Return value might be an error
- out of task descriptors or memory
- not a pointer to an ELF executable
- not a valid priority
Choosing a Task ID
- Must be unique
- Must leave space for an error code
Create is a stub
- set up arguments for kernel
- enter kernel
- on return, retrieve return value from where kernel put it
- put it in the right place for return from function call.
What to do in the Kernel
1. Check priority
2. Get a free task descriptor (TD)
3. Initialize TD
- task state
- parent Pid
- priority
- other stuff not yet initializable
4. Define the Pid
- Must be unique
- Must leave space for an error return
5. Allocate segment for the stack
- set the stack pointer: SS, ESP
6. Choose PSW
- for now interrupts should be disabled
- push onto stack
7. Find code segment
- push CS and EIP onto stack
8. Add task to priority queues
9. Set return value to Tid
- put it in the TD of the caller
10. Put SS, ESP in TD
Return to: