• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *   Copyright (C) Bull S.A. 1996
3  *   Copyright (c) International Business Machines  Corp., 2001
4  *
5  *   This program is free software;  you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13  *   the GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program;  if not, write to the Free Software
17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 /*---------------------------------------------------------------------+
20 |                           shmem_test_05.c                            |
21 | ==================================================================== |
22 |                                                                      |
23 | Title:        SHMBLA is treated as 0x1000                            |
24 |                                                                      |
25 | Purpose:      simultaneous attachment of more than ten shared        |
26 |               memory regions to a process at adresses that are       |
27 |		multiple of the value SHMBLA . EXTSHM=ON is set ,      |
28 |               the value of SHMLBA is treated as 0x1000 internally    |
29 |                                                                      |
30 | Description:  Simplistic test to verify that a process can obtain    |
31 |               11 shared memory regions in the adress space from      |
32 |               0x30000000 to 0x3FFFFFFF .                             |
33 |                                                                      |
34 |                                                                      |
35 | Algorithm:    *  from 1 up to 11                                     |
36 |               {                                                      |
37 |               o  Create a key to uniquely identify the shared segment|
38 |		   using ftok()	subroutine.			       |
39 |               o  Obtain a unique shared memory identifier with       |
40 |                  shmget ()                                           |
41 |               o  Map the shared memory segment to the current        |
42 |                  process with shmat ()                               |
43 |               o  Index through the shared memory segment             |
44 |               }                                                      |
45 |               *  from 1 up to 11                                     |
46 |               {                                                      |
47 |               o  Detach from the segment with shmdt()                |
48 |               o  Release the shared memory segment with shmctl ()    |
49 |               }                                                      |
50 |                                                                      |
51 | System calls: The following system calls are tested:                 |
52 |                                                                      |
53 |               ftok()                                                 |
54 |               shmget ()                                              |
55 |               shmat ()                                               |
56 |               shmdt ()                                               |
57 |               shmctl ()                                              |
58 |                                                                      |
59 | Usage:        shmem_test_05                                          |
60 |                                                                      |
61 | To compile:   cc -O -g  shmem_test_05.c -o shmem_test_05 -lbsd       |
62 |                                                                      |
63 | Last update:                                                         |
64 |                                                                      |
65 | Change Activity                                                      |
66 |                                                                      |
67 |   Version  Date    Name  Reason                                      |
68 |    0.1     010997  J.Malcles  initial version for 4.2.G              |
69 |                                                                      |
70 |                                                                      |
71 +---------------------------------------------------------------------*/
72 
73 #include <stdio.h>
74 #include <stdlib.h>
75 #include <string.h>
76 #include <errno.h>
77 #include <unistd.h>
78 #include <sys/shm.h>
79 
80 #include <sys/types.h>
81 #include <sys/ipc.h>
82 
83 #include <sys/stat.h>
84 off_t offsets[] = {
85 	0x30000000,
86 	0x30200000,
87 	0x30400000,
88 	0x30600000,
89 	0x30800000,
90 	0x30A00000,
91 	0x30C00000,
92 	0x30D00000,
93 	0x30F00000,
94 	0x31000000,
95 	0x32000000
96 };
97 
98 int offsets_cnt = sizeof(offsets) / sizeof(offsets[0]);
99 /* Defines
100  *
101  * MAX_SHMEM_SIZE: maximum shared memory segment size of 256MB
102  *
103  * MAX_SHMEM_NUMBER: maximum number of simultaneous attached shared memory
104  * regions
105  *
106  * DEFAULT_SHMEM_SIZE: default shared memory size, unless specified with
107  * -s command line option
108  *
109  * SHMEM_MODE: shared memory access permissions (permit process to read
110  * and write access)
111  *
112  * USAGE: usage statement
113  */
114 #define MAX_SHMEM_SIZE		256*1024*1024
115 #define MAX_SHMEM_NUMBER	11
116 #define DEFAULT_SHMEM_SIZE	1024*1024
117 #define	SHMEM_MODE		(SHM_R | SHM_W)
118 #define USAGE	"\nUsage: %s [-s shmem_size]\n\n" \
119 		"\t-s shmem_size  size of shared memory segment (bytes)\n" \
120 		"\t               (must be less than 256MB!)\n\n"
121 
122 /*
123  * Function prototypes
124  *
125  * parse_args (): Parse command line arguments
126  * sys_error (): System error message function
127  * error (): Error message function
128  */
129 void parse_args(int, char **);
130 void sys_error(const char *, int);
131 void error(const char *, int);
132 
133 /*
134  * Global variables
135  *
136  * shmem_size: shared memory segment size (in bytes)
137  */
138 int shmem_size = DEFAULT_SHMEM_SIZE;
139 
140 /*---------------------------------------------------------------------+
141 |                               main                                   |
142 | ==================================================================== |
143 |                                                                      |
144 |                                                                      |
145 | Function:  Main program  (see prolog for more details)               |
146 |                                                                      |
147 | Returns:   (0)  Successful completion                                |
148 |            (-1) Error occurred                                       |
149 |                                                                      |
150 +---------------------------------------------------------------------*/
main(int argc,char ** argv)151 int main(int argc, char **argv)
152 {
153 	off_t offset;
154 	int i;
155 
156 	int shmid[MAX_SHMEM_NUMBER];	/* (Unique) Shared memory identifier */
157 
158 	char *shmptr[MAX_SHMEM_NUMBER];	/* Shared memory segment address */
159 	char *ptr;		/* Index into shared memory segment */
160 
161 	int value = 0;		/* Value written into shared memory segment */
162 
163 	key_t mykey[MAX_SHMEM_NUMBER];
164 	char *null_file = "/dev/null";
165 	char proj[MAX_SHMEM_NUMBER] = {
166 		'3',
167 		'4',
168 		'5',
169 		'6',
170 		'7',
171 		'8',
172 		'9',
173 		'A',
174 		'B',
175 		'C',
176 		'E'
177 	};
178 
179 	/*
180 	 * Parse command line arguments and print out program header
181 	 */
182 	parse_args(argc, argv);
183 	printf("%s: IPC Shared Memory TestSuite program\n", *argv);
184 
185 	for (i = 0; i < offsets_cnt; i++) {
186 		/*
187 		 * Create a key to uniquely identify the shared segment
188 		 */
189 
190 		mykey[i] = ftok(null_file, proj[i]);
191 
192 		printf
193 		    ("\n\tmykey to uniquely identify the shared memory segment 0x%x\n",
194 		     mykey[i]);
195 
196 		printf("\n\tGet shared memory segment (%d bytes)\n",
197 		       shmem_size);
198 		/*
199 		 * Obtain a unique shared memory identifier with shmget ().
200 		 */
201 
202 /*	if ((shmid[i]= shmget(mykey[i], shmem_size, IPC_CREAT | 0666 )) < 0) */
203 		if ((shmid[i] = shmget(IPC_PRIVATE, shmem_size,
204 				       IPC_CREAT | IPC_EXCL | 0666)) < 0)
205 			sys_error("shmget failed", __LINE__);
206 
207 		printf("\n\tAttach shared memory segment to process\n");
208 		/*
209 		 * Attach the shared memory segment to the process
210 		 */
211 
212 		offset = offsets[i];
213 
214 #ifndef __64BIT__
215 		printf("\n\toffset of the shared memory segment 0x%lx\n",
216 		       offset);
217 		if ((shmptr[i] =
218 		     shmat(shmid[i], (const void *)offset, 0)) == (char *)-1)
219 #else
220 		printf
221 		    ("\n\toffset of the shared memory is determined by the system\n");
222 		if ((shmptr[i] = (char *)shmat(shmid[i], 0, 0)) == (char *)-1)
223 #endif
224 			sys_error("shmat failed", __LINE__);
225 
226 		printf("\n\tIndex through shared memory segment ...\n");
227 
228 		/*
229 		 * Index through the shared memory segment
230 		 */
231 
232 		for (ptr = shmptr[i]; ptr < (shmptr[i] + shmem_size); ptr++)
233 			*ptr = value++;
234 
235 	}
236 
237 	printf("\n\tDetach from the segment using the shmdt subroutine\n");
238 
239 	printf("\n\tRelease shared memory\n");
240 
241 	for (i = 0; i < offsets_cnt; i++) {
242 		/*
243 		 * Detach from the segment
244 		 */
245 
246 		shmdt(shmptr[i]);
247 
248 		/*
249 		 * Release shared memory
250 		 */
251 
252 		if (shmctl(shmid[i], IPC_RMID, 0) < 0)
253 			sys_error("shmctl failed", __LINE__);
254 
255 	}
256 	/*
257 	 * Program completed successfully -- exit
258 	 */
259 
260 	printf("\nsuccessful!\n");
261 
262 	return (0);
263 }
264 
265 /*---------------------------------------------------------------------+
266 |                             parse_args ()                            |
267 | ==================================================================== |
268 |                                                                      |
269 | Function:  Parse the command line arguments & initialize global      |
270 |            variables.                                                |
271 |                                                                      |
272 | Updates:   (command line options)                                    |
273 |                                                                      |
274 |            [-s] size: shared memory segment size                     |
275 |                                                                      |
276 +---------------------------------------------------------------------*/
parse_args(int argc,char ** argv)277 void parse_args(int argc, char **argv)
278 {
279 	int i;
280 	int errflag = 0;
281 	char *program_name = *argv;
282 	extern char *optarg;	/* Command line option */
283 
284 	while ((i = getopt(argc, argv, "s:?")) != EOF) {
285 		switch (i) {
286 		case 's':
287 			shmem_size = atoi(optarg);
288 			break;
289 		case '?':
290 			errflag++;
291 			break;
292 		}
293 	}
294 
295 	if (shmem_size < 1 || shmem_size > MAX_SHMEM_SIZE)
296 		errflag++;
297 
298 	if (errflag) {
299 		fprintf(stderr, USAGE, program_name);
300 		exit(2);
301 	}
302 }
303 
304 /*---------------------------------------------------------------------+
305 |                             sys_error ()                             |
306 | ==================================================================== |
307 |                                                                      |
308 | Function:  Creates system error message and calls error ()           |
309 |                                                                      |
310 +---------------------------------------------------------------------*/
sys_error(const char * msg,int line)311 void sys_error(const char *msg, int line)
312 {
313 	char syserr_msg[256];
314 
315 	sprintf(syserr_msg, "%s: %s\n", msg, strerror(errno));
316 	error(syserr_msg, line);
317 }
318 
319 /*---------------------------------------------------------------------+
320 |                               error ()                               |
321 | ==================================================================== |
322 |                                                                      |
323 | Function:  Prints out message and exits...                           |
324 |                                                                      |
325 +---------------------------------------------------------------------*/
error(const char * msg,int line)326 void error(const char *msg, int line)
327 {
328 	fprintf(stderr, "ERROR [line: %d] %s\n", line, msg);
329 	exit(-1);
330 }
331