Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/tests/vmalloc/tsharemem.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1999-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#include "vmtest.h"
21
22
/* Test safe concurrent accesses of memory obtained by
23
** either mmap or shmget.
24
**
25
** Written by Kiem-Phong Vo
26
*/
27
28
#ifndef N_PROC
29
#define N_PROC 64
30
#endif
31
32
#define M_SIZE 32 /* max size of an allocated blk */
33
#define N_ALLOC (16*1024) /* #allocations in each process */
34
#define N_FREE (8*1024) /* #frees <= #allocations */
35
36
typedef struct _piece_s
37
{
38
Void_t* addr; /* allocated address */
39
size_t size; /* size to be allocated */
40
int free; /* 1: to be freed */
41
} Piece_t;
42
Piece_t Piece[N_ALLOC];
43
44
static char *Mapstore;
45
static char *Shmstore;
46
47
static int working(char* store, char* type, char* num, ssize_t size)
48
{
49
ssize_t k, f;
50
Vmalloc_t *vm;
51
Vmstat_t vmst;
52
pid_t pid = getpid();
53
54
tinfo("Process %s[pid=%d]: about to open region for %s", num, pid, store);
55
if(!(vm = vmmopen(store, strcmp(type, "map") == 0 ? -1 : 1, size)) )
56
terror("Process %s[pid=%d]: can't open %s allocation region on %s", num, pid, type, store);
57
tinfo("Process %s[pid=%d]: %s region successfully opened for %s", num, pid, type, store);
58
59
for(k = f = 0; k < N_ALLOC; ++k)
60
{ if(!(Piece[k].addr = vmalloc(vm, Piece[k].size)) )
61
terror("Process %s[pid=%d]: vmalloc failed", num, pid);
62
63
if(k < (N_ALLOC-1) && (random()%100) != 0 )
64
continue;
65
66
for(; f <= k; ++f ) /* free anything that should be freed */
67
{ if(!Piece[f].free)
68
continue;
69
if(vmfree(vm, Piece[f].addr) < 0)
70
terror("Process %s[pid=%d]: vmfree failed", num, pid);
71
Piece[f].free = 0;
72
Piece[f].addr = (Void_t*)0;
73
}
74
}
75
76
if(vmstat(vm, &vmst) < 0)
77
terror("Process %s[pid=%d]: vmstat failed", num, pid);
78
tinfo("Process %s[pid=%d]: extent=%d busy=(n=%d,z=%d) free=(n=%d,z=%d)",
79
num, pid, vmst.extent, vmst.n_busy, vmst.s_busy, vmst.n_free, vmst.s_free);
80
81
vmclose(vm);
82
83
return 0;
84
}
85
86
static pid_t makeprocess(char* program, char* store, char* type, int p)
87
{
88
pid_t pid;
89
char num[64], *argv[6];
90
91
sprintf(num, "%d", p);
92
argv[0] = program;
93
argv[1] = "--child";
94
argv[2] = store;
95
argv[3] = type;
96
argv[4] = num;
97
argv[5] = 0;
98
99
if((pid = fork()) < 0 )
100
terror("Could not fork() a subprocess");
101
else if(pid > 0 ) /* return to parent process */
102
return pid;
103
else if(execv(program, argv) < 0 )
104
terror("Process %d[pid=%d]: Could not execv() subprocess", p, pid);
105
else return 0; /* strictly speaking, never reached */
106
}
107
108
tmain()
109
{
110
int test, flag, code = 2;
111
ssize_t k, f, size;
112
pid_t pid;
113
char *store, *type;
114
Vmstat_t vmst;
115
Vmalloc_t *vm;
116
pid_t proc[N_PROC];
117
118
taso(ASO_PROCESS);
119
120
size = 0; /* make up list of pieces for allocation */
121
srandom(0); /* make it easier to debug */
122
for(k = 0; k < N_ALLOC; ++k)
123
{ Piece[k].size = (random()%M_SIZE) + 1;
124
size += Piece[k].size + 16; /* add slop for malloc header */
125
}
126
for(f = 0; f < N_FREE; ) /* set up what should be freed */
127
{ for(k = 0; k < N_ALLOC; ++k)
128
{ if(Piece[k].free == 1)
129
continue;
130
else if(random()%16 == 0)
131
{ Piece[k].free = 1;
132
if((f += 1) >= N_FREE)
133
break;
134
}
135
}
136
}
137
size = 2*size*N_PROC; /* this should be big enough for region */
138
139
if(k = tchild())
140
return working(argv[k], argv[k+1], argv[k+2], size);
141
142
Mapstore = tstfile("map", -1);
143
Shmstore = tstfile("shm", -1);
144
for(test = 0; test < 2; ++test )
145
{ if (test)
146
{ type = "shm";
147
flag = 1;
148
store = Shmstore;
149
}
150
else
151
{ type = "map";
152
flag = -1;
153
store = Mapstore;
154
}
155
tinfo("Testing %s shared memory on %s", type, store);
156
157
(void)unlink(Mapstore); /* remove any existing backing store */
158
(void)unlink(Shmstore); /* remove any existing backing store */
159
160
vm = vmmopen(store, flag, size);
161
if(!vm)
162
terror("%s: Can't open shared region", store);
163
164
for(k = 0; k < N_PROC; ++k)
165
{ tinfo("Creating subprocess %d", k);
166
proc[k] = makeprocess(argv[0], store, type, k);
167
}
168
code = twait(proc, N_PROC);
169
170
k = vmstat(vm, &vmst);
171
vmmrelease(vm, 1); /* clean up file, shmid */
172
vmclose(vm);
173
174
if (code)
175
break;
176
if(k < 0 )
177
terror("%s: Can't get statistics for region", store);
178
tinfo("Statistics: store=%s extent=%d busy=(n=%d,z=%d) free=(n=%d,z=%d)",
179
store, vmst.extent, vmst.n_busy, vmst.s_busy, vmst.n_free, vmst.s_free);
180
if(vmst.n_busy != (N_ALLOC-N_FREE)*N_PROC)
181
terror("%s: Number of busy blocks %d is not the expected %d",
182
store, vmst.n_busy, (N_ALLOC-N_FREE)*N_PROC );
183
184
tinfo("Test for %s share memory passed", type);
185
}
186
187
texit(code);
188
}
189
190