1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci *
3f08c3bdfSopenharmony_ci *   Copyright (c) International Business Machines  Corp., 2002
4f08c3bdfSopenharmony_ci *
5f08c3bdfSopenharmony_ci *   This program is free software;  you can redistribute it and/or modify
6f08c3bdfSopenharmony_ci *   it under the terms of the GNU General Public License as published by
7f08c3bdfSopenharmony_ci *   the Free Software Foundation; either version 2 of the License, or
8f08c3bdfSopenharmony_ci *   (at your option) any later version.
9f08c3bdfSopenharmony_ci *
10f08c3bdfSopenharmony_ci *   This program is distributed in the hope that it will be useful,
11f08c3bdfSopenharmony_ci *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12f08c3bdfSopenharmony_ci *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13f08c3bdfSopenharmony_ci *   the GNU General Public License for more details.
14f08c3bdfSopenharmony_ci *
15f08c3bdfSopenharmony_ci *   You should have received a copy of the GNU General Public License
16f08c3bdfSopenharmony_ci *   along with this program;  if not, write to the Free Software
17f08c3bdfSopenharmony_ci *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18f08c3bdfSopenharmony_ci */
19f08c3bdfSopenharmony_ci
20f08c3bdfSopenharmony_ci/* 06/30/2001	Port to Linux	nsharoff@us.ibm.com */
21f08c3bdfSopenharmony_ci/* 11/01/2002	Port to LTP  	robbiew@us.ibm.com */
22f08c3bdfSopenharmony_ci
23f08c3bdfSopenharmony_ci			   /* page01.c */
24f08c3bdfSopenharmony_ci/*======================================================================
25f08c3bdfSopenharmony_ci	=================== TESTPLAN SEGMENT ===================
26f08c3bdfSopenharmony_ciCALLS:	malloc(3)
27f08c3bdfSopenharmony_ci
28f08c3bdfSopenharmony_ci	Run with KILL flag
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_ci>KEYS:  < paging behavior
31f08c3bdfSopenharmony_ci>WHAT:  < Does the system balk at heavy demands on it's paging facilities?
32f08c3bdfSopenharmony_ci>HOW:   < Create a number of process, each of which requests a large
33f08c3bdfSopenharmony_ci	< chunk of memory to be assigned to an array.  Write to each
34f08c3bdfSopenharmony_ci	< element in that array, and verify that what was written/stored
35f08c3bdfSopenharmony_ci	< is what was expected.
36f08c3bdfSopenharmony_ci>BUGS:  <
37f08c3bdfSopenharmony_ci======================================================================*/
38f08c3bdfSopenharmony_ci
39f08c3bdfSopenharmony_ci#include <sys/types.h>
40f08c3bdfSopenharmony_ci#include <sys/wait.h>
41f08c3bdfSopenharmony_ci#include <errno.h>
42f08c3bdfSopenharmony_ci#include <stdio.h>
43f08c3bdfSopenharmony_ci#include <stdlib.h>
44f08c3bdfSopenharmony_ci
45f08c3bdfSopenharmony_ciint bd_arg(char *);
46f08c3bdfSopenharmony_ci
47f08c3bdfSopenharmony_ci/** LTP Port **/
48f08c3bdfSopenharmony_ci#include "test.h"
49f08c3bdfSopenharmony_ci
50f08c3bdfSopenharmony_civoid blenter(void);
51f08c3bdfSopenharmony_civoid setup(void);
52f08c3bdfSopenharmony_civoid anyfail(void);
53f08c3bdfSopenharmony_civoid ok_exit(void);
54f08c3bdfSopenharmony_civoid forkfail(void);
55f08c3bdfSopenharmony_civoid terror(char *);
56f08c3bdfSopenharmony_ciint instress(void);
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_ci#define FAILED 0
59f08c3bdfSopenharmony_ci#define PASSED 1
60f08c3bdfSopenharmony_ci
61f08c3bdfSopenharmony_ciint local_flag = PASSED;
62f08c3bdfSopenharmony_ciint block_number;
63f08c3bdfSopenharmony_ciFILE *temp;
64f08c3bdfSopenharmony_ci
65f08c3bdfSopenharmony_cichar *TCID = "page01";		/* Test program identifier.    */
66f08c3bdfSopenharmony_ciint TST_TOTAL = 1;		/* Total number of test cases. */
67f08c3bdfSopenharmony_ci/**************/
68f08c3bdfSopenharmony_ci
69f08c3bdfSopenharmony_ciint main(argc, argv)
70f08c3bdfSopenharmony_ciint argc;
71f08c3bdfSopenharmony_cichar *argv[];
72f08c3bdfSopenharmony_ci{
73f08c3bdfSopenharmony_ci	int nchild;
74f08c3bdfSopenharmony_ci	int memory_size;
75f08c3bdfSopenharmony_ci	int error_count, i, j, pid, status;
76f08c3bdfSopenharmony_ci	int *number_pointer;
77f08c3bdfSopenharmony_ci	int *memory_pointer;
78f08c3bdfSopenharmony_ci	int child, count;
79f08c3bdfSopenharmony_ci
80f08c3bdfSopenharmony_ci	setup();
81f08c3bdfSopenharmony_ci
82f08c3bdfSopenharmony_ci	if (argc < 2) {
83f08c3bdfSopenharmony_ci		memory_size = 256 * 1024;
84f08c3bdfSopenharmony_ci		nchild = 50;
85f08c3bdfSopenharmony_ci	} else if (argc == 3) {
86f08c3bdfSopenharmony_ci		if (sscanf(argv[1], "%d", &memory_size) != 1)
87f08c3bdfSopenharmony_ci			bd_arg(argv[1]);
88f08c3bdfSopenharmony_ci		if (sscanf(argv[2], "%d", &nchild) != 1)
89f08c3bdfSopenharmony_ci			bd_arg(argv[2]);
90f08c3bdfSopenharmony_ci	} else {
91f08c3bdfSopenharmony_ci		printf("page01 [memory size (words)]  [nchild]\n");
92f08c3bdfSopenharmony_ci		tst_resm(TCONF, "\tBad arg count.");
93f08c3bdfSopenharmony_ci		exit(1);
94f08c3bdfSopenharmony_ci	}
95f08c3bdfSopenharmony_ci
96f08c3bdfSopenharmony_ci	blenter();
97f08c3bdfSopenharmony_ci
98f08c3bdfSopenharmony_ci	error_count = 0;
99f08c3bdfSopenharmony_ci
100f08c3bdfSopenharmony_ci	/****************************************/
101f08c3bdfSopenharmony_ci	/*                                      */
102f08c3bdfSopenharmony_ci	/*      attempt to fork a number of     */
103f08c3bdfSopenharmony_ci	/*      identical processes             */
104f08c3bdfSopenharmony_ci	/*                                      */
105f08c3bdfSopenharmony_ci	/****************************************/
106f08c3bdfSopenharmony_ci
107f08c3bdfSopenharmony_ci	for (i = 1; i <= nchild; i++) {
108f08c3bdfSopenharmony_ci		if ((pid = fork()) == -1) {
109f08c3bdfSopenharmony_ci			terror("Fork failed (may be OK if under stress)");
110f08c3bdfSopenharmony_ci			if (instress())
111f08c3bdfSopenharmony_ci				ok_exit();
112f08c3bdfSopenharmony_ci			forkfail();
113f08c3bdfSopenharmony_ci		} else if (pid == 0) {
114f08c3bdfSopenharmony_ci			/********************************/
115f08c3bdfSopenharmony_ci			/*                              */
116f08c3bdfSopenharmony_ci			/*   allocate memory  of size   */
117f08c3bdfSopenharmony_ci			/*    "memory_size"             */
118f08c3bdfSopenharmony_ci			/*                              */
119f08c3bdfSopenharmony_ci			/********************************/
120f08c3bdfSopenharmony_ci
121f08c3bdfSopenharmony_ci			memory_pointer = malloc(memory_size * sizeof(int));
122f08c3bdfSopenharmony_ci			if (memory_pointer == 0) {
123f08c3bdfSopenharmony_ci				tst_resm(TBROK,
124f08c3bdfSopenharmony_ci					 "Cannot allocate memory - malloc failed.");
125f08c3bdfSopenharmony_ci				if (i < 2) {
126f08c3bdfSopenharmony_ci					tst_resm(TBROK,
127f08c3bdfSopenharmony_ci						 "This should not happen for first two children.");
128f08c3bdfSopenharmony_ci					tst_brkm(TFAIL, NULL,
129f08c3bdfSopenharmony_ci						 "Child %d - fail.",
130f08c3bdfSopenharmony_ci						 i);
131f08c3bdfSopenharmony_ci				} else {
132f08c3bdfSopenharmony_ci					tst_resm(TCONF,
133f08c3bdfSopenharmony_ci						 "This is ok for all but first two children.");
134f08c3bdfSopenharmony_ci					tst_brkm(TCONF, NULL,
135f08c3bdfSopenharmony_ci						 "Child %d - ok.", i);
136f08c3bdfSopenharmony_ci				}
137f08c3bdfSopenharmony_ci			}
138f08c3bdfSopenharmony_ci			number_pointer = memory_pointer;
139f08c3bdfSopenharmony_ci
140f08c3bdfSopenharmony_ci			/********************************/
141f08c3bdfSopenharmony_ci			/*                              */
142f08c3bdfSopenharmony_ci			/*         write to it          */
143f08c3bdfSopenharmony_ci			/*                              */
144f08c3bdfSopenharmony_ci			/********************************/
145f08c3bdfSopenharmony_ci
146f08c3bdfSopenharmony_ci			for (j = 1; j <= memory_size; j++)
147f08c3bdfSopenharmony_ci				*(number_pointer++) = j;
148f08c3bdfSopenharmony_ci			sleep(1);
149f08c3bdfSopenharmony_ci
150f08c3bdfSopenharmony_ci			/********************************/
151f08c3bdfSopenharmony_ci			/*                              */
152f08c3bdfSopenharmony_ci			/*      and read from it to     */
153f08c3bdfSopenharmony_ci			/*  check that what was written */
154f08c3bdfSopenharmony_ci			/*       is still there         */
155f08c3bdfSopenharmony_ci			/*                              */
156f08c3bdfSopenharmony_ci			/********************************/
157f08c3bdfSopenharmony_ci
158f08c3bdfSopenharmony_ci			number_pointer = memory_pointer;
159f08c3bdfSopenharmony_ci			for (j = 1; j <= memory_size; j++) {
160f08c3bdfSopenharmony_ci				if (*(number_pointer++) != j)
161f08c3bdfSopenharmony_ci					error_count++;
162f08c3bdfSopenharmony_ci			}
163f08c3bdfSopenharmony_ci			exit(error_count);
164f08c3bdfSopenharmony_ci		}
165f08c3bdfSopenharmony_ci	}
166f08c3bdfSopenharmony_ci
167f08c3bdfSopenharmony_ci	/****************************************/
168f08c3bdfSopenharmony_ci	/*                                      */
169f08c3bdfSopenharmony_ci	/*      wait for the child processes    */
170f08c3bdfSopenharmony_ci	/*      to teminate and report the #    */
171f08c3bdfSopenharmony_ci	/*      of deviations recognized        */
172f08c3bdfSopenharmony_ci	/*                                      */
173f08c3bdfSopenharmony_ci	/****************************************/
174f08c3bdfSopenharmony_ci
175f08c3bdfSopenharmony_ci	count = 0;
176f08c3bdfSopenharmony_ci	while ((child = wait(&status)) > 0) {
177f08c3bdfSopenharmony_ci#ifdef DEBUG
178f08c3bdfSopenharmony_ci		tst_resm(TINFO, "Test {%d} exited status %d\n", child, status);
179f08c3bdfSopenharmony_ci#endif
180f08c3bdfSopenharmony_ci		if (status)
181f08c3bdfSopenharmony_ci			local_flag = FAILED;
182f08c3bdfSopenharmony_ci		count++;
183f08c3bdfSopenharmony_ci	}
184f08c3bdfSopenharmony_ci
185f08c3bdfSopenharmony_ci	if (count != nchild) {
186f08c3bdfSopenharmony_ci		tst_resm(TWARN, "Wrong number of children waited on.");
187f08c3bdfSopenharmony_ci		tst_resm(TWARN, "Count = %d, expected = %d.", count, nchild);
188f08c3bdfSopenharmony_ci	}
189f08c3bdfSopenharmony_ci
190f08c3bdfSopenharmony_ci	anyfail();
191f08c3bdfSopenharmony_ci	/** NOT REACHED **/
192f08c3bdfSopenharmony_ci	tst_exit();
193f08c3bdfSopenharmony_ci}
194f08c3bdfSopenharmony_ci
195f08c3bdfSopenharmony_ciint bd_arg(str)
196f08c3bdfSopenharmony_cichar *str;
197f08c3bdfSopenharmony_ci{
198f08c3bdfSopenharmony_ci	tst_resm(TCONF, "\tCannot parse %s as a number.", str);
199f08c3bdfSopenharmony_ci	exit(1);
200f08c3bdfSopenharmony_ci}
201f08c3bdfSopenharmony_ci
202f08c3bdfSopenharmony_ci/** LTP Port **/
203f08c3bdfSopenharmony_ci/*
204f08c3bdfSopenharmony_ci * setup
205f08c3bdfSopenharmony_ci *
206f08c3bdfSopenharmony_ci * Do set up - here its a dummy function
207f08c3bdfSopenharmony_ci */
208f08c3bdfSopenharmony_civoid setup()
209f08c3bdfSopenharmony_ci{
210f08c3bdfSopenharmony_ci	tst_tmpdir();
211f08c3bdfSopenharmony_ci	temp = stderr;
212f08c3bdfSopenharmony_ci}
213f08c3bdfSopenharmony_ci
214f08c3bdfSopenharmony_ci/*
215f08c3bdfSopenharmony_ci * Function: blenter()
216f08c3bdfSopenharmony_ci *
217f08c3bdfSopenharmony_ci * Description: Print message on entering a new block
218f08c3bdfSopenharmony_ci */
219f08c3bdfSopenharmony_civoid blenter()
220f08c3bdfSopenharmony_ci{
221f08c3bdfSopenharmony_ci	local_flag = PASSED;
222f08c3bdfSopenharmony_ci	return;
223f08c3bdfSopenharmony_ci}
224f08c3bdfSopenharmony_ci
225f08c3bdfSopenharmony_ci/*
226f08c3bdfSopenharmony_ci *
227f08c3bdfSopenharmony_ci * Function: anyfail()
228f08c3bdfSopenharmony_ci *
229f08c3bdfSopenharmony_ci * Description: Exit a test.
230f08c3bdfSopenharmony_ci */
231f08c3bdfSopenharmony_civoid anyfail()
232f08c3bdfSopenharmony_ci{
233f08c3bdfSopenharmony_ci	(local_flag == FAILED) ? tst_resm(TFAIL, "Test failed")
234f08c3bdfSopenharmony_ci	    : tst_resm(TPASS, "Test passed");
235f08c3bdfSopenharmony_ci	tst_rmdir();
236f08c3bdfSopenharmony_ci	tst_exit();
237f08c3bdfSopenharmony_ci}
238f08c3bdfSopenharmony_ci
239f08c3bdfSopenharmony_ci/*
240f08c3bdfSopenharmony_ci * ok_exit
241f08c3bdfSopenharmony_ci *
242f08c3bdfSopenharmony_ci * Calling block passed the test
243f08c3bdfSopenharmony_ci */
244f08c3bdfSopenharmony_civoid ok_exit()
245f08c3bdfSopenharmony_ci{
246f08c3bdfSopenharmony_ci	local_flag = PASSED;
247f08c3bdfSopenharmony_ci	return;
248f08c3bdfSopenharmony_ci}
249f08c3bdfSopenharmony_ci
250f08c3bdfSopenharmony_ci/*
251f08c3bdfSopenharmony_ci * forkfail()
252f08c3bdfSopenharmony_ci *
253f08c3bdfSopenharmony_ci * exit on failure
254f08c3bdfSopenharmony_ci */
255f08c3bdfSopenharmony_civoid forkfail()
256f08c3bdfSopenharmony_ci{
257f08c3bdfSopenharmony_ci	tst_brkm(TBROK, tst_rmdir, "Reason: %s", strerror(errno));
258f08c3bdfSopenharmony_ci}
259f08c3bdfSopenharmony_ci
260f08c3bdfSopenharmony_ci/*
261f08c3bdfSopenharmony_ci * Function: terror
262f08c3bdfSopenharmony_ci *
263f08c3bdfSopenharmony_ci * Description: prints error message this may not be because some part of the
264f08c3bdfSopenharmony_ci *              test case failed, for example fork() failed. We will log this
265f08c3bdfSopenharmony_ci *              failure as TBROK instead of TFAIL.
266f08c3bdfSopenharmony_ci */
267f08c3bdfSopenharmony_civoid terror(char *message)
268f08c3bdfSopenharmony_ci{
269f08c3bdfSopenharmony_ci	tst_resm(TBROK, "Reason: %s:%s", message, strerror(errno));
270f08c3bdfSopenharmony_ci	return;
271f08c3bdfSopenharmony_ci}
272f08c3bdfSopenharmony_ci
273f08c3bdfSopenharmony_ci/*
274f08c3bdfSopenharmony_ci * instress
275f08c3bdfSopenharmony_ci *
276f08c3bdfSopenharmony_ci * Assume that we are always running under stress, so this function will
277f08c3bdfSopenharmony_ci * return > 0 value always.
278f08c3bdfSopenharmony_ci */
279f08c3bdfSopenharmony_ciint instress()
280f08c3bdfSopenharmony_ci{
281f08c3bdfSopenharmony_ci	tst_resm(TINFO, "System resource may be too low, fork() malloc()"
282f08c3bdfSopenharmony_ci		 " etc are likely to fail.");
283f08c3bdfSopenharmony_ci	return 1;
284f08c3bdfSopenharmony_ci}
285