-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSHMSEM1.c
More file actions
132 lines (110 loc) · 3.6 KB
/
Copy pathSHMSEM1.c
File metadata and controls
132 lines (110 loc) · 3.6 KB
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
// EE4273 Sample Source Code. SHMSEM1.C
//
// This source code implements a single process that benchmarks the time
// it takes to update a block of shared memory that is protected with a
// POSIX .4 semaphore (as a means for mutual exclusion). There is only
// one process and we are benchmarking the cost of mutual exclusion. In
// this case the majority of accesses are uncontested. The program may
// be run with the semaphore locks included and then excluded, (i.e.,
// "commented out") so the resulting semaphore overhead may be measured.
//
// The time measurements are made using the following procedure. The
// shared memory is updated continually together with the number of
// iterations. An ALARM is set to generate a signal (interrupt) after a
// fixed interval of time expires. The signal handler displays the value
// of the count. Perform this test for two cases: 1) when semaphore
// locks are included and 2) not included.
//
// Alternatively you could fork a child and run two processes at once
// benchmarking total throughput.
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <signal.h>
#include <math.h>
#include <float.h>
#define SHMNAME "/my_shm"
#define SEMNAME "/my_sem"
#define TRUE 1
#define TIME_PERIOD 5
#define SIZE 1
int N = 0;
int nbytes;
void timer_expired(int called_via_signal)
{
printf("%d iterations in %i seconds\n", N, TIME_PERIOD);
exit(0);
}
main()
{
extern void timer_expired();
int i, d, nbytes, cps;
char *addr;
struct sigaction sa;
// The following structure is overlaid on the shared memory.
struct phu {
sem_t s;
char beginning_of_data[SIZE];
} *p;
nbytes = sizeof(*p);
// Set up signal handler.
sa.sa_handler = timer_expired;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGALRM, &sa, NULL) < 0) {
perror("sigaction SIGALRM.\n");
exit(1);
}
// Create shared memory region.
if ((d = shm_open(SHMNAME, O_RDWR|O_CREAT|O_EXCL, 0666)) == -1) {
printf("Unable to open shared memory.\n");
exit(1);
}
if (ftruncate(d, nbytes) != 0) {
close(d);
shm_unlink(SHMNAME);
printf("Unable to truncate.\n");
exit(1);
}
p = (struct phu *)mmap(NULL, nbytes, PROT_READ|PROT_WRITE, MAP_SHARED, d,
0);
if(p == (struct phu *) -1) {
close(d);
printf("Unable to mmap.\n");
exit(1);
}
shm_unlink(SHMNAME);
// Create semaphore.
if (sem_init(&p->s, 1, 1) == -1) {
printf("Sema init ERROR = %i.\n", errno);
exit(1);
}
// Begin test - repeatedly acquire mutual exclusion, write to area and
// release mutual exclusion.
addr = p->beginning_of_data;
N = 0;
alarm(TIME_PERIOD);
while ( TRUE ) {
// Acquire parents lock.
if (sem_wait(&p->s) == -1) {
printf("Sem_wait error.\n");
}
// Store data in shared memory.
for (i = 0; i < SIZE; i++) {
addr[i] = 'A';
// printf("i = %d. N = %d.\n", i, N);
// Uncomment this line to debug
}
// Release parents lock.
if (sem_post(&p->s) == -1) {
printf("Sem_post error.\n");
}
N++;
}
}