-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsharedmem_semaphore.c
154 lines (125 loc) · 3.47 KB
/
sharedmem_semaphore.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
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/sem.h>
#define SIZE 16
int main(int argc, char *argv[])
{
int status;
long int i, loop, temp, *sharedMemoryPointer;
int sharedMemoryID;
pid_t pid;
loop = atoi(argv[1]);
int semID;
struct sembuf p = { 0, -1, SEM_UNDO};
struct sembuf v = { 0, +1, SEM_UNDO};
sharedMemoryID = shmget(IPC_PRIVATE, SIZE, IPC_CREAT | S_IRUSR | S_IWUSR);
if(sharedMemoryID < 0)
{
perror("Unable to obtain shared memory\n");
exit(EXIT_FAILURE);
}
sharedMemoryPointer = shmat(sharedMemoryID, 0, 0);
if(sharedMemoryPointer == (void *) -1)
{
perror ("Unable to attach\n");
exit (1);
}
/* create a new semaphore set for use by parent and child processes */
semID = semget(IPC_PRIVATE, 1, 00600);
if (semID < 0)
{
perror("semget: failed to create\n");
exit(EXIT_FAILURE);
}
/* initialize the semaphore set referenced by the previosly obtained semID handle */
if (semctl(semID, 0, SETVAL, 1) < 0)
{
perror("semctl: initialiation failure\n");
exit(EXIT_FAILURE);
}
sharedMemoryPointer[0] = 0;
sharedMemoryPointer[1] = 1;
pid = fork();
if(pid < 0)
{
printf("Fork failed\n");
}
if(pid == 0)
{
// Child
for(i = 0; i < loop; i++)
{
// sem wait
if (semop(semID, &p, 1) < 0)
{
perror("semop: wait failed\n");
exit(EXIT_FAILURE);
}
// critical section
// swap the contents of sharedMemoryPointer[0] and sharedMemoryPointer[1]
temp = sharedMemoryPointer[0];
sharedMemoryPointer[0] = sharedMemoryPointer[1];
sharedMemoryPointer[1] = temp;
// sem signal
if (semop(semID, &v, 1) < 0)
{
perror("semop: wait failed\n");
exit(EXIT_FAILURE);
}
}
if(shmdt(sharedMemoryPointer) < 0)
{
perror ("Unable to detach\n");
exit (1);
}
exit(0);
}
else
{
for(i = 0; i < loop; i++)
{
// sem wait
if (semop(semID, &p, 1) < 0)
{
perror("semop: wait failed\n");
exit(EXIT_FAILURE);
}
// critical section
// swap the contents of sharedMemoryPointer[0] and sharedMemoryPointer[1]
temp = sharedMemoryPointer[1];
sharedMemoryPointer[1] = sharedMemoryPointer[0];
sharedMemoryPointer[0] = temp;
// sem signal
if (semop(semID, &v, 1) < 0)
{
perror("semop: wait failed\n");
exit(EXIT_FAILURE);
}
}
}
wait(&status);
printf("Values: %li\t%li\n", sharedMemoryPointer[0], sharedMemoryPointer[1]);
/* remove the semaphore referenced by semID */
if (semctl(semID, 0, IPC_RMID) < 0)
{
perror("Unable to remove semaphore\n");
exit(EXIT_FAILURE);
}
if(shmdt(sharedMemoryPointer) < 0)
{
perror("Unable to detach\n");
exit(EXIT_FAILURE);
}
if(shmctl(sharedMemoryID, IPC_RMID, 0) < 0)
{
perror("Unable to deallocate\n");
exit(EXIT_FAILURE);
}
return 0;
}