/*2024 Fall COSE341 Operating System*/
/*Project 2*/
/*Kim JinHyeong*/
/* If FCFS, use ku_push(int) instead of ku_push_SJF(int, int) in main*/
/* If SJF, use ku_push_SJF(int, int) instead of ku_push(int) in main*/
#include <linux/syscalls.h>
#include <linux/kernel.h>
#include <linux/linkage.h>
#include <linux/sched.h>
#include <linux/slab.h>
# define IDLE -1
typedef struct _job_t {
int pid;
int jobTime;
} job_t;
int now = IDLE;
typedef struct _node{
int pid; // waiting process pid
int jobTime; // remaining jobTime
struct _node * next; // next node
} NODE; // queue elements
typedef struct header {
int num; // number of waiting queue elements
NODE* first; // first element
NODE* last; // last element
} HEADER;
HEADER waiting_header = {0, NULL, NULL};
int ku_pop(void); // dequeue
int check(int x); // check whether x is in waiting_queue
void ku_push(int pid);
void ku_push_SJF(int pid, int jobTime); // enqueue
SYSCALL_DEFINE2(os2024_ku_cpu, char*, name, int, jobTime) {
// store pid of current process as pid_t type
job_t newJob = {current->pid, jobTime};
// register the process if virtual CPU is idle
if (now == IDLE) now = newJob.pid;
// If the process that sent the request is currently using virtual CPU
if (now == newJob.pid) {
// If the job has finished
if (jobTime == 0) {
printk("Process Finished: %s\n", name);
// if queue is empty, virtual CPU becomes idle
if (waiting_header.num == 0) now = IDLE;
// if not, get next process from queue and load
else now = ku_pop();
}
else printk("Working: %s\n", name);
// request accepted
return 0;
}
else {
// if the request is not from currently handling process
// if (check(newJob.pid)) ku_push(newJob.pid); // enqueue pid b
y FCFS if process is not in waiting queue
if (check(newJob.pid)) ku_push_SJF(newJob.pid, jobTime);
// enqueue pid by SJF if process is not in waiting queue
printk("Working Denied:%s \n", name);
}
//request rejected
return 1;
}
int ku_pop() { // dequeue from waiting queue and return dequeue
d pid valud
NODE* temp = waiting_header.first;
int res = temp->pid;
waiting_header.first = waiting_header.first->next;
waiting_header.num--;
if (waiting_header.num == 0) waiting_header.last == NULL;
kfree(temp);
return res;
}
int check(int new_pid) { // check whether or not the pid of newJo
b is in waiting queue. If it doesn't exist, return 1.
NODE* temp;
int i;
if (waiting_header.num == 0) return 1;
temp = waiting_header.first;
for (i = waiting_header.num; i > 0; i--) {
if (temp->pid == new_pid) return 0;
temp = temp->next;
}
return 1;
}
void ku_push(int pid) { // enequeue the pid of newJob into waiti
ng queue
NODE* new_node = (NODE *)kmalloc(sizeof(NODE), GFP_KERNEL);
new_node->pid = pid;
new_node->next = NULL;
if (waiting_header.num == 0) {
waiting_header.first = new_node;
waiting_header.last = new_node;
waiting_header.num++;
return;
}
waiting_header.last->next = new_node;
waiting_header.last = new_node;
waiting_header.num++;
return;
}
void ku_push_SJF(int pid, int jobTime) { // enequeue the
pid of newJob into waiting queue by ascending order
NODE* pPre = NULL; // former location of ploc
NODE* pLoc; // searching location
NODE* new_node = (NODE *)kmalloc(sizeof(NODE), GFP_KERNEL);
new_node->pid = pid;
new_node->jobTime = jobTime;
new_node->next = NULL;
if (waiting_header.num == 0) {
waiting_header.first = new_node;
waiting_header.last = new_node;
waiting_header.num++;
return;
}
pLoc = waiting_header.first;
while (pLoc) {
if (pLoc->jobTime > new_node->jobTime) break;
pPre = pLoc;
pLoc = pLoc->next;
}
new_node->next = pLoc;
if (pLoc == NULL) waiting_header.last = new_node; // last
if (pPre == NULL) waiting_header.first = new_node; // first
else pPre->next = new_node;
waiting_header.num++;
return;
}
run file
./kucpu_run 7 0 A & ./kucpu_run 5 1 B & ./kucpu_run 3 2 C &




