Process Scheduling Algorithms (FCFS, SJF, RR, PSA)

#pragma warning (disable : 4996)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#define NameLength 4
#define ProcessNumberLimit 8
#define TimeLimit 16
#define PriorityLimit 8

enum statusType {
	Arrival = 0, Wait, Run, Finish
};

typedef struct process {
	char name[NameLength];
	enum statusType status;
	int arrivalTime;
	int needTime;
	int burstTime;
	int startTime;
	int endTime;
	int priority;
	int round;
}PCB;

typedef struct {
	PCB data[ProcessNumberLimit];
	int first;
	int last;
}list;

char algorithmType = '0';
int processNumber = 0;
list arrivalList;
list waitList;
list finishList;
int Round = 0;

void selectAlgorithm();
void initialList();
void createProcess();
void createTypeFAndS();
void createTypeR();
void createTypeP();
void insertInArrivalList(PCB p);
void sortArrivalListToAscending();
void titleTypeFAndS();
void showTypeFAndS(PCB pi);
void titleTypeR();
void showTypeR(PCB pi);
void titleTypeP();
void showTypeP(PCB pi);
int scheduleIsFinish();
void schedule();
void scheduleTypeF(int* time);
void scheduleTypeS(int* time);
void scheduleTypeR(int* time);
void scheduleTypeP(int* time);
void insertInWaitList(int time);
void insertInFinishList(PCB p);
void displayCurrentCondition(int time);
void firstWaitInSJF();
void firstWaitInPSA();

int main() {
	selectAlgorithm();
	initialList();
	createProcess();
	schedule();
	return 0;
}

void selectAlgorithm() {
	do {
		printf("The character 'f' represents FCFS, 's' represents SJF, 'r' represents RR and 'p' represents PSA.\n");
		printf("Input the character which represents the algorithm you want to select: ");
		scanf("%c", &algorithmType);
		char temp;
		while ('\n' != (temp = getchar()) && EOF != temp);//Replace fflush(stdin) with this because GCC does not support the former;
	} while ('f' != algorithmType && 's' != algorithmType && 'r' != algorithmType && 'p' != algorithmType);
	printf("The algorithm you select is ");
	switch (algorithmType) {
	case 'f': {
		printf("FCFS.\n");
		break;
	}
	case 's': {
		printf("SJF.\n");
		break;
	}
	case 'r': {
		printf("RR.\n");
		break;
	}
	case 'p': {
		printf("PSA.\n");
		break;
	}
	default: {
		exit(-1);
		break;
	}
	}
	return;
}

void initialList() {
	arrivalList.first = 0;
	arrivalList.last = 0;
	waitList.first = 0;
	waitList.last = 0;
	finishList.first = 0;
	finishList.last = 0;
	return;
}

void createProcess() {
	do {
		printf("Input the number of process (from 1 to %d) : ", ProcessNumberLimit);
		scanf("%d", &processNumber);
		char temp;
		while ('\n' != (temp = getchar()) && EOF != temp);//Replace fflush(stdin) with this because GCC does not support the former;
	} while (processNumber < 1 || processNumber > ProcessNumberLimit);
	printf("The number of process is %d\n", processNumber);
	switch (algorithmType) {
	case 'f': {
		createTypeFAndS();
		printf("Condation at time 0 is:\n");
		titleTypeFAndS();
		for (int i = arrivalList.first; arrivalList.last != i; i = (i + 1) % ProcessNumberLimit) {
			showTypeFAndS(arrivalList.data[i]);
		}
		break;
	}
	case 's': {
		createTypeFAndS();
		printf("Condation at time 0 is:\n");
		titleTypeFAndS();
		for (int i = arrivalList.first; arrivalList.last != i; i = (i + 1) % ProcessNumberLimit) {
			showTypeFAndS(arrivalList.data[i]);
		}
		break;
	}
	case 'r': {
		createTypeR();
		printf("Condation at time 0 is:\n");
		titleTypeR();
		for (int i = arrivalList.first; arrivalList.last != i; i = (i + 1) % ProcessNumberLimit) {
			showTypeR(arrivalList.data[i]);
		}
		break;
	}
	case 'p': {
		createTypeP();
		printf("Condation at time 0 is:\n");
		titleTypeP();
		for (int i = arrivalList.first; arrivalList.last != i; i = (i + 1) % ProcessNumberLimit) {
			showTypeP(arrivalList.data[i]);
		}
		break;
	}
	default: {
		exit(-1);
		break;
	}
	}
	return;
}

