204 lines
7.1 KiB
C
204 lines
7.1 KiB
C
/******************************************************************************/
|
|
/* */
|
|
/* Copyright (c) International Business Machines Corp., 2008 */
|
|
/* */
|
|
/* This program is free software; you can redistribute it and/or modify */
|
|
/* it under the terms of the GNU General Public License as published by */
|
|
/* the Free Software Foundation; either version 2 of the License, or */
|
|
/* (at your option) any later version. */
|
|
/* */
|
|
/* This program is distributed in the hope that it will be useful, */
|
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
|
/* the GNU General Public License for more details. */
|
|
/* */
|
|
/* You should have received a copy of the GNU General Public License */
|
|
/* along with this program; if not, write to the Free Software */
|
|
/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
/* */
|
|
/******************************************************************************/
|
|
|
|
/******************************************************************************/
|
|
/* */
|
|
/* File: memctl_test01.c */
|
|
/* */
|
|
/* Description: This is a c program that allocates memory in chunks of size */
|
|
/* as given by the calling script. The program touches all the */
|
|
/* allocated pages by writing a string on each page. */
|
|
/* */
|
|
/* Total Tests: 3 */
|
|
/* */
|
|
/* Test Name: mem_controller_test01-03 */
|
|
/* */
|
|
/* */
|
|
/* Test Assertion */
|
|
/* Please refer to the file memctl_testplan.txt */
|
|
/* */
|
|
/* Author: Sudhir Kumar skumar@linux.vnet.ibm.com */
|
|
/* */
|
|
/* History: */
|
|
/* Created 12/03/2008 Sudhir Kumar <skumar@linux.vnet.ibm.com> */
|
|
/* Modified 11/05/2008 Sudhir Kumar <skumar@linux.vnet.ibm.com> */
|
|
/* */
|
|
/******************************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "libcontrollers.h"
|
|
#include "test.h"
|
|
|
|
char *TCID = "memory_controller_test01-03";
|
|
int TST_TOTAL = 3;
|
|
|
|
pid_t scriptpid;
|
|
typedef size_t record_t;
|
|
record_t **array_of_chunks;
|
|
record_t tmp;
|
|
int num_of_chunks, chunk_size, test_num, limit;
|
|
|
|
void cleanup();
|
|
void signal_handler_sigusr1(int signal);
|
|
void signal_handler_sigusr2(int signal);
|
|
int allocate_memory(void);
|
|
|
|
int main(void)
|
|
{
|
|
int ret;
|
|
char mygroup[FILENAME_MAX], mytaskfile[FILENAME_MAX];
|
|
char *mygroup_p, *script_pid_p, *test_num_p, *chunk_size_p;
|
|
char *num_chunks_p;
|
|
struct sigaction newaction1, newaction2, oldaction1, oldaction2;
|
|
|
|
/* Capture variables from the script environment */
|
|
test_num_p = getenv("TEST_NUM");
|
|
mygroup_p = getenv("MYGROUP");
|
|
script_pid_p = getenv("SCRIPT_PID");
|
|
chunk_size_p = getenv("CHUNK_SIZE");
|
|
num_chunks_p = getenv("NUM_CHUNKS");
|
|
|
|
if (test_num_p != NULL && mygroup_p != NULL && script_pid_p != NULL &&
|
|
chunk_size_p != NULL && num_chunks_p != NULL) {
|
|
scriptpid = atoi(script_pid_p);
|
|
test_num = atoi(test_num_p);
|
|
chunk_size = atoi(chunk_size_p);
|
|
num_of_chunks = atoi(num_chunks_p);
|
|
sprintf(mygroup, "%s", mygroup_p);
|
|
} else {
|
|
tst_brkm(TBROK, cleanup,
|
|
"invalid parameters received from script\n");
|
|
}
|
|
|
|
/* XXX (garrcoop): this section really needs error handling. */
|
|
|
|
/* Signal handling for SIGUSR1 received from script */
|
|
sigemptyset(&newaction1.sa_mask);
|
|
newaction1.sa_handler = signal_handler_sigusr1;
|
|
newaction1.sa_flags = 0;
|
|
sigaction(SIGUSR1, &newaction1, &oldaction1);
|
|
|
|
/* Signal handling for SIGUSR2 received from script */
|
|
sigemptyset(&newaction2.sa_mask);
|
|
newaction2.sa_handler = signal_handler_sigusr2;
|
|
newaction2.sa_flags = 0;
|
|
sigaction(SIGUSR2, &newaction2, &oldaction2);
|
|
|
|
sprintf(mytaskfile, "%s", mygroup);
|
|
strcat(mytaskfile, "/tasks");
|
|
/* Assign the task to it's group */
|
|
write_to_file(mytaskfile, "a", getpid()); /* Assign the task to it's group */
|
|
|
|
ret = allocate_memory(); /*should i check ret? */
|
|
|
|
cleanup();
|
|
|
|
tst_exit();
|
|
}
|
|
|
|
/*
|
|
* Function: cleanup()
|
|
* signals for system cleanup in case test breaks
|
|
*/
|
|
void cleanup(void)
|
|
{
|
|
if (kill(scriptpid, SIGUSR1) == -1)
|
|
tst_resm(TWARN | TERRNO, "kill failed");
|
|
}
|
|
|
|
/*
|
|
* Function: signal_handler_sigusr1()
|
|
* signal handler for the new action
|
|
*/
|
|
|
|
void signal_handler_sigusr1(int signal)
|
|
{
|
|
int i;
|
|
(void) signal;
|
|
for (i = 0; i < num_of_chunks; ++i)
|
|
free(array_of_chunks[i]);
|
|
free(array_of_chunks);
|
|
exit(0);
|
|
}
|
|
|
|
/*
|
|
* Function: signal_handler_sigusr2()
|
|
* signal handler for the new action
|
|
*/
|
|
|
|
void signal_handler_sigusr2(int signal)
|
|
{
|
|
int i;
|
|
(void) signal;
|
|
for (i = 0; i < num_of_chunks; ++i)
|
|
free(array_of_chunks[i]);
|
|
free(array_of_chunks);
|
|
if (test_num == 4) {
|
|
/* Allocate different amount of memory for second step */
|
|
chunk_size = 5242880; /* 5 MB chunks */
|
|
num_of_chunks = 15;
|
|
}
|
|
allocate_memory();
|
|
}
|
|
|
|
int allocate_memory(void)
|
|
{
|
|
int i, j;
|
|
/*
|
|
* Allocate array which contains base addresses of all chunks
|
|
*/
|
|
array_of_chunks = malloc(sizeof(record_t *) * num_of_chunks);
|
|
if (array_of_chunks == NULL)
|
|
tst_brkm(TBROK, cleanup,
|
|
"Memory allocation failed for array_of_chunks");
|
|
/*
|
|
* Allocate chunks of memory
|
|
*/
|
|
|
|
for (i = 0; i < num_of_chunks; ++i) {
|
|
array_of_chunks[i] = malloc(chunk_size);
|
|
if (array_of_chunks[i] == NULL)
|
|
tst_brkm(TBROK, cleanup,
|
|
"Memory allocation failed for chunks. Try smaller chunk size");
|
|
}
|
|
|
|
/*
|
|
* Touch all the pages of allocated memory by writing some string
|
|
*/
|
|
limit = chunk_size / sizeof(record_t);
|
|
|
|
for (i = 0; i < num_of_chunks; ++i)
|
|
for (j = 0; j < limit; ++j)
|
|
array_of_chunks[i][j] = 0xaa;
|
|
|
|
/*
|
|
* Just keep on accessing the allocated pages and do nothing relevant
|
|
*/
|
|
while (1) {
|
|
for (i = 0; i < num_of_chunks; ++i)
|
|
for (j = 0; j < limit; ++j)
|
|
tmp = array_of_chunks[i][j];
|
|
}
|
|
return 0;
|
|
}
|