-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprocess_generator.c
176 lines (144 loc) · 4.64 KB
/
process_generator.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
#include "headers.h"
void clearResources(int);
void sendProcess(int);
void endProgram(int);
const Node NULLNODE;
Node *arrivedProc;
queue* allProcesses;
int time; // stores current time
int schedulerPid; // stores the PID of the scheduler
int shmidAP;
int shmidReturnedP;
// Function to read incoming processes file, save it into a queue, and return the queue
queue* readFile(char *f)
{
int i, a, b, p, m;
queue *Q = (queue*)malloc(sizeof(queue));
FILE *fp = fopen (f, "r");
char line[100] = {0};
char *ignore = fgets (line, 100, fp);
Node* n;
while(fscanf(fp, "%d %d %d %d %d", &i, &a, &b, &p, &m) == 5)
{
n = newNode(i, a, b, p, m);
enqueue(Q, n);
}
fclose(fp);
return Q;
}
int main(int argc, char * argv[])
{
// signal(SIGINT, clearResources); // Clears resources when interrupted
signal(SIGUSR1, sendProcess); // Sends arrived processes to scheduler each second when signaled by scheduler
signal(SIGUSR2, endProgram); // Test if all processes are sent to scheduler and end the program when signaled by scheduler
char file[100]; // name of the input file where processes info is stored
int scheduler; // scheduler type
int quantum = 0; // scheduler time quantum if round robin (remains 0 otherwise)
// Read input file
printf("You come again, kind user! \nEnter the name of your processes file:");
scanf("%s", file);
allProcesses = readFile(file);
// Choose scheduler type
printf( "Pick your scheduler: \n 1. Preemptive Highest Priority First \n 2. Shortest Job First \n 3. Round Robin \n 4. Shortest Remaining Time Next \nThe number of your choice: ");
scanf("%d", &scheduler);
// If chosen scheduler is round robin, input time quantum
if (scheduler == 3)
{
printf("The length of your quantum in seconds: ");
scanf("%d", &quantum);
}
// Shared memory to send arriving processes to scheduler
shmidAP = shmget(59, sizeof(Node*), IPC_CREAT|0644);
if(shmidAP == -1)
{
perror("Error in creating shmidAP");
exit(-1);
}
// Shared memory to store number of returned processes
shmidReturnedP = shmget(501, 4, IPC_CREAT | 0644);
if ((long)shmidReturnedP == -1)
{
perror("Error in creating shm!");
exit(-1);
}
// Create clock
int clockPid = fork();
if (clockPid == -1)
perror("error in fork");
else if (clockPid == 0)
{
char *argv[] = { "./clk.out", 0 };
execve(argv[0], &argv[0], NULL);
}
// Initiatize clock
initClk();
// Initiate scheduler
schedulerPid = fork();
if (schedulerPid == -1)
perror("error in fork");
else if (schedulerPid == 0)
{
char s[4];
char q[4];
snprintf(s, 4,"%d", scheduler);
snprintf(q, 4, "%d", quantum);
char *argv[] = { "./scheduler.out", s, q, 0 };// q is zero if not round robin
execve(argv[0], &argv[0], NULL);
}
pause();
// Initialize time counter
time = -1;
Node* n = newNode(0, 0, 0, 0, 0);
while(1)
{
// If 1 clock second passes, increment internal time counter and check queue of all processes
if (getClk() > time)
{
time++;
arrivedProc = (Node*)shmat(shmidAP, NULL, 0);
// If any process arrived at this second, add it to arrived process shared memory and signal scheduler to execute second
if (!isEmpty(allProcesses) && peek(allProcesses) == time)
{
n = dequeue(allProcesses);
*arrivedProc = *n;
}
// If no process arrived at current second, signal scheduler to execute second
else
{
*arrivedProc = NULLNODE;
}
shmdt(arrivedProc);
kill(schedulerPid, SIGUSR1);
}
}
return 0;
}
// Sends arrived processes to scheduler each second when signaled by scheduler
void sendProcess(int signum)
{
arrivedProc = (Node*)shmat(shmidAP, NULL, 0);
if (!isEmpty(allProcesses) && peek(allProcesses) == time)
{
Node* n = dequeue(allProcesses);
*arrivedProc = *n;
}
// If no other process arrived at current second, signal scheduler to execute second
else
{
*arrivedProc = NULLNODE;
}
shmdt(arrivedProc);
kill(schedulerPid, SIGUSR1);
}
// Test if all processes are sent to scheduler and end the program when signaled by scheduler
void endProgram(int signum)
{
if (isEmpty(allProcesses))
{
shmctl(shmidAP, IPC_RMID, NULL);
shmctl(shmidReturnedP, IPC_RMID, NULL);
destroyClk(true);
kill(schedulerPid, SIGINT);
raise(SIGINT);
}
}