memctl_test01.c revision d218f348c12b42a78fa0306d9a033bfa4f67238b
1/******************************************************************************/
2/*                                                                            */
3/* Copyright (c) International Business Machines  Corp., 2008                 */
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
21/******************************************************************************/
22/*                                                                            */
23/* File:        memctl_test01.c                                               */
24/*                                                                            */
25/* Description: This is a c program that allocates memory in chunks of size   */
26/*              as given by the calling script. The program touches all the   */
27/*              allocated pages by writing a string on each page.             */
28/*                                                                            */
29/* Total Tests: 3                                                             */
30/*                                                                            */
31/* Test Name:   mem_controller_test01-03                                      */
32/*                                                                            */
33/*                                                                            */
34/* Test Assertion                                                             */
35/*              Please refer to the file memctl_testplan.txt                  */
36/*                                                                            */
37/* Author:      Sudhir Kumar skumar@linux.vnet.ibm.com                        */
38/*                                                                            */
39/* History:                                                                   */
40/* Created      12/03/2008  Sudhir Kumar <skumar@linux.vnet.ibm.com>          */
41/* Modified     11/05/2008  Sudhir Kumar <skumar@linux.vnet.ibm.com>          */
42/*                                                                            */
43/******************************************************************************/
44
45#include <stdio.h>
46#include <string.h>
47#include <unistd.h>
48
49#include "libcontrollers.h"
50#include "test.h"
51
52char *TCID = "memory_controller_test01-03";
53int TST_TOTAL = 3;
54
55pid_t scriptpid;
56typedef size_t record_t;
57record_t **array_of_chunks;
58record_t tmp;
59int num_of_chunks, chunk_size, test_num, limit;
60
61void cleanup();
62void signal_handler_sigusr1(int signal);
63void signal_handler_sigusr2(int signal);
64int allocate_memory(void);
65
66int main(int argc, char *argv[])
67{
68	int ret;
69	char mygroup[FILENAME_MAX], mytaskfile[FILENAME_MAX];
70	char *mygroup_p, *script_pid_p, *test_num_p, *chunk_size_p;
71	char *num_chunks_p;
72	struct sigaction newaction1, newaction2, oldaction1, oldaction2;
73
74	/* Capture variables from the script environment */
75	test_num_p = getenv("TEST_NUM");
76	mygroup_p = getenv("MYGROUP");
77	script_pid_p = getenv("SCRIPT_PID");
78	chunk_size_p = getenv("CHUNK_SIZE");
79	num_chunks_p = getenv("NUM_CHUNKS");
80
81	if (test_num_p != NULL && mygroup_p != NULL && script_pid_p != NULL &&
82	    chunk_size_p != NULL && num_chunks_p != NULL) {
83		scriptpid = atoi(script_pid_p);
84		test_num = atoi(test_num_p);
85		chunk_size = atoi(chunk_size_p);
86		num_of_chunks = atoi(num_chunks_p);
87		sprintf(mygroup, "%s", mygroup_p);
88	} else {
89		tst_brkm(TBROK, cleanup,
90			 "invalid parameters recieved from script\n");
91	}
92
93	/* XXX (garrcoop): this section really needs error handling. */
94
95	/* Signal handling for SIGUSR1 recieved from script */
96	sigemptyset(&newaction1.sa_mask);
97	newaction1.sa_handler = signal_handler_sigusr1;
98	newaction1.sa_flags = 0;
99	sigaction(SIGUSR1, &newaction1, &oldaction1);
100
101	/* Signal handling for SIGUSR2 recieved from script */
102	sigemptyset(&newaction2.sa_mask);
103	newaction2.sa_handler = signal_handler_sigusr2;
104	newaction2.sa_flags = 0;
105	sigaction(SIGUSR2, &newaction2, &oldaction2);
106
107	sprintf(mytaskfile, "%s", mygroup);
108	strcat(mytaskfile, "/tasks");
109	/* Assign the task to it's group */
110	write_to_file(mytaskfile, "a", getpid());	/* Assign the task to it's group */
111
112	ret = allocate_memory();	/*should i check ret? */
113
114	cleanup();
115
116	tst_exit();
117}
118
119/*
120 * Function: cleanup()
121 * signals for system cleanup in case test breaks
122 */
123void cleanup()
124{
125	if (kill(scriptpid, SIGUSR1) == -1)
126		tst_resm(TWARN | TERRNO, "kill failed");
127}
128
129/*
130 * Function: signal_handler_sigusr1()
131 * signal handler for the new action
132 */
133
134void signal_handler_sigusr1(int signal)
135{
136	int i;
137	for (i = 0; i < num_of_chunks; ++i)
138		free(array_of_chunks[i]);
139	free(array_of_chunks);
140	exit(0);
141}
142
143/*
144 * Function: signal_handler_sigusr2()
145 * signal handler for the new action
146 */
147
148void signal_handler_sigusr2(int signal)
149{
150	int i;
151	for (i = 0; i < num_of_chunks; ++i)
152		free(array_of_chunks[i]);
153	free(array_of_chunks);
154	if (test_num == 4) {
155		/* Allocate different amount of memory for second step */
156		chunk_size = 5242880;	/* 5 MB chunks */
157		num_of_chunks = 15;
158	}
159	allocate_memory();
160}
161
162int allocate_memory()
163{
164	int i, j;
165	/*
166	 * Allocate array which contains base addresses of all chunks
167	 */
168	array_of_chunks = malloc(sizeof(record_t *) * num_of_chunks);
169	if (array_of_chunks == NULL)
170		tst_brkm(TBROK, cleanup,
171			 "Memory allocation failed for array_of_chunks");
172	/*
173	 * Allocate chunks of memory
174	 */
175
176	for (i = 0; i < num_of_chunks; ++i) {
177		array_of_chunks[i] = malloc(chunk_size);
178		if (array_of_chunks[i] == NULL)
179			tst_brkm(TBROK, cleanup,
180				 "Memory allocation failed for chunks. Try smaller chunk size");
181	}
182
183	/*
184	 * Touch all the pages of allocated memory by writing some string
185	 */
186	limit = chunk_size / sizeof(record_t);
187
188	for (i = 0; i < num_of_chunks; ++i)
189		for (j = 0; j < limit; ++j)
190			array_of_chunks[i][j] = 0xaa;
191
192	/*
193	 * Just keep on accessing the allocated pages and do nothing relevant
194	 */
195	while (1) {
196		for (i = 0; i < num_of_chunks; ++i)
197			for (j = 0; j < limit; ++j)
198				tmp = array_of_chunks[i][j];
199	}
200	return 0;
201}
202