cpuctl_test01.c revision 6b78bd97ae956c84863ab786cb34f5ce592d2300
1/******************************************************************************/ 2/* */ 3/* Copyright (c) International Business Machines Corp., 2007 */ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 18/* */ 19/******************************************************************************/ 20 21/******************************************************************************/ 22/* */ 23/* File: cpuctl_test01.c */ 24/* */ 25/* Description: This is a c program that tests the cpucontroller fairness of */ 26/* scheduling the tasks according to their group shares. This */ 27/* testcase tests the ability of the cpu controller to provide */ 28/* fairness for share values (absolute). */ 29/* */ 30/* Total Tests: 2 */ 31/* */ 32/* Test Name: cpu_controller_test01 */ 33/* */ 34/* Test Assertion */ 35/* Please refer to the file cpuctl_testplan.txt */ 36/* */ 37/* Author: Sudhir Kumar sudhirkumarmalik@in.ibm.com */ 38/* */ 39/* History: */ 40/* Created- 20/12/2007 -Sudhir Kumar sudhirkumarmalik@in.ibm.com */ 41/* */ 42/******************************************************************************/ 43 44/* Standard Include Files */ 45#include <unistd.h> 46#include <math.h> 47#include <signal.h> 48#include <stdio.h> 49#include <stdlib.h> 50#include <string.h> 51#include <sys/resource.h> 52#include <sys/syscall.h> 53#include <sys/time.h> 54#include <sys/types.h> 55#include <time.h> 56#include <unistd.h> 57 58#include "test.h" /* LTP harness APIs*/ 59 60#define TIME_INTERVAL 60 /* Time interval in seconds*/ 61#define NUM_INTERVALS 3 /* How many iterations of TIME_INTERVAL */ 62#define NUM_SETS 7 /* How many share values (with same ratio)*/ 63#define MULTIPLIER 10 /* decides the rate at which share value gets multiplied*/ 64 65extern int Tst_count; 66char *TCID = "cpu_controller_test01"; 67int TST_TOTAL = 1; 68pid_t scriptpid; 69extern void 70cleanup() 71{ 72 kill (scriptpid, SIGUSR1);/* Inform the shell to do cleanup*/ 73 tst_exit (); /* Report exit status*/ 74} 75 76int write_to_file (char * file, const char* mode, unsigned int value); 77void signal_handler_alarm (int signal ); 78int timer_expired = 0; 79 80int main(int argc, char* argv[]) 81{ 82 83 int num_cpus; /* To calculate cpu time in %*/ 84 char mygroup[32], mytaskfile[32], mysharesfile[32], ch; 85 pid_t pid; 86 int my_group_num, /* A number attached with a group*/ 87 fd, /* A descriptor to open a fifo for synchronized start*/ 88 first_counter =0, /* To take n number of readings*/ 89 second_counter=0; /* To track number of times the base value of shares has been changed*/ 90 double total_cpu_time, /* Accumulated cpu time*/ 91 delta_cpu_time, /* Time the task could run on cpu(s) (in an interval)*/ 92 prev_cpu_time=0; 93 struct rusage cpu_usage; 94 time_t current_time, prev_time, delta_time; 95 unsigned long int myshares = 1; /* Simply the base value to start with*/ 96 struct sigaction newaction, oldaction; 97 /* Signal handling for alarm*/ 98 sigemptyset (&newaction.sa_mask); 99 newaction.sa_handler = signal_handler_alarm; 100 newaction.sa_flags=0; 101 sigaction (SIGALRM, &newaction, &oldaction); 102 103 /* Check if all parameters passed are correct*/ 104 if ((argc < 5) || ((my_group_num = atoi(argv[1])) <= 0) || ((scriptpid = atoi(argv[3])) <= 0) || ((num_cpus = atoi(argv[4])) <= 0)) 105 { 106 tst_brkm (TBROK, cleanup, "Invalid input parameters\n"); 107 } 108 109 myshares *= my_group_num; 110 sprintf(mygroup,"%s", argv[2]); 111 sprintf(mytaskfile, "%s", mygroup); 112 sprintf(mysharesfile, "%s", mygroup); 113 strcat (mytaskfile,"/tasks"); 114 strcat (mysharesfile,"/cpu.shares"); 115 pid = getpid(); 116 write_to_file (mytaskfile, "a", pid); /* Assign the task to it's group*/ 117 write_to_file (mysharesfile, "w", myshares); 118 119 fd = open ("./myfifo", 0); 120 if (fd == -1) 121 { 122 tst_brkm (TBROK, cleanup, "Could not open fifo for synchronization"); 123 } 124 125 fprintf(stdout,"\ntask-%d SHARES=%lu\n",my_group_num, myshares); 126 read (fd, &ch, 1); /* To block all tasks here and fire them up at the same time*/ 127 prev_time = time (NULL); /* Note down the time*/ 128 129 while (1) 130 { 131 /* Need to run some cpu intensive task, which also frequently checks the timer value*/ 132 double f = 274.345, mytime; /*just a float number to take sqrt*/ 133 alarm (TIME_INTERVAL); 134 timer_expired = 0; 135 while (!timer_expired) /* Let the task run on cpu for TIME_INTERVAL*/ 136 f = sqrt (f*f); /* Time of this operation should not be high otherwise we can 137 * exceed the TIME_INTERVAL to measure cpu usage 138 */ 139 current_time = time (NULL); 140 delta_time = current_time - prev_time; /* Duration in case it is not exact TIME_INTERVAL*/ 141 142 getrusage (0, &cpu_usage); 143 total_cpu_time = (cpu_usage.ru_utime.tv_sec + cpu_usage.ru_utime.tv_usec * 1e-6 + /* user time*/ 144 cpu_usage.ru_stime.tv_sec + cpu_usage.ru_stime.tv_usec * 1e-6) ; /* system time*/ 145 delta_cpu_time = total_cpu_time - prev_cpu_time; 146 147 prev_cpu_time = total_cpu_time; 148 prev_time = current_time; 149 if (delta_time > TIME_INTERVAL) 150 mytime = (delta_cpu_time * 100) / (delta_time * num_cpus); 151 else 152 mytime = (delta_cpu_time * 100) / (TIME_INTERVAL * num_cpus); 153 154 fprintf (stdout,"PID: %u\ttask-%d:cpu time ---> %6.3f\%(%fs) --->%lu(shares)\tinterval:%lu\n",getpid(),my_group_num, mytime, delta_cpu_time, myshares, delta_time); 155 first_counter++; 156 157 if (first_counter >= NUM_INTERVALS) /* Take n sets of readings for each shares value*/ 158 { 159 first_counter = 0; 160 second_counter++; 161 if (second_counter >= NUM_SETS) 162 exit (0); /* This task is done with its job*/ 163 myshares = MULTIPLIER * myshares; /* Keep same ratio but change values*/ 164 write_to_file (mysharesfile, "w", myshares); 165 fprintf(stdout,"\ntask-%d SHARES=%lu\n",my_group_num, myshares); 166 }/* end if*/ 167 }/* end while*/ 168}/* end main*/ 169 170 171int write_to_file (char *file, const char *mode, unsigned int value) 172{ 173 FILE *fp; 174 fp = fopen (file, mode); 175 if (fp == NULL) 176 { 177 tst_brkm (TBROK, cleanup, "Could not open file %s for writing", file); 178 } 179 fprintf (fp, "%u\n", value); 180 fclose (fp); 181 return 0; 182} 183 184void signal_handler_alarm (int signal) 185{ 186 timer_expired = 1; 187} 188