• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
52 char *TCID = "memory_controller_test01-03";
53 int TST_TOTAL = 3;
54 
55 pid_t scriptpid;
56 typedef size_t record_t;
57 record_t **array_of_chunks;
58 record_t tmp;
59 int num_of_chunks, chunk_size, test_num, limit;
60 
61 void cleanup();
62 void signal_handler_sigusr1(int signal);
63 void signal_handler_sigusr2(int signal);
64 int allocate_memory(void);
65 
main(void)66 int main(void)
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 received from script\n");
91 	}
92 
93 	/* XXX (garrcoop): this section really needs error handling. */
94 
95 	/* Signal handling for SIGUSR1 received 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 received 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  */
cleanup(void)123 void cleanup(void)
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 
signal_handler_sigusr1(int signal)134 void signal_handler_sigusr1(int signal)
135 {
136 	int i;
137 	(void) signal;
138 	for (i = 0; i < num_of_chunks; ++i)
139 		free(array_of_chunks[i]);
140 	free(array_of_chunks);
141 	exit(0);
142 }
143 
144 /*
145  * Function: signal_handler_sigusr2()
146  * signal handler for the new action
147  */
148 
signal_handler_sigusr2(int signal)149 void signal_handler_sigusr2(int signal)
150 {
151 	int i;
152 	(void) signal;
153 	for (i = 0; i < num_of_chunks; ++i)
154 		free(array_of_chunks[i]);
155 	free(array_of_chunks);
156 	if (test_num == 4) {
157 		/* Allocate different amount of memory for second step */
158 		chunk_size = 5242880;	/* 5 MB chunks */
159 		num_of_chunks = 15;
160 	}
161 	allocate_memory();
162 }
163 
allocate_memory(void)164 int allocate_memory(void)
165 {
166 	int i, j;
167 	/*
168 	 * Allocate array which contains base addresses of all chunks
169 	 */
170 	array_of_chunks = malloc(sizeof(record_t *) * num_of_chunks);
171 	if (array_of_chunks == NULL)
172 		tst_brkm(TBROK, cleanup,
173 			 "Memory allocation failed for array_of_chunks");
174 	/*
175 	 * Allocate chunks of memory
176 	 */
177 
178 	for (i = 0; i < num_of_chunks; ++i) {
179 		array_of_chunks[i] = malloc(chunk_size);
180 		if (array_of_chunks[i] == NULL)
181 			tst_brkm(TBROK, cleanup,
182 				 "Memory allocation failed for chunks. Try smaller chunk size");
183 	}
184 
185 	/*
186 	 * Touch all the pages of allocated memory by writing some string
187 	 */
188 	limit = chunk_size / sizeof(record_t);
189 
190 	for (i = 0; i < num_of_chunks; ++i)
191 		for (j = 0; j < limit; ++j)
192 			array_of_chunks[i][j] = 0xaa;
193 
194 	/*
195 	 * Just keep on accessing the allocated pages and do nothing relevant
196 	 */
197 	while (1) {
198 		for (i = 0; i < num_of_chunks; ++i)
199 			for (j = 0; j < limit; ++j)
200 				tmp = array_of_chunks[i][j];
201 	}
202 	return 0;
203 }
204