순환 리스트로 구현한 라운드 로빈 스케쥴러 (C언어)

2022. 5. 17. 15:28CS/운영체제

운영 체제 과제로 구현한 라운드로빈 스케쥴러 입니다. 

가져가셔서 입맛에 맞게 바꿔서 제출하세요 ^^

#include<stdio.h>  
#include <stdlib.h>
#include<conio.h>  

typedef struct pcb {
    struct pcb* PCBNext;
    int id;
    int arrt;
    int burt;
    int temp;

}PCB;



void InitPCB(PCB** phead, PCB** ptail);
void AddPCB(PCB** phead, PCB** ptail, int arrt, int burt, int* pcblens);
PCB* RemovePCB(PCB** phead, PCB** ptail, PCB* now, int* pcblens);
void ViewPCB(PCB* head, PCB* tail);
void CPUScheduling(PCB** phead, PCB** ptail, int quant, int NOP, int* pcblens);


void main()
{
    PCB* PCBhead, * PCBtail;
    InitPCB(&PCBhead, &PCBtail);

    // 변수 선언, 초기화
    int i, NOP, quant, wt = 0, tat = 0;
    
    printf(" 전체 PCB의 개수를 입력하시오. : ");
    scanf_s("%d", &NOP);
    int pcblens = 0;
    // 변수의 개수를 저장

    // 프로세스의 도착 시간과 종료 시간을 입력
    for (i = 0; i < NOP; i++)
    {
        int a, b;
        printf("\n 도착시간과 종료시간을 입력하세요. [%d]\n", i + 1);
        printf(" 도착 시간: \t");  // Accept arrival time  
        scanf_s("%d", &a);
        printf("\n 종료 시간: \t"); // Accept the Burst time  
        scanf_s("%d", &b);
        // temp에도 각 프로세스의 종료 시간을 저장
        AddPCB(&PCBhead, &PCBtail, a, b, &pcblens);
        printf("현재 PCB의 개수 : %d \n", pcblens);

        ViewPCB(PCBhead, PCBtail);
    }
    // 타임 퀀트 입력  
    printf("\n");
    printf("Time Quantum을 입력하시오. : \t");
    scanf_s("%d", &quant);

    CPUScheduling(&PCBhead, &PCBtail, quant, NOP,&pcblens);
    _getch();
}


void InitPCB(PCB** phead, PCB** ptail) {
    *phead = NULL;
    *ptail = NULL;
    printf("PCB가 초기화 됬습니다. \n");

}
void AddPCB(PCB** phead, PCB** ptail, int narrt, int nburt, int* pcblen) {
    PCB* newPCB = (PCB*)malloc(sizeof(PCB));
    newPCB->id = *pcblen;
    newPCB->arrt = narrt;
    newPCB->burt = nburt;
    newPCB->temp = nburt;

    if (*phead == NULL)
    {
        newPCB->PCBNext = newPCB;
        *phead = *ptail = newPCB;
        *pcblen += 1;
        return;
    }
    (*ptail)->PCBNext = newPCB;
    newPCB->PCBNext = (*phead);
    *ptail = newPCB;
    *pcblen += 1;

}
PCB* RemovePCB(PCB** phead, PCB** ptail, PCB* now, int* pcblen) {
    PCB* prev = NULL;
    PCB* seek = *phead;
    PCB* head = *phead;


    while (seek != *ptail)
    {
        if (seek == now)
        {
            break;
        }
        prev = seek;
        seek = seek->PCBNext;
    }

    if (seek == *ptail && seek != now)
    {
        return;
    }
    if (seek == *phead)
    {
        *phead = seek->PCBNext;
        (*ptail)->PCBNext = *phead;
        free(seek);
        *pcblen -= 1;
        return *ptail;
    }
    if (seek == *ptail)
    {
        *ptail = prev;
    }
    if (prev)
    {
        prev->PCBNext = seek->PCBNext;
    }
    free(seek);
    *pcblen -= 1;
    return prev;

}

void ViewPCB(PCB* head, PCB* tail)
{
    PCB* seek = head;
    int i = 0;

    if (head == NULL) {
        printf("비어 있습니다 \n");
        return;
    }
    while (seek != tail)
    {
        i++;
        printf("[%2d]:%-05d, %-05d", i, seek->arrt, seek->burt);

        if (i % 5 == 0)
        {
            printf("\n");
        }
        seek = seek->PCBNext;
    }
    i++;
    printf("[%2d]:%-05d, %-05d", i, seek->arrt, seek->burt);
    printf("\n");
}

void CPUScheduling(PCB** phead, PCB** ptail, int quant, int NOP, int* pcblen) {
    printf("\n PCB ID \t\t Burst Time \t\t TAT \t\t Waiting Time \n");
    int i, sum, count = 0, wt = 0, tat = 0;
    int start = (*phead)->arrt;
    float avg_wt, avg_tat;

    PCB* now = *phead;
    for (sum = 0, i = 0; *pcblen != 0; )
    {
        if (now->temp <= quant && now->temp > 0) // define the conditions   
        {
            sum = sum + now->temp;
            now->temp = 0;
            count = 1;
        }
        else if (now->temp > 0)
        {
            now->temp = now->temp - quant;
            sum = sum + quant;
        }
        if (now->temp == 0 && count == 1)
        {
            PCB* now_adr = NULL;
            printf("\nPCB ID[%d] \t\t %d\t\t\t %d\t\t %d", now->id, now->burt, sum - now->arrt + start, sum - now->arrt - now->burt + start);
            wt = wt + sum - now->arrt - now->burt ;
            tat = tat + sum - now->arrt ;

            if (now->PCBNext->arrt <= sum) {
                now_adr = now->PCBNext;
            }
            else {
                now_adr = *phead;
            }
            
            now = RemovePCB(phead, ptail, now, pcblen);
            
            count = 0;
        }
        if (pcblen == 0) {
            return;
        }
        if(*pcblen >= 1 && now->PCBNext->arrt <= sum) {
            now = now->PCBNext;
        }
        else {
            now = *phead;
        }

    }
    avg_wt = wt * 1.0 / NOP + start;
    avg_tat = tat * 1.0 / NOP+ start;
    printf("\n Average Turn Around Time: \t%f", avg_tat);
    printf("\n Average Waiting Time: \t%f", avg_wt);
}
반응형

'CS > 운영체제' 카테고리의 다른 글

OS : Deadlock, priority inversion  (0) 2022.06.02
LRU 구현하기  (0) 2022.05.17
OS : CPU Scheduling & Context Switch (microC/ OS-2)  (0) 2022.04.14
OS : 프로세스 구현 (microC/ OS-2)  (0) 2022.04.14
OS : Thread (microC/ OS-2)  (0) 2022.04.14