void createTypeFAndS() {
	printf("Now create as type FAndS.\n");
	printf("########\n");
	for (int i = 1; i <= processNumber; i++) {
		PCB p;
		printf("Input process name (max length is %d) : ", NameLength);
		scanf("%s", p.name);
		do {
			printf("Input arrival time (from 0 to %d) : ", TimeLimit);
			scanf("%d", &(p.arrivalTime));
		} while (p.arrivalTime < 0 || p.arrivalTime > TimeLimit);
		do {
			printf("Input need time (from 1 to %d) : ", TimeLimit);
			scanf("%d", &(p.needTime));
		} while (p.needTime < 1 || p.needTime > TimeLimit);
		char temp;
		while ('\n' != (temp = getchar()) && EOF != temp);//Replace fflush(stdin) with this because GCC does not support the former;
		printf("########\n");
		p.burstTime = 0;
		p.startTime = 0;
		p.endTime = 0;
		insertInArrivalList(p);
	}
	sortArrivalListToAscending();
	return;
}

void createTypeR() {
	printf("Now create as type R.\n");
	do {
		printf("Input round (from 1 to %d) : ", TimeLimit / 2);
		scanf("%d", &Round);
	} while (Round < 1 || Round > TimeLimit / 2);
	printf("OK, round will be %d.\n", Round);
	printf("########\n");
	for (int i = 1; i <= processNumber; i++) {
		PCB p;
		printf("Input process name (max length is %d) : ", NameLength);
		scanf("%s", p.name);
		do {
			printf("Input arrival time (from 0 to %d) : ", TimeLimit);
			scanf("%d", &(p.arrivalTime));
		} while (p.arrivalTime < 0 || p.arrivalTime > TimeLimit);
		do {
			printf("Input need time (from 1 to %d) : ", TimeLimit);
			scanf("%d", &(p.needTime));
		} while (p.needTime < 1 || p.needTime > TimeLimit);
		char temp;
		while ('\n' != (temp = getchar()) && EOF != temp);//Replace fflush(stdin) with this because GCC does not support the former;
		printf("########\n");
		p.burstTime = 0;
		p.startTime = 0;
		p.endTime = 0;
		p.round = Round;
		insertInArrivalList(p);
	}
	sortArrivalListToAscending();
	return;
}

void createTypeP() {
	printf("Now create as type P.\n");
	printf("########\n");
	for (int i = 1; i <= processNumber; i++) {
		PCB p;
		printf("Input process name (max length is %d) : ", NameLength);
		scanf("%s", p.name);
		do {
			printf("Input arrival time (from 0 to %d) : ", TimeLimit);
			scanf("%d", &(p.arrivalTime));
		} while (p.arrivalTime < 0 || p.arrivalTime > TimeLimit);
		do {
			printf("Input need time (from 1 to %d) : ", TimeLimit);
			scanf("%d", &(p.needTime));
		} while (p.needTime < 1 || p.needTime > TimeLimit);
		do {
			printf("Input the priority (from 0 to %d) : ", PriorityLimit);
			scanf("%d", &(p.priority));
		} while (p.priority < 0 || p.priority > PriorityLimit);
		char temp;
		while ('\n' != (temp = getchar()) && EOF != temp);//Replace fflush(stdin) with this because GCC does not support the former;
		printf("########\n");
		p.burstTime = 0;
		p.startTime = 0;
		p.endTime = 0;
		insertInArrivalList(p);
	}
	sortArrivalListToAscending();
	return;
}

