#include #include #include #include "schedule.h" #include "mem_alloc.h" /* This file contains a bare bones skeleton for the scheduler function for the second assignment for the OSN course of the 2005 fall semester. Author: G.D. van Albada Section Computational Science Universiteit van Amsterdam Date: October 23, 2003 Modified: September 29, 2005 */ #define N_TRY 5 #define SLICE 10 /* This variable will simulate the allocatable memory */ static long memory[MEM_SIZE]; /* Struct with user data*/ typedef struct u_data { int priority; } u_data; /* Retrieves the first proces with a given or higher priority from the ready queue */ student_pcb* get_prio(int priority) { student_pcb *proc; proc = ready_proc; if (!proc) { return proc; } while (((u_data *)proc->userdata)->priority > priority) { proc = proc->next; } return proc; } /* Possibly moves the last proces to another queue based on the recieved event*/ void handle_last(event_type event) { student_pcb *last_proc = queue_last(&ready_proc); int last_prio = ((u_data *)last_proc->userdata)->priority; switch (event) { case TIME_EVENT: if (last_prio < 5) { ((u_data *)last_proc->userdata)->priority += 1; } break; case IO_EVENT: if (last_prio > 0) { ((u_data *)last_proc->userdata)->priority -= 1; } break; default: break; } } /* The actual CPU scheduler is implemented here */ static void cpu_scheduler(event_type event) { static int prio_offset = 0; student_pcb *proc; int proc_prio; proc = get_prio(prio_offset); if (!proc && prio_offset < 5) { prio_offset += 1; cpu_scheduler(event); return; } else if (!proc && prio_offset == 5) { return; } proc_prio = ((u_data *)proc->userdata)->priority; handle_last(event); queue_remove(&ready_proc, proc); set_slice(SLICE + pow(2, proc_prio)); queue_append(&ready_proc, proc); } /* The high-level memory allocation scheduler is implemented here */ static void give_memory() { int index; student_pcb *proc; proc = new_proc; for (int i = 0; i < N_TRY; i++) { if (proc) { index = mem_get(proc->mem_need); if (index >= 0) { proc->mem_base = index; u_data *ud = malloc(sizeof(u_data)); if (!ud) { exit(1); } proc->userdata = ud; ((u_data *)proc->userdata)->priority = 0; queue_remove(&new_proc, proc); queue_append(&ready_proc, proc); break; } else { proc = proc->next; } } else { break; } } } /* Here we reclaim the memory of a process after it has finished */ static void reclaim_memory() { student_pcb *proc; proc = defunct_proc; while (proc) { /* Free your own administrative structure if it exists */ if (proc->userdata) { free(proc->userdata); } /* Free the simulated allocated memory */ mem_free(proc->mem_base); proc->mem_base = -1; /* Call the function that cleans up the simulated process */ rm_process(&proc); /* See if there are more processes to be removed */ proc = defunct_proc; } } /* The main scheduling routine */ void schedule(event_type event) { static int first = 1; if (first) { mem_init(memory); finale = my_finale; first = 0; } switch (event) { case NEW_PROCESS_EVENT: give_memory(); break; case TIME_EVENT: case IO_EVENT: cpu_scheduler(event); break; case READY_EVENT: break; case FINISH_EVENT: reclaim_memory(); give_memory(); cpu_scheduler(event); break; default: printf("I cannot handle event nr. %d\n", event); break; } }