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(int argc,char * argv[])66 int 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 */
cleanup()123 void 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
signal_handler_sigusr1(int signal)134 void 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
signal_handler_sigusr2(int signal)148 void 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
allocate_memory()162 int 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