-
Notifications
You must be signed in to change notification settings - Fork 0
/
IPCModule.c
275 lines (237 loc) · 8.77 KB
/
IPCModule.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
/* IPCModule.c
Group Members:
Kevin Thomas, kevin.j.thomas@okstate.edu
Lucas Sager, lucas.sager@okstate.edu
Allison Meredith, allison.meredith@okstate.edu
Group: C
Author: Allison Meredith
Date: 4/10/2024
File Description: Inter-process Communication (IPC) Module:
*/
// shared memory THIS IS THE IPC FILE.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <semaphore.h>
#include <sys/wait.h>
#include "Transaction.h"
#include "Synchronization.h"
#include "Synchronization.c"
#define SHARED_MEMORY_SIZE 100
#define SHM_NAME "/data1_shared_memory"
#define SEM_NAME "/que_semaphore"
int shm_fd;
Transaction *sharedMemory;
SharedQueue *queue;
sem_t *semaphore;
void writeProcess(Transaction transaction) {//value needs to be a struct detailing the process // index needs to be account number.
QueueElement element;
element.data = transaction.index; //trasaction number?
element.pid = getpid();
element.account = transaction.account;
//enqueue(element); //not needed trasaction always comes from read first with the approprate blocking
//printf("I've made it here 0 in pid:%d\n",getpid());
//printf("Enqueued process %d\n",element.pid);
// while(peek() != getpid());
// sem_wait(semaphore);
Transaction temp = sharedMemory[transaction.index];
sharedMemory[transaction.index] = transaction;
//printf("Wrote value %d at index %d, prior value was %d\n", transaction.amount, transaction.index, temp.amount);
sem_post(semaphore);
dequeue(queue);
//printf("Dequeued writing process %d\n", getpid());
}
Transaction readProcess(Transaction transaction) {
QueueElement element;
element.data = transaction.index;
element.pid = getpid();
element.account = transaction.account;
enqueue(element);
//printf("Enqueued process %d\n", getpid());
while(peek() != getpid());
sem_wait(semaphore);
//printf("reading memory for read functions\n"); //debug
int value = sharedMemory[transaction.index].amount;
//printf("Read value %d from index %d\n", value, transaction.index);
//sem_post(semaphore); //don't deque and don't free the semephore need to write to close
//dequeue(queue);
//printf("Dequeued reading process %d\n", getpid());
return sharedMemory[transaction.index];
}
Transaction readquiet(Transaction transaction) { // for printing out nicely the history and final balances.
QueueElement element;
element.data = transaction.index;
element.pid = getpid();
element.account = transaction.account;
enqueue_quiet(element);
//printf("Enqueued process %d\n", getpid());
while(peek() != getpid());
sem_wait(semaphore);
int value = sharedMemory[transaction.index].amount;
//printf("Read value %d from index %d\n", value, transaction.index);
sem_post(semaphore);
dequeue(queue);
//printf("Dequeued reading process %d\n", getpid());
return sharedMemory[transaction.index];
}
Transaction readforce(Transaction transaction) { // for forcing reading where your que is resticted elsewhere
//QueueElement element;
//element.data = transaction.index;
//element.pid = getpid();
//element.account = transaction.account;
//enqueue_quiet(element);
//printf("Enqueued process %d\n", getpid());
//while(peek() != getpid());
//sem_wait(semaphore);
//int value = sharedMemory[transaction.index].amount;
//printf("Read value %d from index %d\n", value, transaction.index);
//sem_post(semaphore);
//dequeue(queue);
//printf("Dequeued reading process %d\n", getpid());
return sharedMemory[transaction.index];
}
int search_queue(int account) {
sem_wait(mutex);
if (queue->front == -1) {
//printf("Queue is empty\n"); //debug
sem_post(mutex);
return 0;
}
int i = queue->front;
do {
if (queue->elements[i].data == account) {
sem_post(mutex);
return 1; // Match found
}
i = (i + 1) % queue->size;
} while (i != (queue->rear + 1) % queue->size);
sem_post(mutex);
return 0; // No match found
}
Transaction transferCheckin(Transaction transaction) {
// printf("doing trasfer checkin\n"); //debug
QueueElement element;
element.data = transaction.index;
element.pid = getpid();
element.account = transaction.account;
enqueue(element);
//printf("Enqueued process %d\n", getpid());
while(peek() != getpid());
//printf("doing trasfer checkin past peek\n");
sem_wait(semaphore);
//printf("doing trasfer checkin past sema\n"); // debug
int value = sharedMemory[transaction.index].amount;
//printf("Read value %d from index %d\n", value, transaction.index);
//sem_post(semaphore); //dont release this is done in the compaion trasfer release
//dequeue(queue);
//printf("Dequeued reading process %d\n", getpid());
return sharedMemory[transaction.index];
}
void transferrelease(Transaction transaction, Transaction transaction2) {//stores both of the values for the trasfer
//QueueElement element;
//element.data = transaction.index; //trasaction number?
//element.pid = getpid();
//element.account = transaction.account;
//enqueue(element);
//printf("I've made it here 0 in pid:%d\n",getpid());
//printf("Enqueued process %d\n",element.pid);
//while(peek() != getpid()); // could be maintained
//sem_wait(semaphore); //expedted we already have the semaphre
//Transaction temp = sharedMemory[transaction.index]; //not needed just for print
sharedMemory[transaction.index] = transaction;
sharedMemory[transaction2.index] = transaction2;
//printf("wrote t2 to index %i\n",transaction2.index); //debug
//printf("Wrote value %d at index %d, prior value was %d\n", transaction.amount, transaction.index, temp.amount);
sem_post(semaphore);
dequeue(queue);
//printf("Dequeued writing process %d\n", getpid());
}
void sharedMemorysetup()
{
create_shared_memory();
init_semaphores();
// Create the shared memory object
shm_fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666);
if (shm_fd == -1) {
perror("shm_open");
exit(1);
}
// Set the size of the shared memory object
ftruncate(shm_fd, SHARED_MEMORY_SIZE * sizeof(Transaction));
// Map the shared memory object into the address space
sharedMemory = (Transaction*)mmap(NULL, SHARED_MEMORY_SIZE * sizeof(Transaction), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (sharedMemory == MAP_FAILED) {
perror("mmap");
exit(1);
}
// Initialize the semaphore
semaphore = sem_open(SEM_NAME, O_CREAT, 0666, 1);
if (semaphore == SEM_FAILED) {
perror("sem_open");
exit(1);
}
}
void sharedMemorycleanup(int pass)
{
cleanup(pass);
// Unmap and close the shared memory object
munmap(sharedMemory, SHARED_MEMORY_SIZE * sizeof(Transaction));
close(shm_fd);
// Remove the shared memory object
shm_unlink(SHM_NAME);
// Close and unlink the semaphore
sem_close(semaphore);
sem_unlink(SEM_NAME);
}
// int main() {
// /*
// //cleanup(0); //cleanup if you have issues with closing
// // munmap(sharedMemory, SHARED_MEMORY_SIZE * sizeof(Transaction));
// //close(shm_fd);
// // Remove the shared memory object
// shm_unlink(SHM_NAME);
// // Close and unlink the semaphore
// sem_close(semaphore);
// sem_unlink(SEM_NAME);
// // Remove the shared memory object
// shm_unlink(SHM_NAME);
// */
// sharedMemorysetup();
// int index = rand() % SHARED_MEMORY_SIZE;
// int value;
// Transaction transaction;
// transaction.index = index;
// // Create a child process
// pid_t pid = fork();
// if(pid == 0) pid = fork();
// if(pid == 0) pid = fork();
// if (pid == -1) {
// perror("fork");
// exit(1);
// } else if (pid == 0) {
// // Child process
// int iterations = 0;
// while (iterations < 10) {
// readProcess(transaction);
// iterations++;
// }
// exit(0);
// } else {
// // Parent process
// int iterations = 0;
// while (iterations < 10) {
// value = rand() % 100;
// transaction.amount = value;
// writeProcess(transaction);
// iterations++;
// }
// // Wait for the child process to finish
// wait(NULL);
// wait(NULL);
// wait(NULL);
// }
// sharedMemorycleanup(1);
// return 0;
// }