let time = ref 0;; let update_frequency = 13;; let update_quantum current_process _ (* pid *) process = if process <> current_process then match process.state with | Zombie i -> () | _ -> process.quantum <- process.quantum / 2;; let elect_process active_processes = let cmp p1 p2 = compare p1.quantum p2.quantum in (* List.sort est stable, ie. preserve l'ordre sur les clés de même valeur. List.rev assure un comportement FIFO à quatum égale, ce qui évite les situations de famine. *) active_processes := List.sort cmp (List.rev !active_processes); match !active_processes with | [] -> raise Halt | h :: t -> h.quantum <- 0; h;; (** system_state est inchangé *) let rec run system_state = if !verbose then Printf.eprintf "pid=%d code=%d starts running\n%!" system_state.current.pid system_state.current.pcode; let code = system_state.current.pcode in try process system_state.codes.(code) with Trap -> syscall system_state | Signal -> signal system_state | Invalid_argument _ -> raise Invalid_code and signal system_state = incr time; if !time mod update_frequency = 0 then Hashtbl.iter (update_quantum system_state.current) system_state.processes; let p = system_state.current in p.quantum <- p.quantum + 1; if p.quantum == max_quantum then begin if !verbose then Printf.eprintf "pid=%d preempted\n%!" system_state.current.pid; schedule system_state end else run system_state and schedule system_state = let p = elect_process system_state.active_processes in if !verbose then Printf.eprintf "resuming=%d\n%!" p.pid; system_state.current <- p; machine.reg <- p.preg; run system_state;; |