void insertInArrivalList(PCB p) {
	p.status = Arrival;
	arrivalList.data[arrivalList.last] = p;
	arrivalList.last = (arrivalList.last + 1) % ProcessNumberLimit;
	return;
}

void sortArrivalListToAscending() {
	int latest;
	for (int i = arrivalList.first; arrivalList.last != (i + 1) % ProcessNumberLimit; i = (i + 1) % ProcessNumberLimit) {
		latest = i;
		for (int j = (i + 1) % ProcessNumberLimit; arrivalList.last != j; j = (j + 1) % ProcessNumberLimit) {
			if (arrivalList.data[j].arrivalTime < arrivalList.data[latest].arrivalTime) {
				latest = j;
			}
		}
		if (i != latest) {
			PCB temp = arrivalList.data[i];
			arrivalList.data[i] = arrivalList.data[latest];
			arrivalList.data[latest] = temp;
		}
	}
	return;
}

void titleTypeFAndS() {
	printf("ProcessName\tStatus\t\tArrivalTime\tNeedTime\tBurstTime\tStartTime\tEndTime\n");
	return;
}

void showTypeFAndS(PCB pi) {
	printf("%s\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\n", pi.name, pi.status, pi.arrivalTime, pi.needTime, pi.burstTime, pi.startTime, pi.endTime);
	return;
}

void titleTypeR() {
	printf("ProcessName\tStatus\t\tArrivalTime\tNeedTime\tBurstTime\tStartTime\tEndTime\t\tRound\n");
	return;
}

void showTypeR(PCB pi) {
	printf("%s\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\n", pi.name, pi.status, pi.arrivalTime, pi.needTime, pi.burstTime, pi.startTime, pi.endTime, pi.round);
	return;
}

void titleTypeP() {
	printf("ProcessName\tStatus\t\tArrivalTime\tNeedTime\tBurstTime\tStartTime\tEndTime\t\tPriority\n");
	return;
}

void showTypeP(PCB pi) {
	printf("%s\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\n", pi.name, pi.status, pi.arrivalTime, pi.needTime, pi.burstTime, pi.startTime, pi.endTime, pi.priority);
	return;
}

int scheduleIsFinish() {
	if (processNumber == finishList.last - finishList.first) {//totally in finishList;
		return 1;
	}
	else {
		return 0;
	}
}

void schedule() {
	int time = 0;
	insertInWaitList(time);
	while (0 == scheduleIsFinish()) {
		switch (algorithmType) {
		case 'f': {
			scheduleTypeF(&time);
			break;
		}
		case 's': {
			scheduleTypeS(&time);
			break;
		}
		case 'r': {
			scheduleTypeR(&time);
			break;
		}
		case 'p': {
			scheduleTypeP(&time);
			break;
		}
		default: {
			exit(-1);
			break;
		}
		}
	}
	return;
}

void scheduleTypeF(int* time) {
	printf("Scheduling Algorithm: FCFS.\n");
	if (waitList.last == waitList.first) {//current have nothing in waitList, try next second;
		(*time)++;
	}
	else {
		if (Run != waitList.data[waitList.first].status) {//need to choose a new one to run;
			waitList.data[waitList.first].startTime = (*time);
			waitList.data[waitList.first].status = Run;
		}
		waitList.data[waitList.first].burstTime++;
		(*time)++;
		if (waitList.data[waitList.first].needTime == waitList.data[waitList.first].burstTime) {
			waitList.data[waitList.first].endTime = (*time);
			insertInFinishList(waitList.data[waitList.first]);
			waitList.first = (waitList.first + 1) % ProcessNumberLimit;
		}
	}
	insertInWaitList(*time);
	displayCurrentCondition(*time);
	return;
}

