void fn3(void *args)
{
 int *n = (int*)args;
 printQueues();
 printf("\nExecuting F3, ready queue id: %d\n", ready_queue->id);
 printf("\n The Argument Obtained is: %d", args);

 MySemaphoreSignal(sem1);
 temp = getSemaphoreFromId(sem1.semaphoreId);
 printf("\nF3 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue);
 MySemaphoreSignal(sem2);
 temp = getSemaphoreFromId(sem2.semaphoreId);
 printf("\nF3 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue);
 MySemaphoreSignal(sem1);
 temp = getSemaphoreFromId(sem1.semaphoreId);
 printf("\nF3 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue);
 MySemaphoreSignal(sem2);

 temp = getSemaphoreFromId(sem2.semaphoreId);
 printf("\nF3 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue);
 MySemaphoreSignal(sem2);

  temp = getSemaphoreFromId(sem2.semaphoreId);
 printf("\nF3 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue);
 MySemaphoreSignal(sem2);

  temp = getSemaphoreFromId(sem2.semaphoreId);
 printf("\nF3 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue);
 MySemaphoreSignal(sem2);

 temp = getSemaphoreFromId(sem2.semaphoreId);
 printf("\nF3 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue);
 printQueues();
}
void MySemaphoreWait(MySemaphore semaphore)
{

	/*The counter of S is positive 
In this case, the counter is decreased by 1 and the thread resumes its execution.
The counter of S is zero 
In this case, the thread is suspended and put into the private queue of S.*/
	
	MySemaphore* sem = getSemaphoreFromId(semaphore.semaphoreId);
	//capture the context here (1)
	printf("\nTP1");
	ucontext_t currentContext;
	getcontext(&currentContext);

	printf("\nTP1");
	printf("\n Semaphore Id: %d", sem->semaphoreId);
	printf("\n Semaphore Value: %d", sem->semaphoreValue);
	
	sem->semaphoreValue--;
	if (sem->semaphoreValue >= 0) //Verify once, if Semaphore value change from 1 to 0 allows the execu
		return; //the semaphore is free for access

	printf("\nTP2");
	printQueues();
	printf("\n Semaphore Value: %d", sem->semaphoreValue);
	printQueues();
	if(ready_queue == NULL)
	{
		setcontext(&controller);
	}
	if (ready_queue != NULL)
	{
		printf("\nTP2");
		printf("\nTP2");
		ready_queue->semaphoreBlocked = sem->semaphoreId;
		MyThread* trav = ready_queue->next;
		MyThread* temp = ready_queue;
		printf("\nTP3");
		insertIntoSemaphoreBlockedQueue(ready_queue);
		ready_queue->context = currentContext;
		ready_queue->next = NULL;
		ready_queue = trav;
		//printf("\n Printing the Queues from Thread Join: ");
		//printQueues();
		if(ready_queue != NULL)
			setcontext(&ready_queue->context);

		//Put the context captured at (1) into the blockedSemaphoreQueue
		
	}
}
int fn1()
{
 int n = 10;
 printf("\nExecuting F1, ready queue id: %d\n", ready_queue->id);
 printf("\n N = %d", n);
 printf("\n &N = %d", &n);
 sem1 = MySemaphoreInit(2);
 sem2 = MySemaphoreInit(0);
 printf("CPAfterSemaphoreCreation");
 printQueues();
 printf("\nGetting SemaphoreId: %d",sem1.semaphoreId);
 temp = getSemaphoreFromId(sem1.semaphoreId);
 printf("\nF2 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue);
 temp = getSemaphoreFromId(sem2.semaphoreId);
 printf("\nF2 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue);
 child2 = MyThreadCreate((void*)fn2, &n);
 child2 = MyThreadCreate((void*)fn2, &n);
 child2 = MyThreadCreate((void*)fn3, &n);
 child2 = MyThreadCreate((void*)fn2, &n);
 printf("\nthis is from 1_1\n");
 printf("\n Joining the threads: parent %d(won't run again), child %d", ready_queue->id, child2.id);
 MyThreadJoinAll();
 printf("\nthis is from 1_2\n");
 printf("If printed, %d has joined successfully", ready_queue->id);

}
void MyThreadInit(void(*start_funct)(void *), void *args)
{
start = 1;
	
	MyThread* node;
    	//printf("\nCP1");
	ready_queue = malloc(sizeof(MyThread));
	getcontext(&ready_queue->context);
 	ready_queue->context.uc_link=&controller;
 	ready_queue->context.uc_stack.ss_sp=malloc(MEM);
 	ready_queue->context.uc_stack.ss_size=MEM;
 	ready_queue->context.uc_stack.ss_flags=0;
	ready_queue->id = threadCount++;
	//printf("Allocation Initial Id: %d", ready_queue->id);

	makecontext(&ready_queue->context, (void*)start_funct, 1, (int)args);

	ucontext_t next;
	int id;	

	getcontext(&controller);

	//printf("\nAbout to Start Checking of Unblocking");
	//printQueues();
	CheckForUnblocking();
	//printf("\nChecked for Block");

	
	//printQueues();


	if(ready_queue != NULL)
	{
		
		
		if(start == 1)
		{
			next = ready_queue->context;
			id = ready_queue->id;
			//printf("\n 2 Should Repeat:");
			//printf("\n4Allocation Initial Id: %d", ready_queue->id);
			start = 0;
			//printQueues();
			setcontext(&next);
		}
		else if (ready_queue->next != NULL)
		{	
			ready_queue = ready_queue->next;
			//CheckForUnblocking();
			next = ready_queue->context;
			id = ready_queue->id;
			//printf("\n 2 Should Repeat:");
			//printf("\nSetting Context Id: %d",id);


			//printQueues();

			setcontext(&next);
		}
		else 
		{	
			//printf("1Entering New Code");
			ready_queue = NULL;
			//printf("2Entering New Code");
			//printQueues();
			CheckForUnblocking();
			//printf("1Entering New Code");
			if (ready_queue != NULL)
			{
				next = ready_queue->context;
				id = ready_queue->id;
				//printf("\n 2 Should Repeat:");
				//printf("\nSetting Context Id: %d",id);


				//printQueues();

				setcontext(&next);
			}
		}
	}
 	printf("completed\n");
 	printQueues();
 	printf("Final Queue Remains: ");
 	MySemaphoreDestroy(sem1);
 	MySemaphoreDestroy(sem2);
 	printQueues();

}
void CheckForUnblocking()
{

	int isReadyEmpty = 0;
	if(ready_queue == NULL)
		isReadyEmpty = 1;

	printf("\nStarting Checking of Unblocking");
	int i;
	int flag = 0;
	printQueues(); //getting segmentation fault here, need to check further - only for the last blocked thread.
	printf("CP1");
	if(blocked_queue == NULL)
		return;
	printf("CP2");
	MyThread* trav = blocked_queue;
	MyThread* temp;

		flag = 0;
		for(i=0; i<ARR_SIZE; i++)
		{
			if(trav->blockedFor[i] == 0)
				break;
			if(presentInReadyQueue(trav->blockedFor[i]))
			{
				flag = 1;
				printf("\nFlagged 1");
				break;
			}
			if(presentInSemaphoreBlockedQueue(trav->blockedFor[i]))
			{
				//printQueues();
				flag = 1;
				printf("\nFlagged 1");
				//printQueues();

				break;
			}	
		}
		printf("CP3");
		if(flag == 0)
		{
			blocked_queue = blocked_queue->next;
			printf("\n Before inserting to ready queue: %d", trav->id);
			insertIntoReadyQueue(trav);
			if(blocked_queue == NULL)
			{
				printf("\nUnblocking Last Node at Head: %d", trav->id);
				if(isReadyEmpty == 1)
				{
					printf("Yayy! it works!");
					setcontext(&ready_queue->context);
				}
				return;			
			}			
		}

	
		
	MyThread* prev = blocked_queue;
	trav = blocked_queue;
	while(trav != NULL)
	{
		flag = 0;
		for(i=0; i<ARR_SIZE; i++)
		{
			if(trav->blockedFor[i] == 0)
				break;
			if(presentInReadyQueue(trav->blockedFor[i]))
			{
				flag = 1;
				break;
			}	
			if(presentInSemaphoreBlockedQueue(trav->blockedFor[i]))
			{
				//printQueues();
				flag = 1;
				printf("\nFlagged 1");
				//printQueues();

				break;
			}
		}
		if(flag == 0)
		{
			//printf("Before Inserting - id: %d", trav->id);
			temp = trav;
			if(prev == trav)
			{
				blocked_queue = blocked_queue->next;
				prev = blocked_queue;
				trav = blocked_queue;
			}
			else
			{
				trav = trav->next;
			}
			trav->next = trav->next->next;
			insertIntoReadyQueue(temp);
			//printf("Inserted Node");
			//printf("\nUnblocking Node: %d", temp->id);
			
		}
		else
		{
			prev = trav;
			trav = trav->next;
		}
			
	}

	if(isReadyEmpty == 1)
	{
		printf("Yayy! it works!");
		setcontext(&ready_queue->context);
	}
	
}
Пример #6
0
/*
 * Simulates a multilevel feedback queue cpu scheduling algorithm
 * TODO Update the file parsing to be smarter and provide documentation
 */
int main(int argc, char** argv) {
    const int FIELD_LENGTH = 1024; //Default string allocation
    char line[FIELD_LENGTH]; //Buffer for line reading of master file
    char* sub_out; //Output of substring checks for certain fields
    int read_T1 = 0; //0 if T1 hasnt been read yet
    int read_T2 = 0; //0 if T2 hasnt been read yet
    int T1, T2; //Time Quantums
    int processCount = 0; //Number of processes read from the file
    int processCompleted = 0; //Counter for number of process completed
    Queue* futureProcesses = new_queue(0); //Queue of all the processes that havent technically been submitted yet
    Queue* completed = new_queue(-1); //Queue of all completed processes, for output of averaging at the end

    int i;
    //Open the file passed in as the only argument to the program
    FILE* master_file = fopen(argv[1], "rt");
    if (master_file == 0) {
        fprintf(stderr, "Failed to open %s\n", argv[1]);
        exit(1);
    }

    //Open output file for logging functions of the simulator
    FILE* out_file = fopen("cpu_output.txt", "w");
    fprintf(out_file, "############################################################\n");
    fprintf(out_file, "Logging for Multi-Level Queue Scheduling Simulation Started!\n");
    fprintf(out_file, "############################################################\n\n");

    //Read in the file and create necessary process objects
    if (master_file != NULL) {
        //Read line by line to get T1 and T2
        while (fgets(line, FIELD_LENGTH, master_file) != NULL) {
            if (strcmp(line, "\n") == 0) {
                //SKIP NEW LINES IN THE FILE
            } else {
                //Change the line to all lowercase
                array_to_lower(line);

                //Read in TQ#1 and TQ#2
                if (!read_T1) {
                    sub_out = strstr(line, "time quantum 1:");
                    if (sub_out != NULL) {
                        read_T1 = 1;
                        T1 = get_num(sub_out);
                    }
                } else if (!read_T2) {
                    sub_out = strstr(line, "time quantum 2:");
                    if (sub_out != NULL) {
                        read_T2 = 1;
                        T2 = get_num(sub_out);
                        break;
                    }
                }
            }
        }
        //Initialize a CPU
        CPU* cpu = new_cpu(T1, T2);

        //Read in the rest of the file and create all processes and their associated bursts
        while (fgets(line, FIELD_LENGTH, master_file) != NULL) {
            if (strcmp(line, "\n") == 0) {
                //SKIP NEW LINES IN THE FILE
            } else {
                //Change the line to all lowercase
                array_to_lower(line);
                Process* end = get_end(futureProcesses);

                //Get the process id and create a new process for it
                sub_out = strstr(line, "process id:");
                if (sub_out != NULL) {
                    int id = get_num(sub_out);
                    Process* process = new_process(id);
                    if (end != NULL) {
                        end->next = process;
                    } else {
                        futureProcesses->processes = process;
                    }
                    processCount++;
                }

                //Get the arrival time of the most recently created process
                sub_out = strstr(line, "arrival time:");
                if (sub_out != NULL) {
                    int arrival = get_num(sub_out);
                    end->arrival_time = arrival;
                }

                //Create a cpu burst of the recently created process
                sub_out = strstr(line, "cpu burst:");
                if (sub_out != NULL) {
                    int length = get_num(sub_out);
                    Burst* cpu_burst = new_cpu_burst(length);
                    Burst* burst_end = get_last_burst(end);
                    if (burst_end != NULL) {
                        burst_end->next_burst = cpu_burst;
                    } else {
                        end->bursts = cpu_burst;
                    }
                }

                //Create a i/o burst for the recently created process
                sub_out = strstr(line, "i/o burst:");
                if (sub_out != NULL) {
                    int length = get_num(sub_out);
                    Burst* io_burst = new_io_burst(length);
                    Burst* burst_end = get_last_burst(end);
                    if (burst_end != NULL) {
                        burst_end->next_burst = io_burst;
                    } else {
                        end->bursts = io_burst;
                    }
                }

                //Set the device id for the recently created i/o burst
                sub_out = strstr(line, "i/o device id:");
                if (sub_out != NULL) {
                    int id = get_num(sub_out);
                    Burst* burst_end = get_last_burst(end);
                    if (burst_end != NULL) {
                        burst_end->device_num = id;
                    } else {
                        end->bursts->device_num = id;
                    }
                }
            }
        }
        fclose(master_file);

        //Handle if no processes are read in
        if (processCount == 0) {
            fclose(out_file);
            fprintf(stderr, "Zero processes were read in.\nThis could be correct or an error in the format of the input file.\nPlease verify that the input file is formatted correctly. \n");
            exit(1);
        }

        //Run the simulation of the cpu until all processes have been completed
        while (processCompleted < processCount) {

            //Go through the list of processes that havent arrived yet
            Process* tempProc = futureProcesses->processes;
            Process* lastTemp = NULL;
            while (tempProc != NULL) {
                if (tempProc->arrival_time == cpu->time) {
                    //Create a copy of the process to move to the cpu
                    Process* moved = copy_process(tempProc);
                    fprintf(out_file, "Time: %-5d\tProcess#%d Arrived\n", cpu->time, moved->id);

                    if (moved->bursts->type == 1) { //Initial burst is cpu
                        printf("NEW PROCESS CPU FIRST\n");
                        fprintf(out_file, "Time: %-5d\tInitial burst of Process#%d is a CPU burst\n", cpu->time, moved->id);
                        if (cpu->idle == 1) { //If nothing is running on the cpu
                            fprintf(out_file, "Time: %-5d\tCPU was found to be idle, running process on CPU\n", cpu->time);
                            moved->state = 1;
                            cpu->current_process = moved;
                            cpu->idle = 0;
                            cpu->queue = 1;
                            printQueues(out_file, cpu);
                        } else { //If cpu is occupied put new process in Q1
                            fprintf(out_file, "Time: %-5d\tCPU was found to be busy, putting process in Q1\n", cpu->time);
                            Process* end = get_end(cpu->Q1);
                            moved->state = 2;
                            if (end != NULL) { //If Stuff is already in Q1
                                end->next = moved;
                            } else { //If nothing is in Q1
                                cpu->Q1->processes = moved;
                                cpu->Q1->isEmpty = 0;
                            }
                            printQueues(out_file, cpu);
                        }
                    } else { //Initial burst is I/O
                        printf("NEW PROCESS I/O FIRST\n");
                        Burst* i_burst = moved->bursts;
                        int device = i_burst->device_num;
                        IODevice* devQ;
                        switch (device) {
                            case 1: //Next burst is on D1
                                devQ = cpu->D1;
                                break;
                            case 2: //Next burst is on D2
                                devQ = cpu->D2;
                                break;
                            case 3: //Next burst is on D3
                                devQ = cpu->D3;
                                break;
                            case 4: //Next burst is on D4
                                devQ = cpu->D4;
                                break;
                            case 5: //Next burst is on D5
                                devQ = cpu->D5;
                                break;
                        }
                        //Move the process to the correct i/o device
                        fprintf(out_file, "Time: %-5d\tInitial burst of Process#%d is a I/O burst on device %d\n", cpu->time, cpu->current_process->id, devQ->id);
                        Process* io_end = get_io_proc_end(devQ);
                        if (io_end != NULL) {
                            io_end->next = moved;
                        } else {
                            fprintf(out_file, "Time: %-5d\tProcess#%d running on I/O Device Queue %d\n", cpu->time, cpu->current_process->id, devQ->id);
                            devQ->processes = moved;
                        }
                        printQueues(out_file, cpu);
                    }

                    //Remove the process from futureProcesses
                    if (lastTemp != NULL) { //This wasnt the first 
                        lastTemp->next = tempProc->next;
                        tempProc = lastTemp->next;
                    } else { //Process was the first or only in future list
                        futureProcesses->processes = tempProc->next;
                        tempProc = futureProcesses->processes;
                    }
                } else { //Times not equal get next process in list
                    lastTemp = tempProc;
                    tempProc = tempProc->next;
                }
            }

            //Increment running process time on cpu and decrement its remaining time
            //If remaining time is 0, if last burst move process to completed otherwise move it to correct i/o queue
            if (cpu->idle == 0) {
                printf("CPU NOT IDLE\n");
                Burst* burst = get_next_incomplete_burst(cpu->current_process);
                if (burst != NULL) {
                    printf("NEXT BURST IS NOT NULL\n");
                    burst->time_active++;
                    burst->time_remaining--;
                    if (burst->time_remaining == 0) { //Burst is complete
                        printf("BURST COMPLETE\n");
                        burst->completed = 1;
                        fprintf(out_file, "Time: %-5d\tCPU burst of Process#%d completed\n", cpu->time, cpu->current_process->id);
                        if (burst->next_burst != NULL) {
                            printf("MORE BURSTS\n");
                            int device = burst->next_burst->device_num;
                            IODevice* devQ;
                            switch (device) {
                                case 1: //Next burst is on D1
                                    devQ = cpu->D1;
                                    break;
                                case 2: //Next burst is on D2
                                    devQ = cpu->D2;
                                    break;
                                case 3: //Next burst is on D3
                                    devQ = cpu->D3;
                                    break;
                                case 4: //Next burst is on D4
                                    devQ = cpu->D4;
                                    break;
                                case 5: //Next burst is on D5
                                    devQ = cpu->D5;
                                    break;
                            }
                            //Move the process to the correct i/o device
                            fprintf(out_file, "Time: %-5d\tProcess#%d moved to I/O Device Queue %d\n", cpu->time, cpu->current_process->id, devQ->id);
                            Process* io_end = get_io_proc_end(devQ);
                            cpu->current_process->next = NULL;
                            if (io_end != NULL) {
                                io_end->next = cpu->current_process;
                            } else {
                                fprintf(out_file, "Time: %-5d\tProcess#%d running on I/O Device Queue %d\n", cpu->time, cpu->current_process->id, devQ->id);
                                devQ->processes = cpu->current_process;
                            }
                        } else {
                            printf("PROCESS COMPLETE\n");
                            cpu->current_process->state = 0;
                            fprintf(out_file, "Time: %-5d\tProcess#%d completed. Time waiting for CPU: %d Time waiting for I/O: %d Total completion time: %d\n", cpu->time, cpu->current_process->id, cpu->current_process->waiting_cpu, cpu->current_process->waiting_io, (cpu->time - cpu->current_process->arrival_time));
                            cpu->current_process->completion_t = cpu->time;
                            processCompleted++;
                            Process* end = get_end(completed);
                            if (end != NULL) { //If there are already processes in completed
                                end->next = cpu->current_process;
                            } else { //If this is the first process in completed
                                completed->processes = cpu->current_process;
                            }
                        }
                        //Cpu is empty
                        cpu->current_process = NULL;
                        cpu->idle = 1;
                        cpu->queue = 0;
                        printQueues(out_file, cpu);
                    }
                }
            }


            //Increase cpu wait time for all processes in all 3 queues
            Process* pq1 = get_end(cpu->Q1);
            while (pq1 != NULL) {
                printf("INCREMENTING Q1 WAIT TIMES\n");
                pq1->waiting_cpu++;
                pq1 = pq1->next;
            }
            Process* q2 = get_end(cpu->Q2);
            while (q2 != NULL) {
                printf("INCREMENTING Q2 WAIT TIMES\n");
                q2->waiting_cpu++;
                q2 = q2->next;
            }
            Process* pq3 = get_end(cpu->Q3);
            while (pq3 != NULL) {
                printf("INCREMENTING Q3 WAIT TIMES\n");
                pq3->waiting_cpu++;
                pq3 = pq3->next;
            }

            //For the first process in each device queue decrement time remaining
            //If remaining time is 0, if last burst move process to completed otherwise move it to Q1
            //Increment waiting time of process moved to front of device queue
            Process* pd1 = cpu->D1->processes;
            Process* pd2 = cpu->D2->processes;
            Process* pd3 = cpu->D3->processes;
            Process* pd4 = cpu->D4->processes;
            Process* pd5 = cpu->D5->processes;

            if (pd1 != NULL) { //Handle running process in device 1
                printf("PROCESS IN D1\n");
                Burst* bd1 = get_next_incomplete_burst(pd1);
                if (bd1 != NULL) {
                    printf("D1 PROCESS BURST EXISTS\n");
                    bd1->time_remaining--;
                    if (bd1->time_remaining == 0) {
                        printf("BURST IN D1 FINISHED\n");
                        bd1->completed = 1;
                        fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d completed on device %d\n", cpu->time, pd1->id, bd1->device_num);
                        cpu->D1->processes = pd1->next;
                        if (cpu->D1->processes != NULL) {
                            cpu->D1->processes->waiting_io++;
                            fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d running on device %d\n", cpu->time, pd1->next->id, bd1->device_num);
                        }
                        if (bd1->next_burst != NULL) {
                            printf("MOVING PROCESS FROM D1 to Q1\n");
                            Process* end_q = get_end(cpu->Q1);
                            fprintf(out_file, "Time: %-5d\tMoving Process#%d to Q1\n", cpu->time, pd1->id);
                            pd1->next = NULL;
                            if (end_q != NULL) {
                                end_q->next = pd1;
                            } else {
                                cpu->Q1->processes = pd1;
                                cpu->Q1->isEmpty = 0;
                            }
                            printQueues(out_file, cpu);
                        } else {
                            printf("PROCESS COMPLETED IN D1\n");
                            pd1->state = 0;
                            Process* end_completed = get_end(completed);
                            processCompleted++;
                            pd1->completion_t = cpu->time;
                            fprintf(out_file, "Time: %-5d\tProcess#%d completed. Time waiting for CPU: %d Time waiting for I/O: %d Total completion time: %d\n", cpu->time, pd1->id, pd1->waiting_cpu, pd1->waiting_io, (cpu->time - pd1->arrival_time));
                            if (end_completed != NULL) {
                                end_completed->next = pd1;
                            } else {
                                completed->processes = pd1;
                                completed->isEmpty = 0;
                            }
                            printQueues(out_file, cpu);
                        }
                    }
                }
            }
            if (pd2 != NULL) { //Handle running process in device 2
                printf("PROCESS IN D2\n");
                Burst* bd2 = get_next_incomplete_burst(pd2);
                if (bd2 != NULL) {
                    printf("D2 PROCESS BURST EXISTS\n");
                    bd2->time_remaining--;
                    if (bd2->time_remaining == 0) {
                        printf("BURST IN D2 FINISHED\n");
                        bd2->completed = 1;
                        fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d completed on device %d\n", cpu->time, pd2->id, bd2->device_num);
                        cpu->D2->processes = pd2->next;
                        if (cpu->D1->processes != NULL) {
                            cpu->D2->processes->waiting_io++;
                            fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d running on device %d\n", cpu->time, pd2->next->id, bd2->device_num);
                        }
                        if (bd2->next_burst != NULL) {
                            printf("MOVING PROCESS FROM D2 to Q1\n");
                            Process* end_q = get_end(cpu->Q1);
                            fprintf(out_file, "Time: %-5d\tMoving Process#%d to Q1\n", cpu->time, pd2->id);
                            pd2->next = NULL;
                            if (end_q != NULL) {
                                end_q->next = pd2;
                            } else {
                                cpu->Q1->processes = pd2;
                                cpu->Q1->isEmpty = 0;
                            }
                            printQueues(out_file, cpu);
                        } else {
                            printf("PROCESS COMPLETED IN D2\n");
                            pd2->state = 0;
                            Process* end_completed = get_end(completed);
                            processCompleted++;
                            pd2->completion_t = cpu->time;
                            fprintf(out_file, "Time: %-5d\tProcess#%d completed. Time waiting for CPU: %d Time waiting for I/O: %d Total completion time: %d\n", cpu->time, pd2->id, pd2->waiting_cpu, pd2->waiting_io, (cpu->time - pd2->arrival_time));
                            if (end_completed != NULL) {
                                end_completed->next = pd2;
                            } else {
                                completed->processes = pd2;
                                completed->isEmpty = 0;
                            }
                            printQueues(out_file, cpu);
                        }
                    }
                }
            }
            if (pd3 != NULL) { //Handle running process in device 3
                printf("PROCESS IN D3\n");
                Burst* bd3 = get_next_incomplete_burst(pd3);
                if (bd3 != NULL) {
                    printf("D3 PROCESS BURST EXISTS\n");
                    bd3->time_remaining--;
                    if (bd3->time_remaining == 0) {
                        printf("BURST IN D3 FINISHED\n");
                        bd3->completed = 1;
                        fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d completed on device %d\n", cpu->time, pd3->id, bd3->device_num);
                        cpu->D3->processes = pd3->next;
                        if (cpu->D1->processes != NULL) {
                            cpu->D3->processes->waiting_io++;
                            fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d running on device %d\n", cpu->time, pd3->next->id, bd3->device_num);
                        }
                        if (bd3->next_burst != NULL) {
                            printf("MOVING PROCESS FROM D3 to Q1\n");
                            Process* end_q = get_end(cpu->Q1);
                            fprintf(out_file, "Time: %-5d\tMoving Process#%d to Q1\n", cpu->time, pd3->id);
                            pd3->next = NULL;
                            if (end_q != NULL) {
                                end_q->next = pd3;
                            } else {
                                cpu->Q1->processes = pd3;
                                cpu->Q1->isEmpty = 0;
                            }
                            printQueues(out_file, cpu);
                        } else {
                            printf("PROCESS COMPLETED IN D3\n");
                            pd3->state = 0;
                            Process* end_completed = get_end(completed);
                            processCompleted++;
                            pd3->completion_t = cpu->time;
                            fprintf(out_file, "Time: %-5d\tProcess#%d completed. Time waiting for CPU: %d Time waiting for I/O: %d Total completion time: %d\n", cpu->time, pd3->id, pd3->waiting_cpu, pd3->waiting_io, (cpu->time - pd3->arrival_time));
                            if (end_completed != NULL) {
                                end_completed->next = pd3;
                            } else {
                                completed->processes = pd3;
                                completed->isEmpty = 0;
                            }
                            printQueues(out_file, cpu);
                        }
                    }
                }
            }
            if (pd4 != NULL) {//Handle running process in device 4
                printf("PROCESS IN D4\n");
                Burst* bd4 = get_next_incomplete_burst(pd4);
                if (bd4 != NULL) {
                    printf("D4 PROCESS BURST EXISTS\n");
                    bd4->time_remaining--;
                    if (bd4->time_remaining == 0) {
                        printf("BURST IN D4 FINISHED\n");
                        bd4->completed = 1;
                        fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d completed on device %d\n", cpu->time, pd4->id, bd4->device_num);
                        cpu->D4->processes = pd4->next;
                        if (cpu->D1->processes != NULL) {
                            cpu->D4->processes->waiting_io++;
                            fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d running on device %d\n", cpu->time, pd4->next->id, bd4->device_num);
                        }
                        if (bd4->next_burst != NULL) {
                            printf("MOVING PROCESS FROM D4 to Q1\n");
                            Process* end_q = get_end(cpu->Q1);
                            fprintf(out_file, "Time: %-5d\tMoving Process#%d to Q1\n", cpu->time, pd4->id);
                            pd4->next = NULL;
                            if (end_q != NULL) {
                                end_q->next = pd4;
                            } else {
                                cpu->Q1->processes = pd4;
                                cpu->Q1->isEmpty = 0;
                            }
                            printQueues(out_file, cpu);
                        } else {
                            printf("PROCESS COMPLETED IN D4\n");
                            pd4->state = 0;
                            Process* end_completed = get_end(completed);
                            processCompleted++;
                            pd4->completion_t = cpu->time;
                            fprintf(out_file, "Time: %-5d\tProcess#%d completed. Time waiting for CPU: %d Time waiting for I/O: %d Total completion time: %d\n", cpu->time, pd4->id, pd4->waiting_cpu, pd4->waiting_io, (cpu->time - pd4->arrival_time));
                            if (end_completed != NULL) {
                                end_completed->next = pd4;
                            } else {
                                completed->processes = pd4;
                                completed->isEmpty = 0;
                            }
                            printQueues(out_file, cpu);
                        }
                    }
                }
            }
            if (pd5 != NULL) {//Handle running process in device 5
                printf("PROCESS IN D5\n");
                Burst* bd5 = get_next_incomplete_burst(pd5);
                if (bd5 != NULL) {
                    printf("D5 PROCESS BURST EXISTS\n");
                    bd5->time_remaining--;
                    if (bd5->time_remaining == 0) {
                        printf("BURST IN D5 FINISHED\n");
                        bd5->completed = 1;
                        fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d completed on device %d\n", cpu->time, pd5->id, bd5->device_num);
                        cpu->D5->processes = pd5->next;
                        if (cpu->D1->processes != NULL) {
                            cpu->D5->processes->waiting_io++;
                            fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d running on device %d\n", cpu->time, pd5->next->id, bd5->device_num);
                        }
                        if (bd5->next_burst != NULL) {
                            printf("MOVING PROCESS FROM D5 to Q1\n");
                            Process* end_q = get_end(cpu->Q1);
                            fprintf(out_file, "Time: %-5d\tMoving Process#%d to Q1\n", cpu->time, pd5->id);
                            pd5->next = NULL;
                            if (end_q != NULL) {
                                end_q->next = pd5;
                            } else {
                                cpu->Q1->processes = pd5;
                                cpu->Q1->isEmpty = 0;
                            }
                            printQueues(out_file, cpu);
                        } else {
                            printf("PROCESS COMPLETED IN D5\n");
                            pd5->state = 0;
                            Process* end_completed = get_end(completed);
                            processCompleted++;
                            pd5->completion_t = cpu->time;
                            fprintf(out_file, "Time: %-5d\tProcess#%d completed. Time waiting for CPU: %d Time waiting for I/O: %d Total completion time: %d\n", cpu->time, pd5->id, pd5->waiting_cpu, pd5->waiting_io, (cpu->time - pd5->arrival_time));
                            if (end_completed != NULL) {
                                end_completed->next = pd5;
                            } else {
                                completed->processes = pd5;
                                completed->isEmpty = 0;
                            }
                            printQueues(out_file, cpu);
                        }
                    }
                }
            }

            //Increment the io waiting time for all processes in device queues after the first process in each
            pd1 = cpu->D1->processes;
            pd2 = cpu->D2->processes;
            pd3 = cpu->D3->processes;
            pd4 = cpu->D4->processes;
            pd5 = cpu->D5->processes;
            if (pd1 != NULL) { //Handle device 1
                pd1 = pd1->next;
                while (pd1 != NULL) {
                    printf("Incrementing device 1 waiting\n");
                    pd1->waiting_io++;
                    pd1 = pd1->next;
                }
            }
            if (pd2 != NULL) { //Handle device 2
                pd2 = pd2->next;
                while (pd2 != NULL) {
                    printf("Incrementing device 2 waiting\n");
                    pd2->waiting_io++;
                    pd2 = pd2->next;
                }
            }
            if (pd3 != NULL) { //Handle device 3
                pd3 = pd3->next;
                while (pd3 != NULL) {
                    printf("Incrementing device 3 waiting\n");
                    pd3->waiting_io++;
                    pd3 = pd3->next;
                }
            }
            if (pd4 != NULL) { //Handle device 4
                pd4 = pd4->next;
                while (pd4 != NULL) {
                    printf("Incrementing device 4 waiting\n");
                    pd4->waiting_io++;
                    pd4 = pd4->next;
                }
            }
            if (pd5 != NULL) { //Handle device 5
                pd5 = pd5->next;
                while (pd5 != NULL) {
                    printf("Incrementing device 5 waiting\n");
                    pd5->waiting_io++;
                    pd5 = pd5->next;
                }
            }

            //If cpu is running in Q3
            //Check for other processes with shorter remaining times
            //If there is one move running process to end of Q3
            //Check if Q1 and Q2 are empty, if either isnt free up the cpu and put the running process back into Q3 
            if (cpu->queue == 3 && cpu->current_process != NULL) {
                printf("CPU is in Q3\n");
                if (cpu->Q1->processes != NULL || cpu->Q2->processes != NULL || shortest(cpu->current_process, cpu->Q3) == 0) {
                    printf("PROCESS IN Q3 IS BEING PREEMTED\n");
                    Process* end_que = get_end(cpu->Q3);
                    cpu->current_process->state = 2;
                    fprintf(out_file, "Time: %-5d\tProcess#%d has been moved back into Q3 due to there being a shorter process in Q3 to run or there are processes in Q2 or Q1 that need to be run\n", cpu->time, cpu->current_process->id);

                    if (end_que != NULL) {
                        end_que->next = cpu->current_process;
                    } else {
                        cpu->Q3->processes = cpu->current_process;
                        cpu->Q3->isEmpty = 0;
                    }
                    
                    cpu->current_process = NULL;
                    cpu->idle = 1;
                    cpu->queue = 0;
                    printQueues(out_file, cpu);
                } else {
                    printf("NOTHING IN Q3 PREMTED\n");
                }
            }

            //If cpu is running in Q2
            //If the current process time on cpu > TQ2
            //Move process to Q3 and set cpu to idle
            //If Q1 isnt empty move running process back into Q2, but dont reset its time on the cpu
            if (cpu->queue == 2) {
                printf("CPU is in Q2\n");
                if (get_next_incomplete_burst(cpu->current_process) != NULL && get_next_incomplete_burst(cpu->current_process)->time_active > cpu->TQ2) {
                    //Time ran out for the process move it to Q3
                    printf("TIME RAN OUT FOR PROCESS IN Q2\n");
                    fprintf(out_file, "Time: %-5d\tProcess#%d moved to Q3 for not being able to complete within the Time Quantum of Q2\n", cpu->time, cpu->current_process->id);
                    Process* end_q3 = get_end(cpu->Q3);
                    cpu->current_process->state = 2;
                    if (end_q3 != NULL) {
                        end_q3->next = cpu->current_process;
                    } else {
                        cpu->Q3->processes = cpu->current_process;
                        cpu->Q3->isEmpty = 0;
                    }
                    
                    cpu->current_process = NULL;
                    cpu->idle = 1;
                    cpu->queue = 0;
                    printQueues(out_file, cpu);
                } else if (cpu->Q1->isEmpty == 0) {
                    //Preempt the process since there are processes in Q1
                    printf("PREMETING PROCESS IN Q2 FOR ONE IN Q1\n");
                    fprintf(out_file, "Time: %-5d\tProcess#%d moved back into Q2 because there are processes in Q1 that need to be run\n", cpu->time, cpu->current_process->id);
                    Process* end_q2 = get_end(cpu->Q2);
                    cpu->current_process->state = 2;
                    if (end_q2 != NULL) {
                        end_q2->next = cpu->current_process;
                    } else {
                        cpu->Q2->processes = cpu->current_process;
                        cpu->Q2->isEmpty = 0;
                    }
                    
                    cpu->current_process = NULL;
                    cpu->idle = 1;
                    cpu->queue = 0;
                    printQueues(out_file, cpu);
                } else {
                    printf("NOTHING MOVED OFF CPU FROM Q2\n");
                }
            }

            //If the cpu is running in Q1
            //If the current process time on cpu > TQ1
            //Move the process to Q2 and set cpu to idle
            if (cpu->queue == 1) {
                printf("CPU is in Q1\n");
                if (get_next_incomplete_burst(cpu->current_process) != NULL && get_next_incomplete_burst(cpu->current_process)->time_active > cpu->TQ1) {
                    //Time ran out for the process move it to Q2
                    printf("TIME RAN OUT FOR PROCESS IN Q1\n");
                    fprintf(out_file, "Time: %-5d\tProcess#%d moved to Q2 because it could not complete within the Time Quantum of Q1\n", cpu->time, cpu->current_process->id);
                    Process* end_q2 = get_end(cpu->Q2);
                    get_next_incomplete_burst(cpu->current_process)->time_active = 0;
                    cpu->current_process->state = 2;
                    if (end_q2 != NULL) {
                        end_q2->next = cpu->current_process;
                    } else {
                        cpu->Q2->processes = cpu->current_process;
                        cpu->Q2->isEmpty = 0;
                    }
                    
                    cpu->current_process = NULL;
                    cpu->idle = 1;
                    cpu->queue = 0;
                    printQueues(out_file, cpu);
                } else {
                    printf("NOTHING REMOVED FOR TIME FROM Q1\n");
                }
            }

            //If Q1 has stuff in it and the cpu is free
            //Put the first thing from Q1 onto the cpu
            if (cpu->Q1->processes != NULL && cpu->idle == 1) {
                printf("Q1 not empty and CPU idle\n");
                Process* q1_popped = cpu->Q1->processes;
                fprintf(out_file, "Time: %-5d\tMoving Process#%d from Q1 onto the CPU\n", cpu->time, q1_popped->id);
                cpu->Q1->processes = q1_popped->next;
                q1_popped->next = NULL;
                if (cpu->Q1->processes == NULL) {
                    cpu->Q1->isEmpty = 1;
                }
                cpu->current_process = q1_popped;
                cpu->queue = 1;
                cpu->idle = 0;
                q1_popped->state = 1;
                printQueues(out_file, cpu);
            }//Else If Q2 has stuff in it and the cpu is free
                //Put the first thing from Q2 onto the cpu
            else if (cpu->Q2->processes != NULL && cpu->idle == 1) {
                printf("Q2 not empty and CPU idle\n");
                Process* q2_popped = cpu->Q2->processes;
                fprintf(out_file, "Time: %-5d\tMoving Process#%d from Q2 onto the CPU\n", cpu->time, q2_popped->id);
                cpu->Q2->processes = q2_popped->next;
                q2_popped->next = NULL;
                if (cpu->Q2->processes == NULL) {
                    cpu->Q2->isEmpty = 1;
                }
                cpu->current_process = q2_popped;
                cpu->queue = 2;
                cpu->idle = 0;
                q2_popped->state = 1;
                printQueues(out_file, cpu);
            }//Else If Q3 has stuff in it and the cpu is free
                //Put the lowest time remaining onto the cpu
            else if (cpu->Q3->processes != NULL && cpu->idle == 1) {
                printf("Q3 not empty and CPU idle\n");
                //FIX THIS
                //Process* shortest = get_shortest_remaining(cpu->Q3);
                Process* shortest = cpu->Q3->processes;
                cpu->Q3->processes = shortest->next;
                fprintf(out_file, "Time: %-5d\tMoving Process#%d from Q3 onto the CPU\n", cpu->time, shortest->id);
                cpu->current_process = shortest;
                cpu->queue = 3;
                cpu->idle = 0;
                shortest->state = 1;
                if (cpu->Q3->processes == NULL) {
                    cpu->Q3->isEmpty = 1;
                }
                printQueues(out_file, cpu);
            }

            cpu->time++;
            printf("TIME: %d\n", cpu->time);
        }

        //Write final average data to the output file
        //Average waiting time
        //Average turnaround time
        int waiting_sum = 0;
        int total_sum = 0;
        Process* itr = completed->processes;
        while (itr != NULL) {
            waiting_sum += itr->waiting_cpu;
            total_sum += (itr->completion_t - itr->arrival_time);
            itr = itr->next;
        }
        fprintf(out_file, "\n\nAverage waiting time: %d\nAverage turnaround time: %d\n", waiting_sum / processCompleted, total_sum / processCompleted);

        fprintf(out_file, "\n\n############################################################\n");
        fprintf(out_file, "Logging for Multi-Level Queue Scheduling Simulation Ended!\n");
        fprintf(out_file, "############################################################\n");
        fclose(out_file);
    }
    return (EXIT_SUCCESS);
}
Пример #7
0
int main(int argc, char *argv[])
{
    char word[20]; //primul cuvant de pe fiecare linie din fisierul de intrare
    FILE *f = fopen(argv[1], "r");

    int N;
    fscanf(f, "%d\n", &N);

    struct window *windows = new struct window[N]; //vector de ghisee
    Queue<person> *q = new Queue<person>[N]; //vector de cozii
    Stack<int> *s = new Stack<int>[N]; //vector de stive
    struct array arrayWindows; //retine cate ghisee au fost deschise si ID-urile
    arrayWindows.nrWindows = 0;
    arrayWindows.A = new int[N];

    //citirea si interpretarea fisierului de input
    while(fscanf(f, "%s", word) == 1)
    {
        if(strcmp(word, "OPEN_WINDOW") == 0)
        {
            int window_id, weight_min, weight_max, q_, k;
            fscanf(f, "%d%d%d%d%d", &window_id, &weight_min, &weight_max, &q_, &k);
            open_window(windows, &arrayWindows, q, s, window_id, weight_min,
                        weight_max, q_, k);
        }

        else if(strcmp(word, "ADD_PERSON") == 0)
        {
            int personal_id, package_weight, window_id;
            fscanf(f, "%d%d%d", &personal_id, &package_weight, &window_id);
            add_person(q, personal_id, package_weight, window_id);
        }

        else if(strcmp(word, "PROCESS") == 0)
        {
            int window_id, n_people;
            fscanf(f, "%d%d", &window_id, &n_people);
            process(windows, arrayWindows, q, s, window_id, n_people);
        }

        else if(strcmp(word, "PROCESS_ALL") == 0)
        {
            int window_id;
            fscanf(f, "%d", &window_id);
            processAll(windows, arrayWindows, q, s, window_id);
        }

        else if(strcmp(word, "PRINT_QUEUES") == 0)
            printQueues(q, arrayWindows);

        else if(strcmp(word, "PRINT_STACKS") == 0)
            printStacks(s, arrayWindows);

        else if(strcmp(word, "FLUSH_STACKS") == 0)
            flushStacks(s, arrayWindows);
    }

    fclose(f);

    return 0;
}