/** * Dequeue input queue, put into realtime / userjob queue */ void deqInputQ() { int validate; PcbPtr ps; while(inputQ && inputQ->arrivalTime <= cpuTimer) { ps = deqPcb(&inputQ); /* exception handling */ if((validate = validateJob(ps)) != 0) { printPcbInput(ps); if(validate == ERROR_MEM) printf("Job is demanding too much memory - deleted\n"); if(validate == ERROR_IO) printf("Job is demanding too many i/o resources - deleted\n"); free(ps); ps = NULL; } else { if(ps->priority == 0) { // priority == 0 -> real time queue ps->mab = memAlloc(realTimeMemory, MAX_MEMORY_REALTIME); realTimeQ = enqPcb(realTimeQ, ps); } else { // priority > 0 -> user job queue userJobQ = enqPcb(userJobQ, ps); } } } }
/** * 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; } } }
//funtion to run the algorithm void rr_run(){ PcbPtr current_process = NULL; int dispatch_timer = 0; while(input_head || rr_head || current_process){ //puts("input q:"); //print_arrivaltimes(input_head); //puts("rr q:"); //print_arrivaltimes(rr_head); while(input_head && input_head->arrivaltime <= dispatch_timer){ //dequeue the head of the input queue, then add //it to the end of the round robin queue. //We need to initialize the head if we haven't already if(!rr_head){ rr_head = deqPcb(&input_head); rr_head->next = NULL; } else{ PcbPtr tmp = deqPcb(&input_head); tmp->next = NULL; enqPcb(rr_head,tmp); } } if(current_process){ current_process->remainingcputime--; if(current_process->remainingcputime <= 0){ terminatePcb(current_process); free(current_process); current_process = NULL; } //if there is something waiting in the RR queue, //we need to stop the current process and give //another process some time. else if(rr_head){ if(kill(current_process->pid,SIGTSTP)){ fprintf(stderr,"temp stop of %d failed", (int)current_process->pid); } enqPcb(rr_head,current_process); current_process = NULL; } } if(!current_process && rr_head){ waitpid(-1, NULL, WUNTRACED); current_process = deqPcb(&rr_head); current_process->next = NULL; startPcb(current_process); } ++dispatch_timer; sleep(1); } }
/** * Read job dispatch list from the file */ void readFile(char *fileName) { int counter = 0; FILE *fp; if ( (fp = freopen(fileName, "r", stdin)) ) { char buffer[MAX_BUFFER]; PcbPtr ps; while (!feof(fp) && counter <= 1000) { // up to maximum 1000 jobs if (fgets(buffer, MAX_BUFFER, fp)) { ps = createnullPcb(); /* initialize Pcb */ ps->arrivalTime = atoi(strtok(buffer, DELIMITER)); ps->priority = atoi(strtok(NULL, DELIMITER)); ps->remainingCpuTime = atoi(strtok(NULL, DELIMITER)); ps->memNeed = atoi(strtok(NULL, DELIMITER)); ps->io.printer = atoi(strtok(NULL, DELIMITER)); ps->io.scanner = atoi(strtok(NULL, DELIMITER)); ps->io.modem = atoi(strtok(NULL, DELIMITER)); ps->io.cd = atoi(strtok(NULL, DELIMITER)); inputQ = enqPcb(inputQ, ps); } counter++; } } else { error("Job dispatch list file is not found\n"); } }
int main (int argc, char *argv[]) { char * inputfile; // job dispatch file FILE * inputliststream; PcbPtr inputqueue = NULL; // input queue buffer PcbPtr currentprocess = NULL; // current process PcbPtr process = NULL; // working pcb pointer int timer = 0; // dispatcher timer // 0. Parse command line if (argc == 2) inputfile = argv[1]; else PrintUsage (stderr, argv[0]); // 1. Initialize dispatcher queue; // (already initialised in assignments above) // 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) // 4. While there's anything in the queue or there is a currently running process: while(inputqueue != NULL || currentprocess != NULL){//begin while // i. If a process is currently running; if(currentprocess != NULL){//begin if // a. Decrement process remainingcputime; currentprocess->remainingcputime--; // b. If times up: if(currentprocess->remainingcputime <=0){//begin if1 // A. Send SIGINT to the process to terminate it; currentprocess = terminatePcb(currentprocess); // B. Free up process structure memory free(currentprocess); printf("Successful"); }//end if1 }//end if // ii. If no process now currently running && // dispatcher queue is not empty && // arrivaltime of process at head of queue is <= dispatcher timer: if(currentprocess == NULL && inputqueue != NULL && inputqueue->arrivaltime <= timer){//begin if // a. Dequeue process and start it (fork & exec) // b. Set it as currently running process; process = deqPcb(&inputqueue); currentprocess = startPcb(process); }//end if // iii. sleep for one second; sleep(1); // iv. Increment dispatcher timer; timer++; // v. Go back to 4. continue; }//end while // 5. Exit exit (0); }
int main (int argc, char *argv[]) { char * inputfile; // job dispatch file FILE * inputliststream; PcbPtr inputqueue = NULL; // input queue buffer PcbPtr currentprocess = NULL; // current process // PcbPtr process = NULL; // working pcb pointer int timer = 0; // dispatcher timer // 0. Parse command line if (argc == 2) inputfile = argv[1]; else PrintUsage (stderr, argv[0]); // 1. Initialize dispatcher queue; // (already initialised in assignments above) // 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); } PcbPtr nextPCB; while (!feof(inputliststream)) { // put processes into input_queue nextPCB = createnullPcb(); if(fscanf(inputliststream, "%d, %d, %d, %d, %d, %d, %d, %d", &(nextPCB->arrivaltime), &(nextPCB->priority), &(nextPCB->remainingcputime), &(nextPCB->mbytes), &(nextPCB->req.printers), &(nextPCB->req.scanners), &(nextPCB->req.modems), &(nextPCB->req.cds) )!= 8){ free(nextPCB); continue; } nextPCB->status = PCB_INITIALIZED; inputqueue = enqPcb(inputqueue, nextPCB); } // 3. Start dispatcher timer; // (already set to zero above) // 4. While there's anything in the queue or there is a currently running process: while (inputqueue || currentprocess ) { if(currentprocess){ (currentprocess->remainingcputime) -= 1; if(currentprocess->remainingcputime == 0){ // if(prevprocess == NULL){ // // this would have to be the first/only process, or head of the queue // // that would mean the last process added would be the previous process // nextPCB->next = currentprocess->next; // }else { // prevprocess->next = currentprocess->next; // } //send SIGINT to terminate process terminatePcb(currentprocess); free(currentprocess); currentprocess = NULL; } } if (!currentprocess && inputqueue && inputqueue->arrivaltime <= timer){ currentprocess = deqPcb(&inputqueue); if(currentprocess) startPcb(currentprocess); } sleep(1); timer++; } // 5. Exit exit (0); }
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); }
/** * Main function */ int main(int argc, char **argv) { PcbPtr curPs = NULL, tmp; initialise(); /* read job dispatch list from the file */ if(argc != 2) error("Error: <file> argument missing or incorrect"); readFile(argv[1]); /* while there's currently running process or anything in queues */ while(curPs || inputQ || userJobQ || realTimeQ || priorityQ_1 || priorityQ_2 || priorityQ_3) { deqInputQ(); deqUserJobQ(); /* if there is a currently running process */ if(curPs) { curPs->remainingCpuTime -= TIME_QUANTUM; // decrement process remaining time /* if time's up */ if(curPs->remainingCpuTime <= 0) { /* terminate process */ curPs = terminatePcb(curPs); /* free memory */ if(curPs->priority == 0) curPs->mab->allocated = 0; else memFree(curPs->mab); /* free resource */ rsrcFree(curPs); free(curPs); curPs = NULL; } /* if user process and there's any process are waiting */ else if(curPs->priority > 0 && (realTimeQ || priorityQ_1 || priorityQ_2 || priorityQ_3) ) { curPs = suspendPcb(curPs); /* decrease priority, and enqueue on appropriate queue */ switch(curPs->priority) { case 1: priorityQ_2 = enqPcb(priorityQ_2, curPs); break; default: priorityQ_3 = enqPcb(priorityQ_3, curPs); break; } if(curPs->priority < 3) curPs->priority++; curPs = NULL; } } /* if no currently running process */ if(!curPs) { /* dequeue a highest priority process */ tmp = NULL; if(realTimeQ) tmp = deqPcb(&realTimeQ); else if(priorityQ_1) tmp = deqPcb(&priorityQ_1); else if(priorityQ_2) tmp = deqPcb(&priorityQ_2); else if(priorityQ_3) tmp = deqPcb(&priorityQ_3); /* if there's anything in dispatch queues */ if(tmp != NULL) { curPs = tmp; curPs = startPcb(curPs); // start or restart } } struct timespec req, rem; req.tv_sec = TIME_QUANTUM; req.tv_nsec = 0; nanosleep(&req, &rem); cpuTimer += TIME_QUANTUM; } /* free memory */ realTimeMemory = memFree(realTimeMemory); memory = memFree(memory); return 0; }