void scheduleTypeS(int* time) {
	printf("Scheduling Algorithm: SJF.\n");
	if (waitList.last == waitList.first) {//current have nothing in waitList, try next second;
		(*time)++;
	}
	else {
		if (Run != waitList.data[waitList.first].status) {//need to choose a new one to run;
			firstWaitInSJF();
			waitList.data[waitList.first].startTime = (*time);
			waitList.data[waitList.first].status = Run;
		}
		waitList.data[waitList.first].burstTime++;
		(*time)++;
		if (waitList.data[waitList.first].needTime == waitList.data[waitList.first].burstTime) {
			waitList.data[waitList.first].endTime = (*time);
			insertInFinishList(waitList.data[waitList.first]);
			waitList.first = (waitList.first + 1) % ProcessNumberLimit;
		}
	}
	insertInWaitList(*time);
	displayCurrentCondition(*time);
	return;
}

void scheduleTypeR(int* time) {
	printf("Scheduling Algorithm: RR.\n");
	if (waitList.last == waitList.first) {//current have nothing in waitList, try next second;
		(*time)++;
	}
	else {//have something;
		if (Run != waitList.data[waitList.first].status) {//first not run;
			if (Round == waitList.data[waitList.first].round) {//first time;
				waitList.data[waitList.first].startTime = (*time);
			}
			else {//not first time;
				waitList.data[waitList.first].round = Round;//initial round;
			}
			waitList.data[waitList.first].status = Run;
		}
		else {//first is run;
			if (0 == waitList.data[waitList.first].round) {
				waitList.data[waitList.first].status = Wait;
				waitList.data[waitList.last] = waitList.data[waitList.first];
				waitList.last = (waitList.last + 1) % ProcessNumberLimit;
				waitList.first = (waitList.first + 1) % ProcessNumberLimit;
				printf("Round is zero, next one.\n");
				return;
			}
		}
		waitList.data[waitList.first].burstTime++;
		waitList.data[waitList.first].round--;
		(*time)++;
		if (waitList.data[waitList.first].needTime == waitList.data[waitList.first].burstTime) {
			waitList.data[waitList.first].round = 0;//finish;
			waitList.data[waitList.first].endTime = (*time);
			insertInFinishList(waitList.data[waitList.first]);
			waitList.first = (waitList.first + 1) % ProcessNumberLimit;
		}
	}
	insertInWaitList(*time);
	displayCurrentCondition(*time);
	return;
}

void scheduleTypeP(int* time) {
	printf("Scheduling Algorithm: PSA.\n");
	if (waitList.last == waitList.first) {//current have nothing in waitList, try next second;
		(*time)++;
	}
	else {
		if (Run != waitList.data[waitList.first].status) {//need to choose a new one to run;
			firstWaitInPSA();
			waitList.data[waitList.first].startTime = (*time);
			waitList.data[waitList.first].status = Run;
		}
		waitList.data[waitList.first].burstTime++;
		(*time)++;
		if (waitList.data[waitList.first].needTime == waitList.data[waitList.first].burstTime) {
			waitList.data[waitList.first].endTime = (*time);
			insertInFinishList(waitList.data[waitList.first]);
			waitList.first = (waitList.first + 1) % ProcessNumberLimit;
		}
	}
	insertInWaitList(*time);
	displayCurrentCondition(*time);
	return;
}

void insertInWaitList(int time) {
	for (int i = arrivalList.first; (arrivalList.data[i].arrivalTime <= time) && (arrivalList.last != i); i = (i + 1) % ProcessNumberLimit) {
		arrivalList.data[i].status = Wait;
		waitList.data[waitList.last] = arrivalList.data[i];
		waitList.last = (waitList.last + 1) % ProcessNumberLimit;
		arrivalList.first = (arrivalList.first + 1) % ProcessNumberLimit;
	}
	return;
}

void insertInFinishList(PCB p) {
	p.status = Finish;
	finishList.data[finishList.last] = p;
	finishList.last = (finishList.last + 1) % ProcessNumberLimit;
	return;
}

