1*49cdfc7eSAndroid Build Coastguard Worker /*****************************************************************************/
2*49cdfc7eSAndroid Build Coastguard Worker /* */
3*49cdfc7eSAndroid Build Coastguard Worker /* Copyright (c) International Business Machines Corp., 2001 */
4*49cdfc7eSAndroid Build Coastguard Worker /* */
5*49cdfc7eSAndroid Build Coastguard Worker /* This program is free software; you can redistribute it and/or modify */
6*49cdfc7eSAndroid Build Coastguard Worker /* it under the terms of the GNU General Public License as published by */
7*49cdfc7eSAndroid Build Coastguard Worker /* the Free Software Foundation; either version 2 of the License, or */
8*49cdfc7eSAndroid Build Coastguard Worker /* (at your option) any later version. */
9*49cdfc7eSAndroid Build Coastguard Worker /* */
10*49cdfc7eSAndroid Build Coastguard Worker /* This program is distributed in the hope that it will be useful, */
11*49cdfc7eSAndroid Build Coastguard Worker /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
12*49cdfc7eSAndroid Build Coastguard Worker /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
13*49cdfc7eSAndroid Build Coastguard Worker /* the GNU General Public License for more details. */
14*49cdfc7eSAndroid Build Coastguard Worker /* */
15*49cdfc7eSAndroid Build Coastguard Worker /* You should have received a copy of the GNU General Public License */
16*49cdfc7eSAndroid Build Coastguard Worker /* along with this program; if not, write to the Free Software */
17*49cdfc7eSAndroid Build Coastguard Worker /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
18*49cdfc7eSAndroid Build Coastguard Worker /* */
19*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
20*49cdfc7eSAndroid Build Coastguard Worker
21*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
22*49cdfc7eSAndroid Build Coastguard Worker /* */
23*49cdfc7eSAndroid Build Coastguard Worker /* History: July - 16 - 2001 Created by Manoj Iyer, IBM Austin TX. */
24*49cdfc7eSAndroid Build Coastguard Worker /* email:[email protected] */
25*49cdfc7eSAndroid Build Coastguard Worker /* */
26*49cdfc7eSAndroid Build Coastguard Worker /* July - 30 - 2001 Modified - Added function write_to_mem. */
27*49cdfc7eSAndroid Build Coastguard Worker /* */
28*49cdfc7eSAndroid Build Coastguard Worker /* Aug - 14 - 2001 Modified - Added code to remove the shared */
29*49cdfc7eSAndroid Build Coastguard Worker /* memory segment ids. */
30*49cdfc7eSAndroid Build Coastguard Worker /* */
31*49cdfc7eSAndroid Build Coastguard Worker /* Aug - 15 - 2001 Modified - Added for loop to run the test */
32*49cdfc7eSAndroid Build Coastguard Worker /* repeatedly. */
33*49cdfc7eSAndroid Build Coastguard Worker /* */
34*49cdfc7eSAndroid Build Coastguard Worker /* Oct - 22 - 2001 Modified - Fixed bad code in main(). */
35*49cdfc7eSAndroid Build Coastguard Worker /* removed stray code and options. Pthread_join */
36*49cdfc7eSAndroid Build Coastguard Worker /* part fixed, older version was completely bad */
37*49cdfc7eSAndroid Build Coastguard Worker /* */
38*49cdfc7eSAndroid Build Coastguard Worker /* Nov - 09 - 2001 Modified - Removed compile errors */
39*49cdfc7eSAndroid Build Coastguard Worker /* - added missing header file string.h */
40*49cdfc7eSAndroid Build Coastguard Worker /* - removed unused variables. */
41*49cdfc7eSAndroid Build Coastguard Worker /* - made read_ndx and write_ndx static variable*/
42*49cdfc7eSAndroid Build Coastguard Worker /* */
43*49cdfc7eSAndroid Build Coastguard Worker /* Nov - 91 - 2001 Modified - Changed scope of status variable */
44*49cdfc7eSAndroid Build Coastguard Worker /* - change the status of status variable from */
45*49cdfc7eSAndroid Build Coastguard Worker /* int *status to int status[1] */
46*49cdfc7eSAndroid Build Coastguard Worker /* */
47*49cdfc7eSAndroid Build Coastguard Worker /* File: shmat1.c */
48*49cdfc7eSAndroid Build Coastguard Worker /* */
49*49cdfc7eSAndroid Build Coastguard Worker /* Description: Test the LINUX memory manager. The program is aimed at */
50*49cdfc7eSAndroid Build Coastguard Worker /* stressing the memory manager by repeaded shmat/write/read/ */
51*49cdfc7eSAndroid Build Coastguard Worker /* shmatd of file/memory of random size (maximum 1000 * 4096) */
52*49cdfc7eSAndroid Build Coastguard Worker /* done by multiple processes. */
53*49cdfc7eSAndroid Build Coastguard Worker /* */
54*49cdfc7eSAndroid Build Coastguard Worker /* Create a file of random size upto 1000 times 4096. */
55*49cdfc7eSAndroid Build Coastguard Worker /* process X shmats and un-shmats this file in memory. */
56*49cdfc7eSAndroid Build Coastguard Worker /* process Y changes content of the file to Y, ie writes to it. */
57*49cdfc7eSAndroid Build Coastguard Worker /* process Z reads from this memory location, and varifies the */
58*49cdfc7eSAndroid Build Coastguard Worker /* the content of the file. */
59*49cdfc7eSAndroid Build Coastguard Worker /* */
60*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
61*49cdfc7eSAndroid Build Coastguard Worker
62*49cdfc7eSAndroid Build Coastguard Worker /* Include Files */
63*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h> /* definitions for standard I/O */
64*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h> /* required by usleep() */
65*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h> /* definitions for errno */
66*49cdfc7eSAndroid Build Coastguard Worker #include <sched.h> /* definitions for sched_yield() */
67*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h> /* definitions for WEXIT macros */
68*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h> /* required by sigaction & sig handling fncs */
69*49cdfc7eSAndroid Build Coastguard Worker #include <sys/time.h> /* definitions of settimer() */
70*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h> /* definitions of itimer structure */
71*49cdfc7eSAndroid Build Coastguard Worker #include <pthread.h> /* definitions for pthread_create etc */
72*49cdfc7eSAndroid Build Coastguard Worker #include <setjmp.h> /* required by setjmp longjmp */
73*49cdfc7eSAndroid Build Coastguard Worker #include <sys/ucontext.h> /* required by the signal handler */
74*49cdfc7eSAndroid Build Coastguard Worker #include <sys/ipc.h> /* required by shmat shmget etc */
75*49cdfc7eSAndroid Build Coastguard Worker #include <sys/shm.h> /* required by shmat shmget etc */
76*49cdfc7eSAndroid Build Coastguard Worker #include <string.h> /* required by strncmp */
77*49cdfc7eSAndroid Build Coastguard Worker
78*49cdfc7eSAndroid Build Coastguard Worker /* Defines */
79*49cdfc7eSAndroid Build Coastguard Worker #ifndef TRUE
80*49cdfc7eSAndroid Build Coastguard Worker #define TRUE 1
81*49cdfc7eSAndroid Build Coastguard Worker #endif
82*49cdfc7eSAndroid Build Coastguard Worker #ifndef FALSE
83*49cdfc7eSAndroid Build Coastguard Worker #define FALSE 0
84*49cdfc7eSAndroid Build Coastguard Worker #endif
85*49cdfc7eSAndroid Build Coastguard Worker #define prtln() printf(" I AM HERE ==> %s %d\n", __FILE__, __LINE__);
86*49cdfc7eSAndroid Build Coastguard Worker
87*49cdfc7eSAndroid Build Coastguard Worker #define STR_SHMAT " "
88*49cdfc7eSAndroid Build Coastguard Worker #define STR_WRITER " "
89*49cdfc7eSAndroid Build Coastguard Worker #define STR_READER " "
90*49cdfc7eSAndroid Build Coastguard Worker
91*49cdfc7eSAndroid Build Coastguard Worker /* Global Variables */
92*49cdfc7eSAndroid Build Coastguard Worker void *map_address; /* pointer to file in memory */
93*49cdfc7eSAndroid Build Coastguard Worker sigjmp_buf jmpbuf; /* argument to setjmp and longjmp */
94*49cdfc7eSAndroid Build Coastguard Worker int fsize; /* size of the file to be created. */
95*49cdfc7eSAndroid Build Coastguard Worker int done_shmat = 0; /* disallow read and writes before shmat */
96*49cdfc7eSAndroid Build Coastguard Worker
97*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
98*49cdfc7eSAndroid Build Coastguard Worker /* */
99*49cdfc7eSAndroid Build Coastguard Worker /* Function: sig_handler */
100*49cdfc7eSAndroid Build Coastguard Worker /* */
101*49cdfc7eSAndroid Build Coastguard Worker /* Description: handle SIGALRM raised by set_timer(), SIGALRM is raised when */
102*49cdfc7eSAndroid Build Coastguard Worker /* the timer expires. If any other signal is received exit the */
103*49cdfc7eSAndroid Build Coastguard Worker /* test. */
104*49cdfc7eSAndroid Build Coastguard Worker /* */
105*49cdfc7eSAndroid Build Coastguard Worker /* Input: signal - signal number, intrested in SIGALRM! */
106*49cdfc7eSAndroid Build Coastguard Worker /* */
107*49cdfc7eSAndroid Build Coastguard Worker /* Return: exit -1 if unexpected signal is received */
108*49cdfc7eSAndroid Build Coastguard Worker /* exit 0 if SIGALRM is received */
109*49cdfc7eSAndroid Build Coastguard Worker /* */
110*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
sig_handler(int signal,int code,ucontext_t * ut)111*49cdfc7eSAndroid Build Coastguard Worker static void sig_handler(int signal, /* signal number, set to handle SIGALRM */
112*49cdfc7eSAndroid Build Coastguard Worker int code, ucontext_t *ut)
113*49cdfc7eSAndroid Build Coastguard Worker { /* contains pointer to sigcontext structure */
114*49cdfc7eSAndroid Build Coastguard Worker #ifdef __i386__
115*49cdfc7eSAndroid Build Coastguard Worker unsigned long except; /* exception type. */
116*49cdfc7eSAndroid Build Coastguard Worker int ret = 0; /* exit code from signal handler. */
117*49cdfc7eSAndroid Build Coastguard Worker struct sigcontext *scp = /* pointer to sigcontext structure */
118*49cdfc7eSAndroid Build Coastguard Worker (struct sigcontext *)&ut->uc_mcontext;
119*49cdfc7eSAndroid Build Coastguard Worker #endif
120*49cdfc7eSAndroid Build Coastguard Worker
121*49cdfc7eSAndroid Build Coastguard Worker if (signal == SIGALRM) {
122*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout, "Test ended, success\n");
123*49cdfc7eSAndroid Build Coastguard Worker exit(0);
124*49cdfc7eSAndroid Build Coastguard Worker }
125*49cdfc7eSAndroid Build Coastguard Worker #ifdef __i386__
126*49cdfc7eSAndroid Build Coastguard Worker else {
127*49cdfc7eSAndroid Build Coastguard Worker except = scp->trapno;
128*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "signal caught - [%d] ", signal);
129*49cdfc7eSAndroid Build Coastguard Worker }
130*49cdfc7eSAndroid Build Coastguard Worker
131*49cdfc7eSAndroid Build Coastguard Worker switch (except) {
132*49cdfc7eSAndroid Build Coastguard Worker case 10:
133*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
134*49cdfc7eSAndroid Build Coastguard Worker "Exception - invalid TSS, exception #[%ld]\n", except);
135*49cdfc7eSAndroid Build Coastguard Worker break;
136*49cdfc7eSAndroid Build Coastguard Worker case 11:
137*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
138*49cdfc7eSAndroid Build Coastguard Worker "Exception - segment not present, exception #[%ld]\n",
139*49cdfc7eSAndroid Build Coastguard Worker except);
140*49cdfc7eSAndroid Build Coastguard Worker break;
141*49cdfc7eSAndroid Build Coastguard Worker case 12:
142*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
143*49cdfc7eSAndroid Build Coastguard Worker "Exception - stack segment not present, exception #[%ld]\n",
144*49cdfc7eSAndroid Build Coastguard Worker except);
145*49cdfc7eSAndroid Build Coastguard Worker break;
146*49cdfc7eSAndroid Build Coastguard Worker case 13:
147*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
148*49cdfc7eSAndroid Build Coastguard Worker "Exception - general protection, exception #[%ld]\n",
149*49cdfc7eSAndroid Build Coastguard Worker except);
150*49cdfc7eSAndroid Build Coastguard Worker break;
151*49cdfc7eSAndroid Build Coastguard Worker case 14:
152*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
153*49cdfc7eSAndroid Build Coastguard Worker "Exception - page fault, exception #[%ld]\n", except);
154*49cdfc7eSAndroid Build Coastguard Worker ret = 1;
155*49cdfc7eSAndroid Build Coastguard Worker break;
156*49cdfc7eSAndroid Build Coastguard Worker default:
157*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
158*49cdfc7eSAndroid Build Coastguard Worker "Exception type not handled... unknown exception #[%ld]\n",
159*49cdfc7eSAndroid Build Coastguard Worker except);
160*49cdfc7eSAndroid Build Coastguard Worker break;
161*49cdfc7eSAndroid Build Coastguard Worker }
162*49cdfc7eSAndroid Build Coastguard Worker
163*49cdfc7eSAndroid Build Coastguard Worker if (ret) {
164*49cdfc7eSAndroid Build Coastguard Worker if (scp->edi == (int)map_address) {
165*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout,
166*49cdfc7eSAndroid Build Coastguard Worker "page fault at [%#lx] - ignore\n", scp->edi);
167*49cdfc7eSAndroid Build Coastguard Worker siglongjmp(jmpbuf, 1);
168*49cdfc7eSAndroid Build Coastguard Worker } else if (scp->esi == (int)map_address) {
169*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout,
170*49cdfc7eSAndroid Build Coastguard Worker "page fault at [%#lx] - ignore\n", scp->esi);
171*49cdfc7eSAndroid Build Coastguard Worker siglongjmp(jmpbuf, 1);
172*49cdfc7eSAndroid Build Coastguard Worker } else {
173*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
174*49cdfc7eSAndroid Build Coastguard Worker "address at which sigfault occured: [%lx]\n"
175*49cdfc7eSAndroid Build Coastguard Worker "address at which sigfault occured: [%lx]\n"
176*49cdfc7eSAndroid Build Coastguard Worker "address at which memory was shmat: [%p]\n",
177*49cdfc7eSAndroid Build Coastguard Worker (unsigned long)scp->edi,
178*49cdfc7eSAndroid Build Coastguard Worker (unsigned long)scp->esi, map_address);
179*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "bad page fault exit test\n");
180*49cdfc7eSAndroid Build Coastguard Worker exit(-1);
181*49cdfc7eSAndroid Build Coastguard Worker }
182*49cdfc7eSAndroid Build Coastguard Worker } else
183*49cdfc7eSAndroid Build Coastguard Worker exit(-1);
184*49cdfc7eSAndroid Build Coastguard Worker #else
185*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "caught signal %d -- exiting.\n", signal);
186*49cdfc7eSAndroid Build Coastguard Worker exit(-1);
187*49cdfc7eSAndroid Build Coastguard Worker #endif
188*49cdfc7eSAndroid Build Coastguard Worker }
189*49cdfc7eSAndroid Build Coastguard Worker
190*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************//* */
191*49cdfc7eSAndroid Build Coastguard Worker /* Function: usage */
192*49cdfc7eSAndroid Build Coastguard Worker /* */
193*49cdfc7eSAndroid Build Coastguard Worker /* Description: Print the usage message. */
194*49cdfc7eSAndroid Build Coastguard Worker /* */
195*49cdfc7eSAndroid Build Coastguard Worker /* Return: exits with -1 */
196*49cdfc7eSAndroid Build Coastguard Worker /* */
197*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
usage(char * progname)198*49cdfc7eSAndroid Build Coastguard Worker static void usage(char *progname)
199*49cdfc7eSAndroid Build Coastguard Worker { /* name of this program */
200*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
201*49cdfc7eSAndroid Build Coastguard Worker "Usage: %s -h -l -x\n"
202*49cdfc7eSAndroid Build Coastguard Worker "\t -h help, usage message.\n"
203*49cdfc7eSAndroid Build Coastguard Worker "\t -l number of map - write - unmap. default: 1000\n"
204*49cdfc7eSAndroid Build Coastguard Worker "\t -x time for which test is to be run. default: 24 Hrs\n",
205*49cdfc7eSAndroid Build Coastguard Worker progname);
206*49cdfc7eSAndroid Build Coastguard Worker exit(-1);
207*49cdfc7eSAndroid Build Coastguard Worker }
208*49cdfc7eSAndroid Build Coastguard Worker
209*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
210*49cdfc7eSAndroid Build Coastguard Worker /* */
211*49cdfc7eSAndroid Build Coastguard Worker /* Function: shmat_shmdt */
212*49cdfc7eSAndroid Build Coastguard Worker /* */
213*49cdfc7eSAndroid Build Coastguard Worker /* Description: Thread X function. */
214*49cdfc7eSAndroid Build Coastguard Worker /* shmat a random size file and shm-detach this file, this is */
215*49cdfc7eSAndroid Build Coastguard Worker /* done for user defined number of times. */
216*49cdfc7eSAndroid Build Coastguard Worker /* */
217*49cdfc7eSAndroid Build Coastguard Worker /* Input: arg[0] number of times shmat shmdt is done */
218*49cdfc7eSAndroid Build Coastguard Worker /* */
219*49cdfc7eSAndroid Build Coastguard Worker /* Return: -1 on error. */
220*49cdfc7eSAndroid Build Coastguard Worker /* 0 on errorless completion of the loop. */
221*49cdfc7eSAndroid Build Coastguard Worker /* */
222*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
shmat_shmdt(void * args)223*49cdfc7eSAndroid Build Coastguard Worker void *shmat_shmdt(void *args)
224*49cdfc7eSAndroid Build Coastguard Worker { /* arguments to the thread X function. */
225*49cdfc7eSAndroid Build Coastguard Worker int shm_ndx = 0; /* index to number of shmat/shmdt */
226*49cdfc7eSAndroid Build Coastguard Worker key_t shmkey = 0; /* IPC_PRIVATE (key for shmget) */
227*49cdfc7eSAndroid Build Coastguard Worker int shmid; /* shared memory id */
228*49cdfc7eSAndroid Build Coastguard Worker long *locargs = /* local pointer to arguments */
229*49cdfc7eSAndroid Build Coastguard Worker (long *)args;
230*49cdfc7eSAndroid Build Coastguard Worker
231*49cdfc7eSAndroid Build Coastguard Worker while (shm_ndx++ < (int)locargs[0]) {
232*49cdfc7eSAndroid Build Coastguard Worker /* put the reader and writer threads to sleep */
233*49cdfc7eSAndroid Build Coastguard Worker done_shmat = 0;
234*49cdfc7eSAndroid Build Coastguard Worker
235*49cdfc7eSAndroid Build Coastguard Worker /* generate a random size, we will ask for this amount of shared mem */
236*49cdfc7eSAndroid Build Coastguard Worker srand(time(NULL) % 100);
237*49cdfc7eSAndroid Build Coastguard Worker fsize = (1 + (int)(1000.0 * rand() / (RAND_MAX + 1.0))) * 4096;
238*49cdfc7eSAndroid Build Coastguard Worker
239*49cdfc7eSAndroid Build Coastguard Worker if ((shmid = shmget(shmkey, fsize, IPC_CREAT | 0666)) == -1) {
240*49cdfc7eSAndroid Build Coastguard Worker perror("shmat_shmdt(): shmget()");
241*49cdfc7eSAndroid Build Coastguard Worker pthread_exit((void *)-1);
242*49cdfc7eSAndroid Build Coastguard Worker } else {
243*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout,
244*49cdfc7eSAndroid Build Coastguard Worker "%s[%#lx]: shmget(): success, got segment of size %d\n",
245*49cdfc7eSAndroid Build Coastguard Worker STR_SHMAT, pthread_self(), fsize);
246*49cdfc7eSAndroid Build Coastguard Worker }
247*49cdfc7eSAndroid Build Coastguard Worker
248*49cdfc7eSAndroid Build Coastguard Worker if ((map_address = shmat(shmid, NULL, 0))
249*49cdfc7eSAndroid Build Coastguard Worker == (void *)-1) {
250*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "shmat_shmat(): map address = %p\n",
251*49cdfc7eSAndroid Build Coastguard Worker map_address);
252*49cdfc7eSAndroid Build Coastguard Worker perror("shmat_shmdt(): shmat()");
253*49cdfc7eSAndroid Build Coastguard Worker pthread_exit((void *)-1);
254*49cdfc7eSAndroid Build Coastguard Worker } else {
255*49cdfc7eSAndroid Build Coastguard Worker /* Wake up the reader and writer threads. */
256*49cdfc7eSAndroid Build Coastguard Worker /* Write 'X' into map_address. We are not sure about
257*49cdfc7eSAndroid Build Coastguard Worker reader/writer interleaving. So the reader may expect
258*49cdfc7eSAndroid Build Coastguard Worker to find 'X' or 'Y'
259*49cdfc7eSAndroid Build Coastguard Worker */
260*49cdfc7eSAndroid Build Coastguard Worker memset(map_address, 'X', 1);
261*49cdfc7eSAndroid Build Coastguard Worker done_shmat = 1;
262*49cdfc7eSAndroid Build Coastguard Worker usleep(0);
263*49cdfc7eSAndroid Build Coastguard Worker }
264*49cdfc7eSAndroid Build Coastguard Worker
265*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout, "%s[%#lx]: Map address = %p\n",
266*49cdfc7eSAndroid Build Coastguard Worker STR_SHMAT, pthread_self(), map_address);
267*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout,
268*49cdfc7eSAndroid Build Coastguard Worker "%s[%#lx]: Num iter: [%d] Total Num Iter: [%d]\n",
269*49cdfc7eSAndroid Build Coastguard Worker STR_SHMAT, pthread_self(), shm_ndx, (int)locargs[0]);
270*49cdfc7eSAndroid Build Coastguard Worker usleep(0);
271*49cdfc7eSAndroid Build Coastguard Worker sched_yield();
272*49cdfc7eSAndroid Build Coastguard Worker
273*49cdfc7eSAndroid Build Coastguard Worker /* put the threads to sleep before un-shmatting */
274*49cdfc7eSAndroid Build Coastguard Worker done_shmat = 0;
275*49cdfc7eSAndroid Build Coastguard Worker if (shmdt((void *)map_address) == -1) {
276*49cdfc7eSAndroid Build Coastguard Worker perror("shmat_shmdt(): shmdt()");
277*49cdfc7eSAndroid Build Coastguard Worker pthread_exit((void *)-1);
278*49cdfc7eSAndroid Build Coastguard Worker }
279*49cdfc7eSAndroid Build Coastguard Worker if (shmctl(shmid, IPC_RMID, NULL)) {
280*49cdfc7eSAndroid Build Coastguard Worker perror("shmat_shmdt(): shmctl()");
281*49cdfc7eSAndroid Build Coastguard Worker pthread_exit((void *)-1);
282*49cdfc7eSAndroid Build Coastguard Worker }
283*49cdfc7eSAndroid Build Coastguard Worker }
284*49cdfc7eSAndroid Build Coastguard Worker pthread_exit(NULL);
285*49cdfc7eSAndroid Build Coastguard Worker }
286*49cdfc7eSAndroid Build Coastguard Worker
287*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
288*49cdfc7eSAndroid Build Coastguard Worker /* */
289*49cdfc7eSAndroid Build Coastguard Worker /* Function: write_to_mem */
290*49cdfc7eSAndroid Build Coastguard Worker /* */
291*49cdfc7eSAndroid Build Coastguard Worker /* Description: Thread Y function. */
292*49cdfc7eSAndroid Build Coastguard Worker /* Writes 'Y' to the memory location shmat by process X. */
293*49cdfc7eSAndroid Build Coastguard Worker /* */
294*49cdfc7eSAndroid Build Coastguard Worker /* Input: arg[0] number of times write is performed */
295*49cdfc7eSAndroid Build Coastguard Worker /* */
296*49cdfc7eSAndroid Build Coastguard Worker /* Return: -1 on error. */
297*49cdfc7eSAndroid Build Coastguard Worker /* 0 on errorless completion of the loop. */
298*49cdfc7eSAndroid Build Coastguard Worker /* */
299*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
write_to_mem(void * args)300*49cdfc7eSAndroid Build Coastguard Worker void *write_to_mem(void *args)
301*49cdfc7eSAndroid Build Coastguard Worker {
302*49cdfc7eSAndroid Build Coastguard Worker static int write_ndx = 0; /* index to the number of writes to perform */
303*49cdfc7eSAndroid Build Coastguard Worker long *locargs = /* local pointer to the arguments */
304*49cdfc7eSAndroid Build Coastguard Worker (long *)args;
305*49cdfc7eSAndroid Build Coastguard Worker
306*49cdfc7eSAndroid Build Coastguard Worker while (write_ndx++ < (int)locargs[0]) {
307*49cdfc7eSAndroid Build Coastguard Worker /* wait for the thread to shmat, and dont sleep on the processor. */
308*49cdfc7eSAndroid Build Coastguard Worker while (!done_shmat)
309*49cdfc7eSAndroid Build Coastguard Worker usleep(0);
310*49cdfc7eSAndroid Build Coastguard Worker
311*49cdfc7eSAndroid Build Coastguard Worker if (sigsetjmp(jmpbuf, 1) == 1) {
312*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout,
313*49cdfc7eSAndroid Build Coastguard Worker "page fault ocurred due a write after an shmdt from [%p]\n",
314*49cdfc7eSAndroid Build Coastguard Worker map_address);
315*49cdfc7eSAndroid Build Coastguard Worker }
316*49cdfc7eSAndroid Build Coastguard Worker
317*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout,
318*49cdfc7eSAndroid Build Coastguard Worker "%s[%#lx]: write_to_mem(): memory address: [%p]\n",
319*49cdfc7eSAndroid Build Coastguard Worker STR_WRITER, pthread_self(), map_address);
320*49cdfc7eSAndroid Build Coastguard Worker memset(map_address, 'Y', 1);
321*49cdfc7eSAndroid Build Coastguard Worker usleep(1);
322*49cdfc7eSAndroid Build Coastguard Worker sched_yield();
323*49cdfc7eSAndroid Build Coastguard Worker }
324*49cdfc7eSAndroid Build Coastguard Worker pthread_exit(NULL);
325*49cdfc7eSAndroid Build Coastguard Worker }
326*49cdfc7eSAndroid Build Coastguard Worker
327*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
328*49cdfc7eSAndroid Build Coastguard Worker /* */
329*49cdfc7eSAndroid Build Coastguard Worker /* Function: read_from_mem */
330*49cdfc7eSAndroid Build Coastguard Worker /* */
331*49cdfc7eSAndroid Build Coastguard Worker /* Description: Thread Z function. */
332*49cdfc7eSAndroid Build Coastguard Worker /* reads from the memory location shmat by process X. */
333*49cdfc7eSAndroid Build Coastguard Worker /* */
334*49cdfc7eSAndroid Build Coastguard Worker /* Input: arg[0] number of times read is performed */
335*49cdfc7eSAndroid Build Coastguard Worker /* */
336*49cdfc7eSAndroid Build Coastguard Worker /* Return: -1 on error. */
337*49cdfc7eSAndroid Build Coastguard Worker /* 0 on errorless completion of the loop. */
338*49cdfc7eSAndroid Build Coastguard Worker /* */
339*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
read_from_mem(void * args)340*49cdfc7eSAndroid Build Coastguard Worker void *read_from_mem(void *args)
341*49cdfc7eSAndroid Build Coastguard Worker {
342*49cdfc7eSAndroid Build Coastguard Worker static int read_ndx = 0; /* index to the number of writes to perform */
343*49cdfc7eSAndroid Build Coastguard Worker long *locargs = /* local pointer to the arguments */
344*49cdfc7eSAndroid Build Coastguard Worker (long *)args;
345*49cdfc7eSAndroid Build Coastguard Worker
346*49cdfc7eSAndroid Build Coastguard Worker while (read_ndx++ < (int)locargs[0]) {
347*49cdfc7eSAndroid Build Coastguard Worker /* wait for the shmat to happen */
348*49cdfc7eSAndroid Build Coastguard Worker while (!done_shmat)
349*49cdfc7eSAndroid Build Coastguard Worker usleep(0);
350*49cdfc7eSAndroid Build Coastguard Worker
351*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout,
352*49cdfc7eSAndroid Build Coastguard Worker "%s[%#lx]: read_from_mem(): memory address: [%p]\n",
353*49cdfc7eSAndroid Build Coastguard Worker STR_READER, pthread_self(), map_address);
354*49cdfc7eSAndroid Build Coastguard Worker if (sigsetjmp(jmpbuf, 1) == 1) {
355*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout,
356*49cdfc7eSAndroid Build Coastguard Worker "page fault ocurred due a read after an shmdt from %p\n",
357*49cdfc7eSAndroid Build Coastguard Worker map_address);
358*49cdfc7eSAndroid Build Coastguard Worker }
359*49cdfc7eSAndroid Build Coastguard Worker
360*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout, "%s[%#lx]: read_mem(): content of memory: %s\n",
361*49cdfc7eSAndroid Build Coastguard Worker STR_READER, pthread_self(), (char *)map_address);
362*49cdfc7eSAndroid Build Coastguard Worker
363*49cdfc7eSAndroid Build Coastguard Worker if (strncmp(map_address, "Y", 1) != 0) {
364*49cdfc7eSAndroid Build Coastguard Worker if (strncmp(map_address, "X", 1) != 0) {
365*49cdfc7eSAndroid Build Coastguard Worker pthread_exit((void *)-1);
366*49cdfc7eSAndroid Build Coastguard Worker }
367*49cdfc7eSAndroid Build Coastguard Worker }
368*49cdfc7eSAndroid Build Coastguard Worker usleep(1);
369*49cdfc7eSAndroid Build Coastguard Worker sched_yield();
370*49cdfc7eSAndroid Build Coastguard Worker }
371*49cdfc7eSAndroid Build Coastguard Worker pthread_exit(NULL);
372*49cdfc7eSAndroid Build Coastguard Worker }
373*49cdfc7eSAndroid Build Coastguard Worker
374*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
375*49cdfc7eSAndroid Build Coastguard Worker /* */
376*49cdfc7eSAndroid Build Coastguard Worker /* Function: main */
377*49cdfc7eSAndroid Build Coastguard Worker /* */
378*49cdfc7eSAndroid Build Coastguard Worker /* Descrption: Create a large file of size up to a Giga Bytes. write to it */
379*49cdfc7eSAndroid Build Coastguard Worker /* lower case alphabet 'a'. Map the file and change the contents */
380*49cdfc7eSAndroid Build Coastguard Worker /* to 'A's (upper case alphabet), write the contents to the file,*/
381*49cdfc7eSAndroid Build Coastguard Worker /* and unmap the file from memory. Spwan a certian number of */
382*49cdfc7eSAndroid Build Coastguard Worker /* LWP's that will do the above. */
383*49cdfc7eSAndroid Build Coastguard Worker /* */
384*49cdfc7eSAndroid Build Coastguard Worker /* Return: exits with -1 on error */
385*49cdfc7eSAndroid Build Coastguard Worker /* exits with a 0 on success. */
386*49cdfc7eSAndroid Build Coastguard Worker /* */
387*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
main(int argc,char ** argv)388*49cdfc7eSAndroid Build Coastguard Worker int main(int argc, /* number of input parameters. */
389*49cdfc7eSAndroid Build Coastguard Worker char **argv)
390*49cdfc7eSAndroid Build Coastguard Worker { /* pointer to the command line arguments. */
391*49cdfc7eSAndroid Build Coastguard Worker int c; /* command line options */
392*49cdfc7eSAndroid Build Coastguard Worker int num_iter; /* number of iteration to perform */
393*49cdfc7eSAndroid Build Coastguard Worker int thrd_ndx; /* index into the array of threads. */
394*49cdfc7eSAndroid Build Coastguard Worker double exec_time; /* period for which the test is executed */
395*49cdfc7eSAndroid Build Coastguard Worker void *status; /* exit status for light weight process */
396*49cdfc7eSAndroid Build Coastguard Worker int sig_ndx; /* index into signal handler structure. */
397*49cdfc7eSAndroid Build Coastguard Worker pthread_t thid[1000]; /* pids of process that will map/write/unmap */
398*49cdfc7eSAndroid Build Coastguard Worker long chld_args[3]; /* arguments to funcs execed by child process */
399*49cdfc7eSAndroid Build Coastguard Worker extern char *optarg; /* arguments passed to each option */
400*49cdfc7eSAndroid Build Coastguard Worker struct sigaction sigptr; /* set up signal, for interval timer */
401*49cdfc7eSAndroid Build Coastguard Worker
402*49cdfc7eSAndroid Build Coastguard Worker static struct signal_info {
403*49cdfc7eSAndroid Build Coastguard Worker int signum; /* signal number that hasto be handled */
404*49cdfc7eSAndroid Build Coastguard Worker char *signame; /* name of the signal to be handled. */
405*49cdfc7eSAndroid Build Coastguard Worker } sig_info[] = {
406*49cdfc7eSAndroid Build Coastguard Worker {
407*49cdfc7eSAndroid Build Coastguard Worker SIGHUP, "SIGHUP"}, {
408*49cdfc7eSAndroid Build Coastguard Worker SIGINT, "SIGINT"}, {
409*49cdfc7eSAndroid Build Coastguard Worker SIGQUIT, "SIGQUIT"}, {
410*49cdfc7eSAndroid Build Coastguard Worker SIGABRT, "SIGABRT"}, {
411*49cdfc7eSAndroid Build Coastguard Worker SIGBUS, "SIGBUS"}, {
412*49cdfc7eSAndroid Build Coastguard Worker SIGSEGV, "SIGSEGV"}, {
413*49cdfc7eSAndroid Build Coastguard Worker SIGALRM, "SIGALRM"}, {
414*49cdfc7eSAndroid Build Coastguard Worker SIGUSR1, "SIGUSR1"}, {
415*49cdfc7eSAndroid Build Coastguard Worker SIGUSR2, "SIGUSR2"}, {
416*49cdfc7eSAndroid Build Coastguard Worker -1, "ENDSIG"}
417*49cdfc7eSAndroid Build Coastguard Worker };
418*49cdfc7eSAndroid Build Coastguard Worker
419*49cdfc7eSAndroid Build Coastguard Worker /* set up the default values */
420*49cdfc7eSAndroid Build Coastguard Worker num_iter = 1000; /* repeate map - write - unmap operation 1000 times */
421*49cdfc7eSAndroid Build Coastguard Worker exec_time = 24.0; /* minimum time period for which to run the tests */
422*49cdfc7eSAndroid Build Coastguard Worker
423*49cdfc7eSAndroid Build Coastguard Worker while ((c = getopt(argc, argv, "h:l:x:")) != -1) {
424*49cdfc7eSAndroid Build Coastguard Worker switch (c) {
425*49cdfc7eSAndroid Build Coastguard Worker case 'h':
426*49cdfc7eSAndroid Build Coastguard Worker usage(argv[0]);
427*49cdfc7eSAndroid Build Coastguard Worker break;
428*49cdfc7eSAndroid Build Coastguard Worker case 'l': /* number of times to loop in the thread function */
429*49cdfc7eSAndroid Build Coastguard Worker if ((num_iter = atoi(optarg)) == 0)
430*49cdfc7eSAndroid Build Coastguard Worker num_iter = 1000;
431*49cdfc7eSAndroid Build Coastguard Worker break;
432*49cdfc7eSAndroid Build Coastguard Worker case 'x': /* time in hrs to run this test. */
433*49cdfc7eSAndroid Build Coastguard Worker if ((exec_time = atof(optarg)) == 0)
434*49cdfc7eSAndroid Build Coastguard Worker exec_time = 24;
435*49cdfc7eSAndroid Build Coastguard Worker break;
436*49cdfc7eSAndroid Build Coastguard Worker default:
437*49cdfc7eSAndroid Build Coastguard Worker usage(argv[0]);
438*49cdfc7eSAndroid Build Coastguard Worker break;
439*49cdfc7eSAndroid Build Coastguard Worker }
440*49cdfc7eSAndroid Build Coastguard Worker }
441*49cdfc7eSAndroid Build Coastguard Worker
442*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout,
443*49cdfc7eSAndroid Build Coastguard Worker "\n\n\nTest is set to run with the following parameters:\n"
444*49cdfc7eSAndroid Build Coastguard Worker "\tDuration of test: [%f]hrs\n"
445*49cdfc7eSAndroid Build Coastguard Worker "\tnumber of shmat shm detach: [%d]\n", exec_time, num_iter);
446*49cdfc7eSAndroid Build Coastguard Worker
447*49cdfc7eSAndroid Build Coastguard Worker /* set up signals */
448*49cdfc7eSAndroid Build Coastguard Worker sigptr.sa_handler = (void (*)(int signal))sig_handler;
449*49cdfc7eSAndroid Build Coastguard Worker sigfillset(&sigptr.sa_mask);
450*49cdfc7eSAndroid Build Coastguard Worker sigptr.sa_flags = SA_SIGINFO;
451*49cdfc7eSAndroid Build Coastguard Worker for (sig_ndx = 0; sig_info[sig_ndx].signum != -1; sig_ndx++) {
452*49cdfc7eSAndroid Build Coastguard Worker sigaddset(&sigptr.sa_mask, sig_info[sig_ndx].signum);
453*49cdfc7eSAndroid Build Coastguard Worker if (sigaction(sig_info[sig_ndx].signum, &sigptr,
454*49cdfc7eSAndroid Build Coastguard Worker NULL) == -1) {
455*49cdfc7eSAndroid Build Coastguard Worker perror("man(): sigaction()");
456*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
457*49cdfc7eSAndroid Build Coastguard Worker "could not set handler for SIGALRM, errno = %d\n",
458*49cdfc7eSAndroid Build Coastguard Worker errno);
459*49cdfc7eSAndroid Build Coastguard Worker exit(-1);
460*49cdfc7eSAndroid Build Coastguard Worker }
461*49cdfc7eSAndroid Build Coastguard Worker }
462*49cdfc7eSAndroid Build Coastguard Worker
463*49cdfc7eSAndroid Build Coastguard Worker chld_args[0] = num_iter;
464*49cdfc7eSAndroid Build Coastguard Worker alarm(exec_time * 3600.00);
465*49cdfc7eSAndroid Build Coastguard Worker
466*49cdfc7eSAndroid Build Coastguard Worker for (;;) {
467*49cdfc7eSAndroid Build Coastguard Worker /* create 3 threads */
468*49cdfc7eSAndroid Build Coastguard Worker if (pthread_create(&thid[0], NULL, shmat_shmdt, chld_args)) {
469*49cdfc7eSAndroid Build Coastguard Worker perror("main(): pthread_create()");
470*49cdfc7eSAndroid Build Coastguard Worker exit(-1);
471*49cdfc7eSAndroid Build Coastguard Worker } else {
472*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout,
473*49cdfc7eSAndroid Build Coastguard Worker "created thread id[%#lx], execs fn shmat_shmdt()\n",
474*49cdfc7eSAndroid Build Coastguard Worker thid[0]);
475*49cdfc7eSAndroid Build Coastguard Worker }
476*49cdfc7eSAndroid Build Coastguard Worker sched_yield();
477*49cdfc7eSAndroid Build Coastguard Worker
478*49cdfc7eSAndroid Build Coastguard Worker if (pthread_create(&thid[1], NULL, write_to_mem, chld_args)) {
479*49cdfc7eSAndroid Build Coastguard Worker perror("main(): pthread_create()");
480*49cdfc7eSAndroid Build Coastguard Worker exit(-1);
481*49cdfc7eSAndroid Build Coastguard Worker } else {
482*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout,
483*49cdfc7eSAndroid Build Coastguard Worker "created thread id[%#lx], execs fn write_to_mem()\n",
484*49cdfc7eSAndroid Build Coastguard Worker thid[1]);
485*49cdfc7eSAndroid Build Coastguard Worker }
486*49cdfc7eSAndroid Build Coastguard Worker sched_yield();
487*49cdfc7eSAndroid Build Coastguard Worker
488*49cdfc7eSAndroid Build Coastguard Worker if (pthread_create(&thid[2], NULL, read_from_mem, chld_args)) {
489*49cdfc7eSAndroid Build Coastguard Worker perror("main(): pthread_create()");
490*49cdfc7eSAndroid Build Coastguard Worker exit(-1);
491*49cdfc7eSAndroid Build Coastguard Worker } else {
492*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout,
493*49cdfc7eSAndroid Build Coastguard Worker "created thread id[%#lx], execs fn read_from_mem()\n",
494*49cdfc7eSAndroid Build Coastguard Worker thid[2]);
495*49cdfc7eSAndroid Build Coastguard Worker }
496*49cdfc7eSAndroid Build Coastguard Worker sched_yield();
497*49cdfc7eSAndroid Build Coastguard Worker
498*49cdfc7eSAndroid Build Coastguard Worker /* wait for the children to terminate */
499*49cdfc7eSAndroid Build Coastguard Worker for (thrd_ndx = 0; thrd_ndx < 3; thrd_ndx++) {
500*49cdfc7eSAndroid Build Coastguard Worker if (pthread_join(thid[thrd_ndx], &status)) {
501*49cdfc7eSAndroid Build Coastguard Worker perror("main(): pthread_create()");
502*49cdfc7eSAndroid Build Coastguard Worker exit(-1);
503*49cdfc7eSAndroid Build Coastguard Worker }
504*49cdfc7eSAndroid Build Coastguard Worker if (status == (void *)-1) {
505*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr,
506*49cdfc7eSAndroid Build Coastguard Worker "thread [%#lx] - process exited with errors %ld\n",
507*49cdfc7eSAndroid Build Coastguard Worker thid[thrd_ndx], (long)status);
508*49cdfc7eSAndroid Build Coastguard Worker exit(-1);
509*49cdfc7eSAndroid Build Coastguard Worker }
510*49cdfc7eSAndroid Build Coastguard Worker }
511*49cdfc7eSAndroid Build Coastguard Worker }
512*49cdfc7eSAndroid Build Coastguard Worker fprintf(stdout, "TEST PASSED\n");
513*49cdfc7eSAndroid Build Coastguard Worker return 0;
514*49cdfc7eSAndroid Build Coastguard Worker }
515