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/* 11/05/2002	Port to LTP	robbiew@us.ibm.com */
21f08c3bdfSopenharmony_ci/* 06/30/2001	Port to Linux	nsharoff@us.ibm.com */
22f08c3bdfSopenharmony_ci
23f08c3bdfSopenharmony_ci			   /* page02.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	  Writes start in middle of array and proceede to ends.
37f08c3bdfSopenharmony_ci>BUGS:  <
38f08c3bdfSopenharmony_ci======================================================================*/
39f08c3bdfSopenharmony_ci
40f08c3bdfSopenharmony_ci#include <stdio.h>
41f08c3bdfSopenharmony_ci#include <signal.h>
42f08c3bdfSopenharmony_ci#include <errno.h>
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_ci#ifdef LINUX
45f08c3bdfSopenharmony_ci#include <stdlib.h>
46f08c3bdfSopenharmony_ci#include <unistd.h>
47f08c3bdfSopenharmony_ci#include <stdlib.h>
48f08c3bdfSopenharmony_ci#include <sys/wait.h>
49f08c3bdfSopenharmony_ci#endif
50f08c3bdfSopenharmony_ci
51f08c3bdfSopenharmony_ci/** LTP Port **/
52f08c3bdfSopenharmony_ci#include "test.h"
53f08c3bdfSopenharmony_ci
54f08c3bdfSopenharmony_ci#define FAILED 0
55f08c3bdfSopenharmony_ci#define PASSED 1
56f08c3bdfSopenharmony_ci
57f08c3bdfSopenharmony_ciint local_flag = PASSED;
58f08c3bdfSopenharmony_ciint block_number;
59f08c3bdfSopenharmony_ci
60f08c3bdfSopenharmony_cichar *TCID = "page02";		/* Test program identifier.    */
61f08c3bdfSopenharmony_ciint TST_TOTAL = 1;		/* Total number of test cases. */
62f08c3bdfSopenharmony_ci/**************/
63f08c3bdfSopenharmony_ci
64f08c3bdfSopenharmony_ciint bd_arg(char *);
65f08c3bdfSopenharmony_ciint chld_flag;
66f08c3bdfSopenharmony_ciint parent_pid;
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_ciint main(argc, argv)
69f08c3bdfSopenharmony_ciint argc;
70f08c3bdfSopenharmony_cichar *argv[];
71f08c3bdfSopenharmony_ci{
72f08c3bdfSopenharmony_ci	int nchild;
73f08c3bdfSopenharmony_ci	int memory_size, half_memory_size;
74f08c3bdfSopenharmony_ci	int error_count, i, j, pid, status;
75f08c3bdfSopenharmony_ci	int *memory_pointer;
76f08c3bdfSopenharmony_ci	int *up_pointer, *down_pointer;
77f08c3bdfSopenharmony_ci	int child, count;
78f08c3bdfSopenharmony_ci	int chld();
79f08c3bdfSopenharmony_ci
80f08c3bdfSopenharmony_ci	parent_pid = getpid();
81f08c3bdfSopenharmony_ci	tst_tmpdir();
82f08c3bdfSopenharmony_ci
83f08c3bdfSopenharmony_ci	if (signal(SIGUSR1, (void (*)())chld) == SIG_ERR) {
84f08c3bdfSopenharmony_ci		tst_resm(TBROK, "signal failed");
85f08c3bdfSopenharmony_ci		exit(1);
86f08c3bdfSopenharmony_ci	}
87f08c3bdfSopenharmony_ci
88f08c3bdfSopenharmony_ci	if (argc < 2) {
89f08c3bdfSopenharmony_ci		memory_size = 128 * 1024;
90f08c3bdfSopenharmony_ci		nchild = 5;
91f08c3bdfSopenharmony_ci	} else if (argc == 3) {
92f08c3bdfSopenharmony_ci		if (sscanf(argv[1], "%d", &memory_size) != 1)
93f08c3bdfSopenharmony_ci			bd_arg(argv[1]);
94f08c3bdfSopenharmony_ci		if (sscanf(argv[2], "%d", &nchild) != 1)
95f08c3bdfSopenharmony_ci			bd_arg(argv[2]);
96f08c3bdfSopenharmony_ci	} else {
97f08c3bdfSopenharmony_ci		printf("page02 [memory size (words)]  [nchild]\n");
98f08c3bdfSopenharmony_ci		tst_resm(TCONF, "\tBad arg count.");
99f08c3bdfSopenharmony_ci		exit(1);
100f08c3bdfSopenharmony_ci	}
101f08c3bdfSopenharmony_ci	half_memory_size = memory_size / 2;
102f08c3bdfSopenharmony_ci
103f08c3bdfSopenharmony_ci	error_count = 0;
104f08c3bdfSopenharmony_ci
105f08c3bdfSopenharmony_ci	/****************************************/
106f08c3bdfSopenharmony_ci	/*                                      */
107f08c3bdfSopenharmony_ci	/*      attempt to fork a number of     */
108f08c3bdfSopenharmony_ci	/*      identical processes             */
109f08c3bdfSopenharmony_ci	/*                                      */
110f08c3bdfSopenharmony_ci	/****************************************/
111f08c3bdfSopenharmony_ci
112f08c3bdfSopenharmony_ci	for (i = 1; i <= nchild; i++) {
113f08c3bdfSopenharmony_ci		chld_flag = 0;
114f08c3bdfSopenharmony_ci		if ((pid = fork()) == -1) {
115f08c3bdfSopenharmony_ci			tst_resm(TBROK,
116f08c3bdfSopenharmony_ci				 "Fork failed (may be OK if under stress)");
117f08c3bdfSopenharmony_ci			tst_resm(TINFO, "System resource may be too low.");
118f08c3bdfSopenharmony_ci			local_flag = PASSED;
119f08c3bdfSopenharmony_ci			tst_brkm(TBROK, tst_rmdir, "Reason: %s",
120f08c3bdfSopenharmony_ci				 strerror(errno));
121f08c3bdfSopenharmony_ci		} else if (pid == 0) {
122f08c3bdfSopenharmony_ci			/********************************/
123f08c3bdfSopenharmony_ci			/*                              */
124f08c3bdfSopenharmony_ci			/*   allocate memory  of size   */
125f08c3bdfSopenharmony_ci			/*    "memory_size"             */
126f08c3bdfSopenharmony_ci			/*                              */
127f08c3bdfSopenharmony_ci			/********************************/
128f08c3bdfSopenharmony_ci
129f08c3bdfSopenharmony_ci			memory_pointer = malloc(memory_size * sizeof(int));
130f08c3bdfSopenharmony_ci			if (memory_pointer == 0) {
131f08c3bdfSopenharmony_ci				tst_resm(TBROK, "\tCannot malloc memory.");
132f08c3bdfSopenharmony_ci				if (i < 2) {
133f08c3bdfSopenharmony_ci					tst_resm(TBROK,
134f08c3bdfSopenharmony_ci						 "\tThis should not happen to first two children.");
135f08c3bdfSopenharmony_ci					tst_resm(TBROK, "\tChild %d - fail.",
136f08c3bdfSopenharmony_ci						 i);
137f08c3bdfSopenharmony_ci				} else {
138f08c3bdfSopenharmony_ci					tst_resm(TBROK,
139f08c3bdfSopenharmony_ci						 "\tThis is ok for all but first two children.");
140f08c3bdfSopenharmony_ci					tst_resm(TBROK, "\tChild %d - ok.",
141f08c3bdfSopenharmony_ci						 i);
142f08c3bdfSopenharmony_ci					kill(parent_pid, SIGUSR1);
143f08c3bdfSopenharmony_ci					_exit(0);
144f08c3bdfSopenharmony_ci				}
145f08c3bdfSopenharmony_ci				tst_resm(TBROK, "malloc fail");
146f08c3bdfSopenharmony_ci				tst_resm(TFAIL,
147f08c3bdfSopenharmony_ci					 "\tImpossible to allocate memory of size %d in process %d",
148f08c3bdfSopenharmony_ci					 memory_size, i);
149f08c3bdfSopenharmony_ci				kill(parent_pid, SIGUSR1);
150f08c3bdfSopenharmony_ci				tst_exit();
151f08c3bdfSopenharmony_ci			}
152f08c3bdfSopenharmony_ci			kill(parent_pid, SIGUSR1);
153f08c3bdfSopenharmony_ci
154f08c3bdfSopenharmony_ci			down_pointer = up_pointer = memory_pointer +
155f08c3bdfSopenharmony_ci			    (memory_size / 2);
156f08c3bdfSopenharmony_ci
157f08c3bdfSopenharmony_ci			/********************************/
158f08c3bdfSopenharmony_ci			/*                              */
159f08c3bdfSopenharmony_ci			/*         write to it          */
160f08c3bdfSopenharmony_ci			/*                              */
161f08c3bdfSopenharmony_ci			/********************************/
162f08c3bdfSopenharmony_ci
163f08c3bdfSopenharmony_ci			for (j = 1; j <= half_memory_size; j++) {
164f08c3bdfSopenharmony_ci				*(up_pointer++) = j;
165f08c3bdfSopenharmony_ci				*(down_pointer--) = j;
166f08c3bdfSopenharmony_ci			}
167f08c3bdfSopenharmony_ci			sleep(1);
168f08c3bdfSopenharmony_ci
169f08c3bdfSopenharmony_ci			/********************************/
170f08c3bdfSopenharmony_ci			/*                              */
171f08c3bdfSopenharmony_ci			/*      and read from it to     */
172f08c3bdfSopenharmony_ci			/*  check that what was written */
173f08c3bdfSopenharmony_ci			/*       is still there         */
174f08c3bdfSopenharmony_ci			/*                              */
175f08c3bdfSopenharmony_ci			/********************************/
176f08c3bdfSopenharmony_ci
177f08c3bdfSopenharmony_ci			down_pointer = up_pointer = memory_pointer +
178f08c3bdfSopenharmony_ci			    (memory_size / 2);
179f08c3bdfSopenharmony_ci
180f08c3bdfSopenharmony_ci			for (j = 1; j <= half_memory_size; j++) {
181f08c3bdfSopenharmony_ci				if (*(up_pointer++) != j)
182f08c3bdfSopenharmony_ci					error_count++;
183f08c3bdfSopenharmony_ci				if (*(down_pointer--) != j)
184f08c3bdfSopenharmony_ci					error_count++;
185f08c3bdfSopenharmony_ci			}
186f08c3bdfSopenharmony_ci			exit(error_count);
187f08c3bdfSopenharmony_ci		}
188f08c3bdfSopenharmony_ci		while (!chld_flag)
189f08c3bdfSopenharmony_ci			sleep(1);
190f08c3bdfSopenharmony_ci	}
191f08c3bdfSopenharmony_ci
192f08c3bdfSopenharmony_ci	/****************************************/
193f08c3bdfSopenharmony_ci	/*                                      */
194f08c3bdfSopenharmony_ci	/*      wait for the child processes    */
195f08c3bdfSopenharmony_ci	/*      to teminate and report the #    */
196f08c3bdfSopenharmony_ci	/*      of deviations recognized        */
197f08c3bdfSopenharmony_ci	/*                                      */
198f08c3bdfSopenharmony_ci	/****************************************/
199f08c3bdfSopenharmony_ci
200f08c3bdfSopenharmony_ci	count = 0;
201f08c3bdfSopenharmony_ci	while ((child = wait(&status)) > 0) {
202f08c3bdfSopenharmony_ci#ifdef DEBUG
203f08c3bdfSopenharmony_ci		tst_resm(TINFO, "\tTest {%d} exited status %d\n", child,
204f08c3bdfSopenharmony_ci			 status);
205f08c3bdfSopenharmony_ci#endif
206f08c3bdfSopenharmony_ci		if (status)
207f08c3bdfSopenharmony_ci			local_flag = FAILED;
208f08c3bdfSopenharmony_ci		count++;
209f08c3bdfSopenharmony_ci	}
210f08c3bdfSopenharmony_ci
211f08c3bdfSopenharmony_ci	if (count != nchild) {
212f08c3bdfSopenharmony_ci		tst_resm(TFAIL, "\tWrong number of children waited on.");
213f08c3bdfSopenharmony_ci		tst_resm(TFAIL, "\tCount = %d, expected = %d.",
214f08c3bdfSopenharmony_ci			 count, nchild);
215f08c3bdfSopenharmony_ci	}
216f08c3bdfSopenharmony_ci
217f08c3bdfSopenharmony_ci	(local_flag == FAILED) ? tst_resm(TFAIL, "Test failed")
218f08c3bdfSopenharmony_ci	    : tst_resm(TPASS, "Test passed");
219f08c3bdfSopenharmony_ci	tst_rmdir();
220f08c3bdfSopenharmony_ci	tst_exit();
221f08c3bdfSopenharmony_ci
222f08c3bdfSopenharmony_ci}
223f08c3bdfSopenharmony_ci
224f08c3bdfSopenharmony_ciint bd_arg(str)
225f08c3bdfSopenharmony_cichar *str;
226f08c3bdfSopenharmony_ci{
227f08c3bdfSopenharmony_ci	tst_brkm(TCONF, NULL, "\tCannot parse %s as a number.", str);
228f08c3bdfSopenharmony_ci}
229f08c3bdfSopenharmony_ci
230f08c3bdfSopenharmony_ciint chld()
231f08c3bdfSopenharmony_ci{
232f08c3bdfSopenharmony_ci	if (signal(SIGUSR1, (void (*)())chld) == SIG_ERR) {
233f08c3bdfSopenharmony_ci		tst_brkm(TBROK, NULL, "signal failed");
234f08c3bdfSopenharmony_ci	}
235f08c3bdfSopenharmony_ci	chld_flag++;
236f08c3bdfSopenharmony_ci	return 0;
237f08c3bdfSopenharmony_ci}
238