April 19th Lecture - Scheduling ================================= Round Robin (RR) * 1 ready list of processes * 1st proc on list selected for execution * proc runs for 1 quantum (max) then is moved to end of list * if proc blocks before quantum expires, move to next proc immediately * issues: quantum length: - quantum too short => too much overhead - quantum too long => poor response times (esp interactive tasks) * strength: fairness, no starvation * weakness: turn around time; also doesn't get anything finished and out of the way quickly (which could clear up resources) Virtual Round Robin (VRR) * two queues: ready + auxilary * if proc blocks before quantum is up, it rejoins the auxilary queue when it finishes blocking * processes are scheduled from the auxilary queue if it is non-empty, otherwise the ready queue * quantum for times on the auxilary queue = (q - CPU time already used since the process last left the ready queue) First Come First Serve (FCFS) * non-preemptive * procs run until finished or until they voluntarily block * almost no overhead * poor response ratio for short jobs stuck behind longer ones * model often used by user-level threading libraries; okay for intra-app, not so great for inter-app Shortest Job Next (SJN) * non-preemptive * simple: run "shortest" (either total or of next CPU burst) job * if all procs arrive at the same time, this gives the optimal average turnaround time * requires knowledge about execution time in advance (e.g., some kinds of realtime systems), or heuristics that can be used to guess * strength: avg turnaround time * weakness: starvation for longer jobs Shortest Remaining Time First (SRTF) * preemptive SJN * if new process arrives with a shorter length, it immediately preempts the currently running process Length of the next CPU burst is often estimated using the length of the previous bursts t(n) = actual length of n'th burst tau(n+1) = preducted value for next burst a: 0 <= a <= 1 t(n+1) = a*t(n) + (1-a)*tau(n) if a=0 => use same "guess" each time; don't react to changing behavior if a=1 => guess is always length of last burst if 0 balance between last burst and previous guesses Priority Scheduling * priority (int) associated with each proc * CPU is allocated to proc with lowest priority * we can define other algorithms in terms of priority: - SJN: prio = tau(n+1) - FCFS: prio = arrival time * priorities can be fixed or dynamic * aging: as time progresses, change priority of process (to avoid starvation) Lottery Scheduling: * Process P(i) has L(i) tickets * N tickets among all processes * process holding winning ticket gets to run * P(i) has L(i)/N chance to get the CPU * some implementations allow tickets to be handed off between cooperating processes 4.4BSD Scheduling * 256 priority levels in FreeBSD - 0-63: ITHD -- interrupt handlers, bottom half of kernel - 64-127: KERN -- system calls, top half of kernel - 128-159: REALTIME -- real-time processes - 160-223: TIMESHARE -- regular user processes - 224-255: IDLE -- only run if nothing at higher levels can run * one runqueue for each priority level * schedule first process from highest non-empty queue * if full quantum used => put back on end of same queue * priority adjusted dynamically: multilevel feedback * if new thread arrives at higher priority, switch to it immediately if current thread is in userspace; otherwise as soon as it leaves the kernel * kg_estcpu = estimated CPU time * kg_nice = user-tweakable knob (-20 to 20) * kg_userprio = PRI_MIN_TIMESHARE + kg_estcpu/4 + 2*kg_nice * (bounded by MIN_TIMESHARE and MAX_TIMESHARE) * recalculated every 4 clock ticks (~40 ms) * kg_estcpu is incremented for the currently running process each clock tick * kg_estcpu decays once per second: kg_estcpu = kg_estcpu * 2*load/(2*load+1) * load average - # of threads ready to run or waiting on short-term events such as IO ULE Scheduler * described in detail in discussion section * three queues: current, next, idle * when current is empty, swap it with next queue * schedule from current queue, place processes back on next queue * exception: ITHD, KERN, REALTIME, and interactive procs go back on end of current queue * advantages: no need for O(n) scan of process list; better support for multi-CPU and processor affinity