void displayCurrentCondition(int time) {
	printf("Now, time is %d.\n", time);
	switch (algorithmType) {
	case 'f': {
		titleTypeFAndS();
		if (arrivalList.last != arrivalList.first) {
			for (int i = arrivalList.first; arrivalList.last != i; i = (i + 1) % ProcessNumberLimit) {
				showTypeFAndS(arrivalList.data[i]);
			}
		}
		if (waitList.last != waitList.first) {
			for (int i = waitList.first; waitList.last != i; i = (i + 1) % ProcessNumberLimit) {
				showTypeFAndS(waitList.data[i]);
			}
		}
		if (finishList.last != finishList.first) {
			for (int i = finishList.first; finishList.last != i; i = (i + 1) % ProcessNumberLimit) {
				showTypeFAndS(finishList.data[i]);
			}
		}
		break;
	}
	case 's': {
		titleTypeFAndS();
		if (arrivalList.last != arrivalList.first) {
			for (int i = arrivalList.first; arrivalList.last != i; i = (i + 1) % ProcessNumberLimit) {
				showTypeFAndS(arrivalList.data[i]);
			}
		}
		if (waitList.last != waitList.first) {
			for (int i = waitList.first; waitList.last != i; i = (i + 1) % ProcessNumberLimit) {
				showTypeFAndS(waitList.data[i]);
			}
		}
		if (finishList.last != finishList.first) {
			for (int i = finishList.first; finishList.last != i; i = (i + 1) % ProcessNumberLimit) {
				showTypeFAndS(finishList.data[i]);
			}
		}
		break;
	}
	case 'r': {
		titleTypeR();
		if (arrivalList.last != arrivalList.first) {
			for (int i = arrivalList.first; arrivalList.last != i; i = (i + 1) % ProcessNumberLimit) {
				showTypeR(arrivalList.data[i]);
			}
		}
		if (waitList.last != waitList.first) {
			for (int i = waitList.first; waitList.last != i; i = (i + 1) % ProcessNumberLimit) {
				showTypeR(waitList.data[i]);
			}
		}
		if (finishList.last != finishList.first) {
			for (int i = finishList.first; finishList.last != i; i = (i + 1) % ProcessNumberLimit) {
				showTypeR(finishList.data[i]);
			}
		}
		break;
	}
	case 'p': {
		titleTypeP();
		if (arrivalList.last != arrivalList.first) {
			for (int i = arrivalList.first; arrivalList.last != i; i = (i + 1) % ProcessNumberLimit) {
				showTypeP(arrivalList.data[i]);
			}
		}
		if (waitList.last != waitList.first) {
			for (int i = waitList.first; waitList.last != i; i = (i + 1) % ProcessNumberLimit) {
				showTypeP(waitList.data[i]);
			}
		}
		if (finishList.last != finishList.first) {
			for (int i = finishList.first; finishList.last != i; i = (i + 1) % ProcessNumberLimit) {
				showTypeP(finishList.data[i]);
			}
		}
		break;
	}
	default: {
		exit(-1);
		break;
	}
	}
	return;
}

void firstWaitInSJF() {
	int index = waitList.first;
	for (int i = waitList.first + 1; waitList.last != i; i = (i + 1) % ProcessNumberLimit) {
		if (waitList.data[index].needTime > waitList.data[i].needTime) {
			index = i;
		}
	}
	if (waitList.first != index) {
		PCB temp = waitList.data[index];
		waitList.data[index] = waitList.data[waitList.first];
		waitList.data[waitList.first] = temp;
	}
	return;
}

void firstWaitInPSA() {
	int index = waitList.first;
	for (int i = waitList.first + 1; waitList.last != i; i = (i + 1) % ProcessNumberLimit) {
		if (waitList.data[index].priority < waitList.data[i].priority) {
			index = i;
		}
	}
	if (waitList.first != index) {
		PCB temp = waitList.data[index];
		waitList.data[index] = waitList.data[waitList.first];
		waitList.data[waitList.first] = temp;
	}
	return;
}

The above is an independent creation completely from the NUC programming god, all rights reserved, and the infringer must be sanctioned by the tiger security.

2022/11/12 20:30 from NUC 11-513, college no.7.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值