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