/** * Dequeue userjob queue, put into priority queues */ void deqUserJobQ() { PcbPtr ps; MabPtr mem; /* while head of userJobQ can be allocated on memory and resources available If the process is invalid (requires more than maximum of memory or i/o), it should also be enqueued to ensure it is terminate on starting time */ while(userJobQ && (mem = memChk(memory, userJobQ->memNeed)) && rsrcChk(userJobQ)) { ps = deqPcb(&userJobQ); /* allocate memory block */ ps->mab = memAlloc(mem, ps->memNeed); /* allocate I/O resource */ rsrcAlloc(ps); /* enqueue on appropriate feedback queue */ switch(ps->priority) { case 1: priorityQ_1 = enqPcb(priorityQ_1, ps); break; case 2: priorityQ_2 = enqPcb(priorityQ_2, ps); break; case 3: priorityQ_3 = enqPcb(priorityQ_3, ps); break; default: error("Process priority level should be between 1 to 3"); break; } } }
/* Move head of userqueue to feedback queues */ void enqueue_roundrobin() { PcbPtr process; while (user_queue) { // while there are items in the user queue if (check_resource(io_resources,user_queue) == 1 && memChk(memory,user_queue->mbytes)){ // if resources/memory can be allocated for the given process process = pcb_dequeue(&user_queue); process->memory = memAlloc(memory,process->mbytes); // allocating memory if (process->memory) { // making sure it is not null process->memory->id = process->id; } io_resources = allocate_resource(io_resources,process); switch (process->priority) { case 0: break; case 1: p1_queue = pcb_enqueue(p1_queue,process); break; case 2: p2_queue = pcb_enqueue(p2_queue,process); break; case 3: p3_queue = pcb_enqueue(p3_queue,process); break; default: fprintf(stderr, "Error. Priority not correctly set. Process ID: %d Priority: %d\n",process->id,process->priority); break; } } else { // leave the while loop when the above condition fails break; } } }
int main (int argc, char *argv[]) { char * inputfile; // job dispatch file FILE * inputliststream; PcbPtr inputqueue = NULL; // input queue buffer PcbPtr fbqueue[N_FB_QUEUES]; // feedback queues PcbPtr currentprocess = NULL; // current process PcbPtr process = NULL; // working pcb pointer int timer = 0; // dispatcher timer int quantum = QUANTUM; // current time-slice quantum int i; // working index // 0. Parse command line if (argc == 2) inputfile = argv[1]; else PrintUsage (stderr, argv[0]); // 1. Initialize dispatcher queues; for (i = 0; i < N_FB_QUEUES; fbqueue[i++] = NULL); // 2. Fill dispatcher queue from dispatch list file; if (!(inputliststream = fopen(inputfile, "r"))) { // open it SysErrMsg("could not open dispatch list file:", inputfile); exit(2); } while (!feof(inputliststream)) { // put processes into input_queue process = createnullPcb(); if (fscanf(inputliststream,"%d, %d, %d, %d, %d, %d, %d, %d", &(process->arrivaltime), &(process->priority), &(process->remainingcputime), &(process->mbytes), &(process->req.printers), &(process->req.scanners), &(process->req.modems), &(process->req.cds)) != 8) { free(process); continue; } process->status = PCB_INITIALIZED; inputqueue = enqPcb(inputqueue, process); } // 3. Start dispatcher timer; // (already set to zero above) //initialize memory MabPtr memall = createnullMab(1024); //split memory into "protected" Real Time process memory and User Memory MabPtr rtmem = memSplit(memall, 64); MabPtr mem = rtmem->next; //work with "mem" as user memory area mem->justused = 1; //initialize, the "justused" represents the most recently used, and the algorithm assumes one exists no matter what PcbPtr feedbackpending = NULL; // processes waiting for memory // 4. While there's anything in any of the queues or there is a currently running process: while (inputqueue || (CheckQueues(fbqueue) >= 0) || currentprocess ) { // i. Unload any pending processes from the input queue: // While (head-of-input-queue.arrival-time <= dispatcher timer) // dequeue process from input queue and and enqueue on feebackpending queue while (inputqueue && inputqueue->arrivaltime <= timer) { process = deqPcb(&inputqueue); // dequeue process process->status = PCB_READY; // set pcb ready process->priority = 0; // override any priority feedbackpending = enqPcb(feedbackpending, process); // & put on queue } PcbPtr nextprocess = feedbackpending; //unload pending processes from user job queue: //while (feedbackpending->mbytes is free somewhere in user mem: while(feedbackpending && memChk(mem, feedbackpending->mbytes)){ nextprocess = deqPcb(&feedbackpending); // dequeue process from user job queue nextprocess->memoryblock = memAlloc(mem, nextprocess->mbytes); // allocate memory to the process nextprocess->priority = 0; fbqueue[nextprocess->priority] = enqPcb(fbqueue[nextprocess->priority], nextprocess); } puts("got it"); // iii. If a process is currently running; if (currentprocess) { currentprocess->remainingcputime -= quantum; if (currentprocess->remainingcputime <= 0) { terminatePcb(currentprocess); memFree(currentprocess->memoryblock); free(currentprocess); currentprocess = NULL; // c. else if other processes are waiting in feedback queues: } else if (CheckQueues(fbqueue) >= 0) { suspendPcb(currentprocess); if (++(currentprocess->priority) >= N_FB_QUEUES) currentprocess->priority = N_FB_QUEUES - 1; fbqueue[currentprocess->priority] = enqPcb(fbqueue[currentprocess->priority], currentprocess); currentprocess = NULL; } } // iv. If no process currently running && feedback queues are not empty: if (!currentprocess && (i = CheckQueues(fbqueue)) >= 0) { currentprocess = deqPcb(&fbqueue[i]); startPcb(currentprocess); } // v. sleep for quantum; quantum = currentprocess && currentprocess->remainingcputime < QUANTUM ? currentprocess->remainingcputime : !(currentprocess) ? 1 : QUANTUM; sleep(quantum); timer += quantum; } exit (0); }