forked from ShariKing/FuzzyBunnies
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkernel.c
282 lines (199 loc) · 6.71 KB
/
kernel.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
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include "rtx.h"
// *** PCB ENQUEUE ***
int PCB_ENQ(PCB *r, PCB_Q *queue) {
/// if either the PCB pointer or the queue pointer are NULL don't do anything
if (!r || !queue)
return 0;
// if queue is empty
if (queue->head == NULL) {
// set head of queue to new PCB
queue->head = r;
// set tail of queue to new PCB
queue->tail = r;
return 1;
}
// If the queue is NOT empty
// set the 'next' pointer of the PCB at the queue-tail to the newly enqueued PCB
queue->tail->p = r;
// set the 'next' pointer of the newly enqueued PCB to NULL (ie. it's the end of the queue)
r->p = NULL;
// set the tail of the queue to new PCB
queue->tail = r;
return 1;
}
// *** PCB ENQUEUE ***
PCB *PCB_DEQ(PCB_Q *queue) {
// if queue is empty
if (queue->head == NULL) {
//printf("Queue is empty");
// return a NULL pointer
return NULL;
}
// if the queue is NOT empty
// create a temp pointer to a PCB
PCB *t;
// set temp to point to the head of the queue
t = queue->head;
// set the new head of the queue to the 'next' PCB (ie. second in queue) of the old head
queue->head = queue->head->p;
//if the new queue only has one PCB, set the tail = head = PCB
if (queue->head->p == NULL)
queue->tail = queue->head;
// return the pointer to the dequeued PCB
return t;
}
// ***ENVELOPE ENQUEUE***
int env_ENQ(msg_env *e, env_Q *queue) {
if (!e || !queue)
return 0;
//if queue is empty
if (queue->head == NULL) {
// set head of queue to e
queue->head = e;
// set tail of queue to e
queue->tail = e;
return 1;
}
// if the queue is NOT empty
// set the 'next' pointer of the env at the queue-tail to the newly enqueued env
queue->tail->p = e;
// set the 'next' pointer of the new env to NULL
e->p = NULL;
// set the tail of the queue to the new env
queue->tail = e;
return 1;
}
// *** ENVELOPE DEQUEUE ***
msg_env *env_DEQ(env_Q *queue) {
// if the queue doesn't exist
if (!queue)
return NULL;
// create a temp env pointer
msg_env *t = NULL;
// if queue is empty
if (queue->head == NULL) {
// return a NULL pointer
return NULL;
}
// if the queue is NOT empty
// point the temp to the head of the queue
t = queue->head;
// point the new head of the queue to the 'next' pointer of the old head
queue->head = queue->head->p;
// if the queue now only has one env, set the tail = head = sole env
if (queue->head == NULL)
queue->tail = queue->head;
return t;
}
// *** SEND MESSAGE ***
int send_message(int dest_id, msg_env *e) {
// if the env is NULL
if (!e)
return 0;
// if the PCB ID is not valid
if (dest_id > (NUM_PROC - 1) ) {
//printf("Invalid 'Send To' ID, %i, ", dest_id);
return 0;
}
// if the PCD ID is valid
// set the target_id parameter of the env to dest_id
e->target_id = dest_id;
e->sender_id = curr_process->pid;
// create a pointer to the target PCB using the target_id
PCB *target = convert_PID(dest_id);
// if the PID converts correctly to a pointer
if (target){
/*unblock the target process if necessary*/
// if the target's receive message queue is empty or the target is not an i-process
/*if (target->receive_msg_Q->head == NULL || target->priority != -1) {
// enqueue the PCB of the process on the appropriate ready queue
PCB_ENQ(target, convert_priority(target->priority)); //*****not sure if need to put a '&' before convert_priority
// set the target state to 'ready'
strcpy(target->state, "READY"); //apparently strcpy is how you write into an array of chars
}*/
// enqueue the env on the target's receive queue
env_ENQ(e, target->receive_msg_Q);
return 1;
}
// if the PID doesn't convert successfully
else
return 0;
}
// ***RECEIVE MESSAGE***
msg_env *receive_message() { //Doesn't take the PCB as a parameter. Dealt with using curr_process
// if the receive message queue is empty
if (curr_process->receive_msg_Q->head == NULL) {
// if the process is an iprocess or should never be blocked, return a NULL pointer (ie. no env)
if (curr_process->priority == -1 || curr_process->state == "NEVER_BLK_PROC")
return NULL;
// if it's a normal process, block it on receive
strcpy(curr_process->state, "BLK_ON_RCV"); //*********Doesn't need to be put in a queue, and don't care about process switch now********* FIX THIS
return NULL; // *****TO BE FIXED WITH CONTEXT SWITCHING
}
// if the message queue is not empty, dequeue the first message in the queue
else
return env_DEQ(curr_process->receive_msg_Q);
}
// *** SEND CONSOLE CHARS***
int send_console_chars(msg_env *env) {
// if the env is NULL
if (!env)
return 0;
int Z;
// relay the env to the crt i-process using send_message
Z = send_message(1, env);
// if sending fails
if (Z == 0){
//printf("Error with sending");
return 0;
}
return 1;
}
// ***GET CONSOLE CHARS***
int get_console_chars(msg_env * env) {
// if the env is NULL
if (!env)
return 0;
int Z;
// relay the env to the kb i-process using send_message
Z = send_message(0, env);
// incorrect return from send_message
if(Z == 0) {
//printf("Error with sending");
return 0;
}
return 1;
}
// ***GET A PROCESS ID AND RETURN IT'S PCB POINTER***
PCB *convert_PID(int PID) {
// if the process ID is invalid
if (PID > (NUM_PROC - 1) || PID < 0) {
// printf("invalid ID");
return NULL;
}
// if the ID is valid, return the pointer in the PCB array at the value of ID
return pointer_2_PCB[PID];
}
// ***CHANGE THE PRIORITY OF A PROCESS***
PCB_Q *convert_priority(int newPri) {
// if the new priority is not valid (1-3)
if (newPri > 3 || newPri < 0) {
//printf("Invalid priority!!!!!");
return NULL;
}
// if the priority is valid, return the pointer to the priority queue from the array
return pointer_2_RPQ[newPri];
}