Scheduling C
Scheduling C
h"
2 #include <pthread.h>
3 #include <unistd.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6
7 #define TIME_UNIT 100 // In microsecond
8
9 static struct pqueue_t in_queue; // Queue for incomming processes
10 static struct pqueue_t ready_queue; // Queue for ready processes
11
12 static int load_done = 0;
13
14 static int timeslot; // The maximum amount of time a process is allowed
15 // to be run on CPU before being swapped out
16
17 // Emulate the CPU
18 void * cpu(void * arg) {
19 int timestamp = 0;
20 /* Keep running until we have loaded all process from the input file
21 * and there is no process in ready queue */
22 while (!load_done || !empty(&ready_queue)) {
23 /* Pickup the first process from the queue */
24 struct pcb_t * proc = de_queue(&ready_queue);
25 if (proc == NULL) {
26 /* If there is no process in the queue then we
27 * wait until the next time slice */
28 timestamp++;
29 usleep(TIME_UNIT);
30 }else{
31 /* Execute the process */
32 int start = timestamp; // Save timestamp
33 int id = proc->pid; // and PID for tracking
34 /* Decide the amount of time that CPU will spend
35 * on the process and write it to 'exec_time'.
36 * It should not exeed 'timeslot'.
37 */
38 int exec_time = 0;
39
40 // TODO: Calculate exec_time from process's PCB
41
42 // YOUR CODE HERE
43 if(proc->arrival_time <= timestamp)
44 {
45 if(proc->burst_time > timeslot)
46 {
47 proc->burst_time -= timeslot;
48 exec_time += timeslot;
49 }
50 else
51 {
52 exec_time += proc->burst_time;
53 proc->burst_time = 0;
54 }
55 }
56 else
57 {
58 timestamp++;
59 usleep(TIME_UNIT);
60 }
61 /* Emulate the execution of the process by using
62 * 'usleep()' function */
63 usleep(exec_time * TIME_UNIT);
64
65 /* Update the timestamp */
66 timestamp += exec_time;
67
68 // TODO: Check if the process has terminated (i.e. its
69 // burst time is zero. If so, free its PCB. Otherwise,
70 // put its PCB back to the queue.
71
72 // YOUR CODE HERE
73 if(proc->burst_time == 0) {
74 free(proc);
75 }
76 else{
77 en_queue(&ready_queue,proc);
78 }
79
80 /* Track runtime status */
81 printf("%2d-%2d: Execute %d\n", start, timestamp, id);
82 }
83 }
84 }
85
86 // Emulate the loader
87 void * loader(void * arg) {
88 int timestamp = 0;
89 /* Keep loading new process until the in_queue is empty*/
90 while (!empty(&in_queue)) {
91 struct pcb_t * proc = de_queue(&in_queue);
92 /* Loader sleeps until the next process available */
93 int wastetime = proc->arrival_time - timestamp;
94 usleep(wastetime * TIME_UNIT);
95 /* Update timestamp and put the new process to ready queue */
96 timestamp += wastetime;
97 en_queue(&ready_queue, proc);
98 }
99 /* We have no process to load */
100 load_done = 1;
101 }
102
103 /* Read the list of process to be executed from stdin */
104 void load_task() {
105 int num_proc = 0;
106 scanf("%d %d\n", ×lot, &num_proc);
107 int i;
108 for (i = 0; i < num_proc; i++) {
109 struct pcb_t * proc =
110 (struct pcb_t *)malloc(sizeof(struct pcb_t));
111 scanf("%d %d\n", &proc->arrival_time, &proc->burst_time);
112 proc->pid = i;
113 en_queue(&in_queue, proc);
114 }
115 }
116
117 int main() {
118 pthread_t cpu_id; // CPU ID
119 pthread_t loader_id; // LOADER ID
120
121 /* Initialize queues */
122 initialize_queue(&in_queue);
123 initialize_queue(&ready_queue);
124
125 /* Read a list of jobs to be run */
126 load_task();
127
128 /* Start cpu */
129 pthread_create(&cpu_id, NULL, cpu, NULL);
130 /* Start loader */
131 pthread_create(&loader_id, NULL, loader, NULL);
132
133 /* Wait for cpu and loader */
134 pthread_join(cpu_id, NULL);
135 pthread_join(loader_id, NULL);
136
137 pthread_exit(NULL);
138
139 }
140
141
142