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