-
Notifications
You must be signed in to change notification settings - Fork 0
/
message.c
140 lines (118 loc) · 3.22 KB
/
message.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
#include <stdlib.h>
#include "message.h"
#include "list.h"
#include "process.h"
/*
Message
Manages messages system for simulation
*/
static List * sendQueue;
static List * receiveQueue;
int Message_setup() {
sendQueue = List_create();
if (sendQueue == NULL) {
return 1;
}
receiveQueue = List_create();
if (receiveQueue == NULL) {
return 2;
}
return 0;
}
void Message_free(void * message) {
Message * message_node = message;
free(message_node->msg);
message_node->sender = 0;
message_node->receiver = 0;
free(message_node);
}
List * Message_getQueue(int num) {
switch (num) {
case QUEUE_SEND:
return sendQueue;
case QUEUE_RECEIVE:
return receiveQueue;
default:
return NULL;
}
}
int * Message_getQueueArray(int num) {
List * queue = Message_getQueue(num);
return Process_QueueToArray(queue);
}
int prependMessage(PCB * process, Message * message) {
List * messages = process->messages;
return List_prepend(messages, message);
}
Message * Message_getMessage(PCB * process) {
List * messages = process->messages;
return List_trim(messages);
}
PCB * removeProcess(int num, int pid) {
List * queue = Message_getQueue(num);
List_first(queue);
PCB * process = List_search(queue, Process_comparePid, &pid);
if (process == NULL) {
return NULL;
}
return List_remove(queue);
}
int Message_send(int pid, Message * message) {
if (message == NULL) {
return -1;
}
PCB * senderProcess = Process_getCurrentProcess();
message->sender = senderProcess->PID;
message->receiver = pid;
PCB * receiverProcess = removeProcess(QUEUE_RECEIVE, pid);
if (receiverProcess == NULL) {
receiverProcess = Process_getProcess(pid);
if (receiverProcess == NULL) {
Message_free(message);
return -1;
}
prependMessage(receiverProcess, message);
} else {
receiverProcess->isMessageReceived = true;
prependMessage(receiverProcess, message);
Process_prependToReadyQueue(receiverProcess);
}
if (Process_isInitRunning()) {
return 0;
}
senderProcess->state = PROCESS_BLOCKED;
List_add(sendQueue, senderProcess);
Process_changeRunningProcess();
return senderProcess->PID;
}
int Message_receive() {
PCB * process = Process_getCurrentProcess();
List * messages = process->messages;
if (List_count(messages) == 0) {
if (Process_isInitRunning()) {
return -1;
}
process->state = PROCESS_BLOCKED;
List_prepend(receiveQueue, process);
Process_changeRunningProcess();
} else {
process->isMessageReceived = true;
}
return process->PID;
}
int Message_reply(int pid, Message * message) {
if (message == NULL) {
return -1;
}
PCB * process = removeProcess(QUEUE_SEND, pid);
if (process == NULL) {
Message_free(message);
return -1;
}
message->sender = Process_getCurrentProcess()->PID;
message->receiver = pid;
prependMessage(process, message);
process->isMessageReceived = true;
Process_prependToReadyQueue(process);
return pid;
}