-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
772 lines (702 loc) · 23.8 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10
// global variables
int tick = 0;
int capture_process = 0; // Detect whether process is assigned or not.
int capture_burst = 0;
int pointProcess = 0; // Pointing current process
int index = 0;
int compare_index = -1; // index비교
int sequence_holder = 0; // RR, readyQueue에서 프로세스의 순서
int readyProcess = 0; // RR, readyQueue에서 기다리는 프로세스 개수
int timeQuantum = 2; // RR, timeQuantum value
int RR = 0; // RR, timeQuantum switch
typedef struct Process {
int p_id;
int p_arrival;
int p_burst;
int p_allocated;
int p_finish;
int p_used; // Process 사용 유무: 사용안함(-1), 사용함(1)
int p_remainBurst; // SRTF, RR에 사용할 남은 bursttime저장용 변수
int p_sequence; // RR에 사용할 순서 할당 변수
}Process;
typedef struct readyQueue {
int method;
int capacity;
struct NormalType {
struct Process queue[MAXSIZE];
int front, rear;
}Normal;
struct CircularType {
struct Process queue[MAXSIZE];
int front, rear;
}Circular;
struct PriorityType {
struct Process queue[MAXSIZE];
int front, rear;
}Priority;
}readyQueue;
int isEmpty(readyQueue* _Q) {
if (_Q->method == 1) {
return (_Q->Normal.front == _Q->Normal.rear);
}
else if (_Q->method == 2) {
return (_Q->Priority.front == _Q->Priority.rear);
}
else if (_Q->method == 3) {
return (_Q->Priority.front == _Q->Priority.rear);
}
else {
return (_Q->Circular.front == _Q->Circular.rear);
}
}
int isFull(readyQueue* _Q) {
if (_Q->method == 1) {
return (_Q->capacity == MAXSIZE);
}
else if (_Q->method == 2) {
return (_Q->capacity == MAXSIZE);
}
else if (_Q->method == 3) {
return (_Q->capacity == MAXSIZE);
}
else {
return (_Q->capacity == MAXSIZE);
}
}
void initQueue(readyQueue* _Q) {
capture_process = 0; // Initialize global variable (capture_process): FALSE.
_Q->capacity = 0;
if (_Q->method == 1) {
_Q->Normal.front = 0;
_Q->Normal.rear = 0;
}
else if (_Q->method == 2) {
_Q->Priority.front = 0;
_Q->Priority.rear = 0;
}
else if (_Q->method == 3) {
_Q->Priority.front = 0;
_Q->Priority.rear = 0;
}
else {
_Q->Circular.front = 0;
_Q->Circular.rear = 0;
}
}
void enQueue(readyQueue* _Q, Process _P) {
if (_Q->method == 1) {
if (isFull(_Q)) {
printf("d\n", "Error: FULL!");
return;
}
_Q->Normal.queue[_Q->Normal.rear] = _P;
_Q->Normal.rear++;
_Q->capacity++;
}
else if (_Q->method == 2) {
if (isFull(_Q)) {
printf("d\n", "Error: FULL!");
return;
}
_Q->Priority.queue[_Q->Priority.rear] = _P;
_Q->Priority.rear++;
_Q->capacity++;
}
else if (_Q->method == 3) {
if (isFull(_Q)) {
printf("d\n", "Error: FULL!");
return;
}
_Q->Priority.queue[_Q->Priority.rear] = _P;
_Q->Priority.rear++;
_Q->capacity++;
}
else {
if (isFull(_Q)) {
printf("d\n", "Error: FULL!");
return;
}
_Q->Circular.queue[_Q->Circular.rear] = _P;
_Q->Circular.rear++;
_Q->capacity++;
}
}
Process deQueue(readyQueue* _Q) {
if (_Q->method == 1) {
if (isEmpty(_Q)) {
printf("d\n", "Error: EMPTY!");
exit(1);
}
Process temp = _Q->Normal.queue[_Q->Normal.front];
_Q->capacity--;
_Q->Normal.front++;
return temp;
}
else if (_Q->method == 2) {
if (isEmpty(_Q)) {
printf("d\n", "Error: EMPTY!");
exit(1);
}
Process temp = _Q->Priority.queue[_Q->Priority.front];
_Q->capacity--;
_Q->Priority.front++;
return temp;
}
else if (_Q->method == 3) {
if (isEmpty(_Q)) {
printf("d\n", "Error: EMPTY!");
exit(1);
}
Process temp = _Q->Priority.queue[_Q->Priority.front];
_Q->capacity--;
_Q->Priority.front++;
return temp;
}
else {
if (isEmpty(_Q)) {
printf("d\n", "Error: EMPTY!");
exit(1);
}
Process temp = _Q->Circular.queue[_Q->Circular.front];
_Q->capacity--;
_Q->Circular.front++;
return temp;
}
}
struct readyQueue Scheduler; // Main Scheduler
Process temp; // Variable for contiaining process in ready queue.
int pickProcess(readyQueue* _Q, int _tick) {
int burst = 1000;
int result = -1;
for (int i = 0; i < _Q->capacity; i++) {
if (_Q->Priority.queue[i].p_used == -1) { // 선택한 프로세스가 사용되지 않은것인 경우
//if ((_Q->Priority.queue[i].p_arrival <= _tick) && (_Q->Priority.queue[i].p_burst <= burst))
if (_Q->Priority.queue[i].p_arrival <= _tick) {
if (_Q->Priority.queue[i].p_burst < burst) {
burst = _Q->Priority.queue[i].p_burst;
result = i;
}
else {
continue;
}
}
else {
continue;
}
}
else { // 선택한 프로세스가 이미 사용된 경우
continue;
}
}
return result;
}
int monitProcess(readyQueue* _Q, int _tick) {
int burst = 1000;
int result = -1;
for (int i = 0; i < _Q->capacity; i++) {
if (_Q->Priority.queue[i].p_used != 1) { // 해당 프로세스가 사용전(-1), 사용중(0), 사용후(1), 즉 사용되지 않은 것을 찾는다.
if (_Q->Priority.queue[i].p_arrival <= _tick) {
if (_Q->Priority.queue[i].p_remainBurst < burst) {
burst = _Q->Priority.queue[i].p_remainBurst;
result = i;
}
else {
continue;
}
}
else {
continue;
}
}
else {
continue;
}
}
return result;
}
void rotateProcess(readyQueue* _Q, int _tick) { // sequence holder을 사용해서 sequence가 -1인 것에 readyqueue에 들어온 프로세스에 순서 부여 (arrive안에 들어온 것들), 그 이후는 안에서 자동으로 부여 될 것이다.
for (int i = 0; i < _Q->capacity; i++) { // 전체 프로세스 검사
if (_Q->Circular.queue[i].p_used == -1) { // 해당 프로세스가 사용되지 않은 프로세스 인 경우
if (_Q->Circular.queue[i].p_arrival <= _tick) { // 해당 프로세스이 도착한 경우
_Q->Circular.queue[i].p_sequence = sequence_holder; // 대기열 순서를 부여
sequence_holder++; // 다음 순서 대기
_Q->Circular.queue[i].p_used = 0; // 해당 프로세스가 사용 중, 사용이 시작되었음을 표시
readyProcess++; // 준비가 되어있는 프로세스의 개수
}
}
}
}
void set_schedule(int method) {
if (method == 1) {
printf("Scheduling method: FCFS: First Come First Served (Non-preemptive) \n\n");
Scheduler.method = 1;
initQueue(&Scheduler);
}
else if (method == 2) {
printf("Scheduling method: SJF: Shortest Job First (Non-preemptive) \n\n");
Scheduler.method = 2;
initQueue(&Scheduler);
}
else if (method == 3) {
printf("Scheduling method: SRTF: Shortest Remaining Time First (Preemptive) \n\n");
Scheduler.method = 3;
initQueue(&Scheduler);
}
else if (method == 4) {
printf("Scheduling method: RR: Round Robin (Preemptive) \n\n");
Scheduler.method = 4;
initQueue(&Scheduler);
}
else {
printf("Error: Method number is incorrect!\n");
Scheduler.method = -1;
exit(1);
}
}
void read_proc_list(const char* filename) {
int count; // The number of process in text file.
int p_id; // The id of process in text file.
int p_arrival; // The arrival time of process in text file.
int p_burst; // The burst time of process in text file.
Process p_element; // The process for containing information.
FILE* file = fopen(filename, "r"); // Open file
if (file == NULL)
{
printf("%s\n", "ERROR: Failed to read file");
exit(1);
}
fscanf(file, "%d", &count);
//printf("%d\n", count); // count 출력 확인용
for (int i = 0; i < count; i++) {
fscanf(file, "%d %d %d", &p_id, &p_arrival, &p_burst);
p_element.p_id = p_id;
p_element.p_arrival = p_arrival;
p_element.p_burst = p_burst;
p_element.p_allocated = -1;
p_element.p_finish = -1;
p_element.p_used = -1;
p_element.p_remainBurst = p_burst;
p_element.p_sequence = -1;
enQueue(&Scheduler, p_element); // 여기 &안해서 오류날수도!!
//printf("%d %d %d\n", p_id, p_arrival, p_burst);
}
fclose(file);
// 저장 출력 확인용도
/*
for (int j = 0; j < count; j++) {
Process print = Scheduler.Normal.queue[j];
printf("%d %d %d %d %d\n", print.p_id, print.p_arrival, print.p_burst, print.p_allocated, print.p_finish);
}
*/
}
int do_schedule(int tick)
/*
tick은 전역변수로 0부터 시작
스케줄러 time은 tick과 같이 흘러가지
tick 0이다.
if p1의 arrival time이 0이다.
tick 1이다
if p1의 arrival time이 tick보다 작고, burst time이 남았다 -> burst time을 1씩 감소
burst time이 0이되면 dequeue한다
--> 게시판 전역 변수 구조체를 만들어서 저장해놨다가 print performance에 써야겠다...
만약 capacity가 0이 되면 return 0
그 외에는 1
*/
{
int numProcess = Scheduler.capacity; // the number of process in ready queue.
if (Scheduler.method == 1) {
// 스케줄러에 저장된 큐의 arrival time을 tick과 비교하여 확인하자
for (int i = 0; i < numProcess; i++) {
if (Scheduler.Normal.queue[i].p_arrival == tick) {
printf("[tick: %d] New Process (ID: %d) newly joins to ready queue\n", tick, Scheduler.Normal.queue[i].p_id);
}
}
// FCFS
if (capture_process == 0) { // 지금 잡힌게 없다
if (pointProcess < numProcess) { // 스케줄러에는 프로세스가 남아있다.
temp = Scheduler.Normal.queue[pointProcess];// 임시 프로세스 저장
if (temp.p_arrival <= tick) { // 해당 프로세스의 arrival이 tick보다 작으면
capture_process = 1; // 프로세스 잡았다.
Scheduler.Normal.queue[pointProcess].p_allocated = tick; // cpu 할당 시간 입력
capture_burst = temp.p_burst; // burst 복사
printf("[tick: %d] Dispatch to Process (ID: %d)\n", tick, temp.p_id);
}
else {
return 1; // arrival을 기다린다.
}
}
else { // 스케줄러에는 프로세스가 남아있지 않다.
printf("[tick: %d] All processes are terminated.\n", tick);
return 0; // res를 0으로 만들면서 종료.
}
}
else { // 지금 잡힌게 있고 allocated 된 상태이다.
capture_burst--; // burst time을 1줄인다.
if (capture_burst > 0) { // 만약 burst time이 소진되면
return 1;
}
else { // 만약 burst time이 남아있는 경우.
Scheduler.Normal.queue[pointProcess].p_finish = tick; // process의 finish 시간을 저장.
pointProcess++; // 가리키는 프로세스를 이동.
capture_process = 0; // 현재 잡고있는 프로세스 놓아줌.
if (pointProcess < numProcess) {
temp = Scheduler.Normal.queue[pointProcess];
if (temp.p_arrival <= tick) {
capture_process = 1;
Scheduler.Normal.queue[pointProcess].p_allocated = tick;
capture_burst = temp.p_burst;
printf("[tick: %d] Dispatch to Process (ID: %d)\n", tick, temp.p_id);
}
else {
return 1;
}
}
else {
printf("[tick: %d] All processes are terminated.\n", tick);
return 0;
}
return 1;
}
}
}
else if (Scheduler.method == 2) { //SJF
for (int i = 0; i < numProcess; i++) {
if (Scheduler.Priority.queue[i].p_arrival == tick) {
printf("[tick: %d] New Process (ID: %d) newly joins to ready queue\n", tick, Scheduler.Priority.queue[i].p_id);
}
}
if (capture_process == 0) {
if (pointProcess < numProcess) { // pointProcess로 스케줄러 프로세스 사용 개수 체크
index = pickProcess(&Scheduler, tick); // 적합한 프로세스를 찾기
if (index != -1) { // 적합한 프로세스를 찾은 경우
temp = Scheduler.Priority.queue[index];
capture_process = 1;
Scheduler.Priority.queue[index].p_allocated = tick;
capture_burst = temp.p_burst;
printf("[tick: %d] Dispatch to Process (ID: %d)\n", tick, temp.p_id);
}
else { // 적합한 프로세스를 찾지 못한 경우
return 1; // 시간을 보낸다.
}
}
else { // 스케줄러 프로세스 다 썼다.
printf("[tick: %d] All processes are terminated.\n", tick);
return 0; // res를 0으로 만들면서 종료.
}
}
else {
capture_burst--;
if (capture_burst > 0) {
return 1;
}
else {
Scheduler.Priority.queue[index].p_finish = tick;
Scheduler.Priority.queue[index].p_used = 1; // 해당 프로세스를 다 사용했다는 것을 표시
pointProcess++; // 사용한 프로세스의 개수를 표시
capture_process = 0;
if (pointProcess < numProcess) { // 모든 프로세스를 다 사용하지 않은 경우
index = pickProcess(&Scheduler, tick); // 적합한 프로세스를 찾기
if (index != -1) { // 적합한 프로세스를 찾은 경우
temp = Scheduler.Priority.queue[index];
capture_process = 1;
Scheduler.Priority.queue[index].p_allocated = tick;
capture_burst = temp.p_burst;
printf("[tick: %d] Dispatch to Process (ID: %d)\n", tick, temp.p_id);
}
else { // 적합한 프로세스를 찾지 못한 경우
return 1; // 시간을 보낸다.
}
}
else { // 모든 프로세스를 다 사용한 경우
printf("[tick: %d] All processes are terminated.\n", tick);
return 0; // res를 0으로 만들면서 종료.
}
}
}
}
else if (Scheduler.method == 3) { //SRTF
int dispatch = 0; // dispatch 아니면(0), 맞으면(1)
for (int i = 0; i < numProcess; i++) {
if (Scheduler.Priority.queue[i].p_arrival == tick) {
printf("[tick: %d] New Process (ID: %d) newly joins to ready queue\n", tick, Scheduler.Priority.queue[i].p_id);
}
}
if (pointProcess < numProcess) { // 스케줄러에 프로세스가 남아있다
index = monitProcess(&Scheduler, tick); // 적합한 프로세스를 찾는다.
if (compare_index == -1) { // 비교 index가 초기화가 되어있는 상태
compare_index = index;
}
else { // 비교 index가 할당되어있는 상태
if (compare_index == index) { // 프로세스가 바뀌지 않았다.
dispatch = 0;
}
else { // 프로세스가 바뀌었다.
dispatch = 1;
compare_index = index; // 바뀌었으면 그다음 비교를 위해 가져가기
}
}
if (index != -1) { // 적합한 프로세스를 찾은 경우
temp = Scheduler.Priority.queue[index];
if (temp.p_used == -1) { // 처음 선택된 프로세스의 경우
Scheduler.Priority.queue[index].p_used = 0; // 사용이 시작되었음을 표시
Scheduler.Priority.queue[index].p_allocated = tick; // 할당된 시간을 표시
Scheduler.Priority.queue[index].p_remainBurst--; // 남은 burst시간을 줄여주기
printf("[tick: %d] Dispatch to Process (ID: %d)\n", tick, temp.p_id);// dispatch
if (Scheduler.Priority.queue[index].p_remainBurst > 0) { // 남은 burst시간이 있으면
return 1;
}
else { // 남은 burst시간이 없으면
Scheduler.Priority.queue[index].p_used = 1; // 해당 프로세스가 다 사용되었음을 표시
Scheduler.Priority.queue[index].p_finish = tick + 1; // 종료된 시간 할당
pointProcess++; // 사용된 프로세스 개수 증가
return 1;
}
}
else { // 이전에도 사용된 프로세스의 경우
if (dispatch == 1) {
printf("[tick: %d] Dispatch to Process (ID: %d)\n", tick, temp.p_id);// dispatch
}
Scheduler.Priority.queue[index].p_remainBurst--;
if (Scheduler.Priority.queue[index].p_remainBurst > 0) { // 남은 burst시간이 있으면
return 1;
}
else { // 남은 burst시간이 없으면
Scheduler.Priority.queue[index].p_used = 1; // 해당 프로세스가 다 사용되었음을 표시
Scheduler.Priority.queue[index].p_finish = tick + 1; // 종료된 시간 할당
pointProcess++; // 사용된 프로세스 개수 증가
return 1;
}
}
}
else { // 적합한 프로세스를 찾지 못한 경우
return 1;
}
}
else { // 스케줄러에 프로세스를 다 썼다
printf("[tick: %d] All processes are terminated.\n", tick);
return 0;
}
}
else { //RR
int tempSequence = 99999999999999; //순서 비교용 변수
for (int i = 0; i < numProcess; i++) {
if (Scheduler.Circular.queue[i].p_arrival == tick) {
printf("[tick: %d] New Process (ID: %d) newly joins to ready queue\n", tick, Scheduler.Circular.queue[i].p_id);
}
}
if (pointProcess < numProcess) { // readyProcess(출력대기) sequence_holder(대기프로세스의 순서) pointProcess(남은 프로세스)
rotateProcess(&Scheduler, tick); //readyProcess, sequence_holder 업데이트
if (readyProcess > 0) { // 출력 대기인 프로세스가 있는 경우 (p_used: -1 -> 0), 한번썼던것 (p_used: 0 -> 1), 다쓴것 (p_used: 1->2)
// p_used(-1:대기에도 올라오지 않음) (0:사용대기) (1:사용경험있음) (2:사용종료)
// RR변수랑 timequantum이용하자
if (RR == 0) { // 현재 돌아가고 있는 프로세스가 없는 경우
for (int j = 0; j < numProcess; j++) { // 출력 대기인 프로세스 중에서 sequence가 가장 작은것을 선택
if ((Scheduler.Circular.queue[j].p_used == 0) || (Scheduler.Circular.queue[j].p_used == 1)) { // 처음 사용, 이전 사용 혼재
if (Scheduler.Circular.queue[j].p_sequence < tempSequence) {
tempSequence = Scheduler.Circular.queue[j].p_sequence;
index = j; // 가장 앞에 있는 프로세스의 index 저장
}
}
}
temp = Scheduler.Circular.queue[index];
if (Scheduler.Circular.queue[index].p_used == 0) { // 선택된 프로세스가 처음 이면
Scheduler.Circular.queue[index].p_used = 1;
Scheduler.Circular.queue[index].p_allocated = tick;
Scheduler.Circular.queue[index].p_remainBurst--;
timeQuantum--; // timeQuantum 줄이기
RR = 1; // 현재 할당된 프로세스가 있음을 표시
printf("[tick: %d] Dispatch to Process (ID: %d)\n", tick, temp.p_id); // dispatch
if (timeQuantum > 0) {
if (Scheduler.Circular.queue[index].p_remainBurst > 0) {
return 1;
}
else {
timeQuantum = 2;
RR = 0;
Scheduler.Circular.queue[index].p_used = 2;
Scheduler.Circular.queue[index].p_finish = tick + 1;
pointProcess++;
Scheduler.Circular.queue[index].p_sequence = sequence_holder++;
return 1;
}
}
else {
if (Scheduler.Circular.queue[index].p_remainBurst > 0) {
timeQuantum = 2;
RR = 0;
Scheduler.Circular.queue[index].p_sequence = sequence_holder++;
return 1;
}
else {
timeQuantum = 2;
RR = 0;
Scheduler.Circular.queue[index].p_used = 2;
Scheduler.Circular.queue[index].p_finish = tick + 1;
pointProcess++;
Scheduler.Circular.queue[index].p_sequence = sequence_holder++;
return 1;
}
}
}
else { // 선택된 프로세스가 처음이 아니면
Scheduler.Circular.queue[index].p_remainBurst--;
timeQuantum--;
RR = 1;
printf("[tick: %d] Dispatch to Process (ID: %d)\n", tick, temp.p_id); // dispatch
if (timeQuantum > 0) { // timeQuantum이 남은 경우
if (Scheduler.Circular.queue[index].p_remainBurst > 0) { // 프로세스의 remainburst가 남은 경우
return 1;
}
else { // 프로세스의 remainburst를 다 쓴 경우
timeQuantum = 2;
RR = 0;
Scheduler.Circular.queue[index].p_used = 2;
Scheduler.Circular.queue[index].p_finish = tick + 1;
pointProcess++;
Scheduler.Circular.queue[index].p_sequence = sequence_holder++;
return 1;
}
}
else { // timeQuantum을 다 쓴 경우
if (Scheduler.Circular.queue[index].p_remainBurst > 0) { // 프로세스의 remainburst가 남은 경우
timeQuantum = 2;
RR = 0;
Scheduler.Circular.queue[index].p_sequence = sequence_holder++;
return 1;
}
else { // 프로세스의 remainburst를 다 쓴 경우
timeQuantum = 2;
RR = 0;
Scheduler.Circular.queue[index].p_used = 2;
Scheduler.Circular.queue[index].p_finish = tick + 1;
pointProcess++;
Scheduler.Circular.queue[index].p_sequence = sequence_holder++;
return 1;
}
}
}
}
else { // 현재 돌아가고 있는 프로세스가 있는 경우
Scheduler.Circular.queue[index].p_remainBurst--;
timeQuantum--;
RR = 1;
if (timeQuantum > 0) { // timeQuantum이 남은 경우
if (Scheduler.Circular.queue[index].p_remainBurst > 0) { // 프로세스의 remainburst가 남은 경우
return 1;
}
else { // 프로세스의 remainburst를 다 쓴 경우
timeQuantum = 2;
RR = 0;
Scheduler.Circular.queue[index].p_used = 2;
Scheduler.Circular.queue[index].p_finish = tick + 1;
pointProcess++;
Scheduler.Circular.queue[index].p_sequence = sequence_holder++;
return 1;
}
}
else { // timeQuantum을 다 쓴 경우
if (Scheduler.Circular.queue[index].p_remainBurst > 0) { // 프로세스의 remainburst가 남은 경우
timeQuantum = 2;
RR = 0;
Scheduler.Circular.queue[index].p_sequence = sequence_holder++;
return 1;
}
else { // 프로세스의 remainburst를 다 쓴 경우
timeQuantum = 2;
RR = 0;
Scheduler.Circular.queue[index].p_used = 2;
Scheduler.Circular.queue[index].p_finish = tick + 1;
pointProcess++;
Scheduler.Circular.queue[index].p_sequence = sequence_holder++;
return 1;
}
}
}
}
else { // 출력 대기인 프로세스가 없는 경우
return 1;
}
}
else {
printf("[tick: %d] All processes are terminated.\n", tick);
return 0;
}
}
}
/*
while(1){
int res = do_schedule(tick);
if (res == 0 || tick > 100) break;
tick++;
}
*/
void print_performance()
{
int numProcess = Scheduler.capacity;
double totalTAT = 0;
double totalWT = 0;
double totalRT = 0;
printf("\n%s\n", "=================================================================================================================");
printf("%10s %10s %10s %10s %20s %18s %18s\n", "PID", "arrival", "finish", "burst", "Turn around Time", "Wating time", "Response time");
printf("%s\n", "=================================================================================================================");
for (int j = 0; j < numProcess; j++) {
Process print;
if (Scheduler.method == 1) {
print = Scheduler.Normal.queue[j];
}
else if (Scheduler.method == 2) {
print = Scheduler.Priority.queue[j];
}
else if (Scheduler.method == 3) {
print = Scheduler.Priority.queue[j];
}
else {
print = Scheduler.Circular.queue[j];
}
int TAT = print.p_finish - print.p_arrival;
int WT = print.p_finish - print.p_arrival - print.p_burst;
int RT = print.p_allocated - print.p_arrival;
totalTAT = totalTAT + TAT;
totalWT = totalWT + WT;
totalRT = totalRT + RT;
printf("%10d %10d %10d %10d %20d %18d %18d\n", print.p_id, print.p_arrival, print.p_finish, print.p_burst, TAT, WT, RT);
}
printf("%s\n", "-----------------------------------------------------------------------------------------------------------------");
printf("%10s %30s %20f %18f %18f\n", "Average", " ", totalTAT / numProcess, totalWT / numProcess, totalRT / numProcess);
printf("%s\n", "=================================================================================================================");
}
int main(int argc, char* argv[])
{
//char file_name[1024] = "proc_list.txt";
//char file_name[1024] = "rr.txt";
//int schedule_method = 4;
char file_name[1024] = "";
int schedule_method = -1;
printf("Enter process file name:");
scanf("%s", file_name);
printf("Enter process scheduling mehtod \n");
printf("1: FCFS: First Come First Served (Non-preemptive) \n");
printf("2: SJF: Shortest Job First (Non-preemptive) \n");
printf("3: SRTF: Shortest Remaining Time First (Preemptive) \n");
printf("4: RR: Round Robin (Preemptive) \n");
scanf("%d", &schedule_method);
set_schedule(schedule_method);
// set processes
read_proc_list(file_name);
while (1) {
int res = do_schedule(tick);
if (res == 0 || tick > 100) break;
tick++;
}
// 최종 확인용!! 지워야함!
// 아이디 도착시간 실행시간 할당시간 종료시간
for (int j = 0; j < 5; j++) {
Process print = Scheduler.Circular.queue[j];
printf("%d %d %d %d %d %d\n", print.p_id, print.p_arrival, print.p_burst, print.p_allocated, print.p_finish, print.p_used);
}
print_performance();
return 0;
}