1f08c3bdfSopenharmony_ci/******************************************************************************/ 2f08c3bdfSopenharmony_ci/* */ 3f08c3bdfSopenharmony_ci/* Copyright (c) International Business Machines Corp., 2007 */ 4f08c3bdfSopenharmony_ci/* */ 5f08c3bdfSopenharmony_ci/* This program is free software; you can redistribute it and/or modify */ 6f08c3bdfSopenharmony_ci/* it under the terms of the GNU General Public License as published by */ 7f08c3bdfSopenharmony_ci/* the Free Software Foundation; either version 2 of the License, or */ 8f08c3bdfSopenharmony_ci/* (at your option) any later version. */ 9f08c3bdfSopenharmony_ci/* */ 10f08c3bdfSopenharmony_ci/* This program is distributed in the hope that it will be useful, */ 11f08c3bdfSopenharmony_ci/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 12f08c3bdfSopenharmony_ci/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ 13f08c3bdfSopenharmony_ci/* the GNU General Public License for more details. */ 14f08c3bdfSopenharmony_ci/* */ 15f08c3bdfSopenharmony_ci/* You should have received a copy of the GNU General Public License */ 16f08c3bdfSopenharmony_ci/* along with this program; if not, write to the Free Software */ 17f08c3bdfSopenharmony_ci/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 18f08c3bdfSopenharmony_ci/* */ 19f08c3bdfSopenharmony_ci/******************************************************************************/ 20f08c3bdfSopenharmony_ci 21f08c3bdfSopenharmony_ci/******************************************************************************/ 22f08c3bdfSopenharmony_ci/* */ 23f08c3bdfSopenharmony_ci/* File: cpuctl_test04.c */ 24f08c3bdfSopenharmony_ci/* */ 25f08c3bdfSopenharmony_ci/* Description: This is a c program that tests the cpucontroller fairness of */ 26f08c3bdfSopenharmony_ci/* scheduling the tasks according to their group shares. This */ 27f08c3bdfSopenharmony_ci/* testcase tests the ability of the cpu controller to provide */ 28f08c3bdfSopenharmony_ci/* fairness for share values (absolute). */ 29f08c3bdfSopenharmony_ci/* */ 30f08c3bdfSopenharmony_ci/* Total Tests: 2 */ 31f08c3bdfSopenharmony_ci/* */ 32f08c3bdfSopenharmony_ci/* Test 09: Heavy stress test with nice value change */ 33f08c3bdfSopenharmony_ci/* Test 10: Heavy stress test (effect of heavy group on light group) */ 34f08c3bdfSopenharmony_ci/* */ 35f08c3bdfSopenharmony_ci/* Test Name: cpu_controller_test04 */ 36f08c3bdfSopenharmony_ci/* */ 37f08c3bdfSopenharmony_ci/* Test Assertion */ 38f08c3bdfSopenharmony_ci/* Please refer to the file cpuctl_testplan.txt */ 39f08c3bdfSopenharmony_ci/* */ 40f08c3bdfSopenharmony_ci/* Author: Sudhir Kumar skumar@linux.vnet.ibm.com */ 41f08c3bdfSopenharmony_ci/* */ 42f08c3bdfSopenharmony_ci/* History: */ 43f08c3bdfSopenharmony_ci/* Created- 20/12/2007 -Sudhir Kumar <skumar@linux.vnet.ibm.com> */ 44f08c3bdfSopenharmony_ci/* */ 45f08c3bdfSopenharmony_ci/******************************************************************************/ 46f08c3bdfSopenharmony_ci 47f08c3bdfSopenharmony_ci#include <unistd.h> 48f08c3bdfSopenharmony_ci#include <math.h> 49f08c3bdfSopenharmony_ci#include <signal.h> 50f08c3bdfSopenharmony_ci#include <stdio.h> 51f08c3bdfSopenharmony_ci#include <stdlib.h> 52f08c3bdfSopenharmony_ci#include <string.h> 53f08c3bdfSopenharmony_ci#include <sys/resource.h> 54f08c3bdfSopenharmony_ci#include <sys/syscall.h> 55f08c3bdfSopenharmony_ci#include <sys/time.h> 56f08c3bdfSopenharmony_ci#include <sys/types.h> 57f08c3bdfSopenharmony_ci#include <sys/stat.h> 58f08c3bdfSopenharmony_ci#include <fcntl.h> 59f08c3bdfSopenharmony_ci#include <time.h> 60f08c3bdfSopenharmony_ci#include <unistd.h> 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_ci#include "../libcontrollers/libcontrollers.h" 63f08c3bdfSopenharmony_ci#include "test.h" /* LTP harness APIs */ 64f08c3bdfSopenharmony_ci#include "safe_macros.h" 65f08c3bdfSopenharmony_ci 66f08c3bdfSopenharmony_ci#define TIME_INTERVAL 100 /* Time interval in seconds */ 67f08c3bdfSopenharmony_ci#define NUM_INTERVALS 2 /* How many iterations of TIME_INTERVAL */ 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_cichar *TCID = "cpuctl_test04"; 70f08c3bdfSopenharmony_ciint TST_TOTAL = 2; 71f08c3bdfSopenharmony_cipid_t scriptpid; 72f08c3bdfSopenharmony_cichar path[] = "/dev/cpuctl"; 73f08c3bdfSopenharmony_ci 74f08c3bdfSopenharmony_ciextern void cleanup(void) 75f08c3bdfSopenharmony_ci{ 76f08c3bdfSopenharmony_ci kill(scriptpid, SIGUSR1); /* Inform the shell to do cleanup */ 77f08c3bdfSopenharmony_ci tst_exit(); /* Report exit status */ 78f08c3bdfSopenharmony_ci} 79f08c3bdfSopenharmony_ci 80f08c3bdfSopenharmony_ciint main(void) 81f08c3bdfSopenharmony_ci{ 82f08c3bdfSopenharmony_ci 83f08c3bdfSopenharmony_ci int test_num; 84f08c3bdfSopenharmony_ci int task_num; 85f08c3bdfSopenharmony_ci int len; 86f08c3bdfSopenharmony_ci int num_cpus; /* Total time = TIME_INTERVAL *num_cpus in the machine */ 87f08c3bdfSopenharmony_ci char mygroup[FILENAME_MAX], mytaskfile[FILENAME_MAX]; 88f08c3bdfSopenharmony_ci char mysharesfile[FILENAME_MAX], ch; 89f08c3bdfSopenharmony_ci /* Following variables are to capture parameters from script */ 90f08c3bdfSopenharmony_ci char *group_num_p, *mygroup_p, *script_pid_p, *num_cpus_p, *test_num_p, 91f08c3bdfSopenharmony_ci *task_num_p; 92f08c3bdfSopenharmony_ci gid_t mygroup_num; /* A number attached with a group */ 93f08c3bdfSopenharmony_ci int fd; /* A descriptor to open a fifo for synchronized start */ 94f08c3bdfSopenharmony_ci int counter = 0; /* To take n number of readings */ 95f08c3bdfSopenharmony_ci double total_cpu_time, /* Accumulated cpu time */ 96f08c3bdfSopenharmony_ci delta_cpu_time, /* Time the task could run on cpu(s) (in an interval) */ 97f08c3bdfSopenharmony_ci prev_cpu_time = 0; 98f08c3bdfSopenharmony_ci double exp_cpu_time; /* Expected time in % as obtained by shares calculation */ 99f08c3bdfSopenharmony_ci struct rusage cpu_usage; 100f08c3bdfSopenharmony_ci unsigned long int mygroup_shares; 101f08c3bdfSopenharmony_ci time_t current_time, prev_time, delta_time; 102f08c3bdfSopenharmony_ci unsigned int fmyshares, num_tasks; /* f-> from file. num_tasks is tasks in this group */ 103f08c3bdfSopenharmony_ci struct sigaction newaction, oldaction; 104f08c3bdfSopenharmony_ci 105f08c3bdfSopenharmony_ci mygroup_num = -1; 106f08c3bdfSopenharmony_ci num_cpus = 0; 107f08c3bdfSopenharmony_ci task_num = 0; 108f08c3bdfSopenharmony_ci test_num = 0; 109f08c3bdfSopenharmony_ci 110f08c3bdfSopenharmony_ci /* Signal handling for alarm */ 111f08c3bdfSopenharmony_ci sigemptyset(&newaction.sa_mask); 112f08c3bdfSopenharmony_ci newaction.sa_handler = signal_handler_alarm; 113f08c3bdfSopenharmony_ci newaction.sa_flags = 0; 114f08c3bdfSopenharmony_ci sigaction(SIGALRM, &newaction, &oldaction); 115f08c3bdfSopenharmony_ci 116f08c3bdfSopenharmony_ci /* Collect the parameters passed by the script */ 117f08c3bdfSopenharmony_ci group_num_p = getenv("GROUP_NUM"); 118f08c3bdfSopenharmony_ci mygroup_p = getenv("MYGROUP"); 119f08c3bdfSopenharmony_ci script_pid_p = getenv("SCRIPT_PID"); 120f08c3bdfSopenharmony_ci num_cpus_p = getenv("NUM_CPUS"); 121f08c3bdfSopenharmony_ci test_num_p = getenv("TEST_NUM"); 122f08c3bdfSopenharmony_ci task_num_p = getenv("TASK_NUM"); 123f08c3bdfSopenharmony_ci /* Check if all of them are valid */ 124f08c3bdfSopenharmony_ci if ((test_num_p != NULL) 125f08c3bdfSopenharmony_ci && (((test_num = atoi(test_num_p)) <= 10) 126f08c3bdfSopenharmony_ci && ((test_num = atoi(test_num_p)) >= 9))) { 127f08c3bdfSopenharmony_ci if ((group_num_p != NULL) && (mygroup_p != NULL) 128f08c3bdfSopenharmony_ci && (script_pid_p != NULL) && (num_cpus_p != NULL) 129f08c3bdfSopenharmony_ci && (task_num_p != NULL)) { 130f08c3bdfSopenharmony_ci mygroup_num = atoi(group_num_p); 131f08c3bdfSopenharmony_ci scriptpid = atoi(script_pid_p); 132f08c3bdfSopenharmony_ci num_cpus = atoi(num_cpus_p); 133f08c3bdfSopenharmony_ci task_num = atoi(task_num_p); 134f08c3bdfSopenharmony_ci sprintf(mygroup, "%s", mygroup_p); 135f08c3bdfSopenharmony_ci } else { 136f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, 137f08c3bdfSopenharmony_ci "Invalid other input parameters"); 138f08c3bdfSopenharmony_ci } 139f08c3bdfSopenharmony_ci } else { 140f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, "Invalid test number passed"); 141f08c3bdfSopenharmony_ci } 142f08c3bdfSopenharmony_ci 143f08c3bdfSopenharmony_ci /* 144f08c3bdfSopenharmony_ci * Let us give the default group 100 shares, as other groups will have 145f08c3bdfSopenharmony_ci * a multiple of 100 shares. 146f08c3bdfSopenharmony_ci * WARN: For large num of groups this may hit MAX_SHARES 147f08c3bdfSopenharmony_ci */ 148f08c3bdfSopenharmony_ci mygroup_shares = mygroup_num * 100; 149f08c3bdfSopenharmony_ci 150f08c3bdfSopenharmony_ci sprintf(mytaskfile, "%s", mygroup); 151f08c3bdfSopenharmony_ci strcat(mytaskfile, "/tasks"); 152f08c3bdfSopenharmony_ci sprintf(mysharesfile, "%s", mygroup); 153f08c3bdfSopenharmony_ci strcat(mysharesfile, "/cpu.shares"); 154f08c3bdfSopenharmony_ci /* Need some technique so as only 1 task per grp writes to shares file */ 155f08c3bdfSopenharmony_ci if (test_num == 9) 156f08c3bdfSopenharmony_ci write_to_file(mysharesfile, "w", mygroup_shares); /* Write the shares of the group */ 157f08c3bdfSopenharmony_ci 158f08c3bdfSopenharmony_ci write_to_file(mytaskfile, "a", getpid()); /* Assign the task to it's group */ 159f08c3bdfSopenharmony_ci 160f08c3bdfSopenharmony_ci fd = SAFE_OPEN(cleanup, "./myfifo", 0); 161f08c3bdfSopenharmony_ci 162f08c3bdfSopenharmony_ci read(fd, &ch, 1); /* To block all tasks here and fire them up at the same time */ 163f08c3bdfSopenharmony_ci 164f08c3bdfSopenharmony_ci /* 165f08c3bdfSopenharmony_ci * We now calculate the expected % cpu time of this task by getting 166f08c3bdfSopenharmony_ci * it's group's shares, the total shares of all the groups and the 167f08c3bdfSopenharmony_ci * number of tasks in this group. 168f08c3bdfSopenharmony_ci */ 169f08c3bdfSopenharmony_ci FLAG = 0; 170f08c3bdfSopenharmony_ci total_shares = 0; 171f08c3bdfSopenharmony_ci shares_pointer = &total_shares; 172f08c3bdfSopenharmony_ci len = strlen(path); 173f08c3bdfSopenharmony_ci if (!strncpy(fullpath, path, len)) 174f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, "Could not copy directory path %s ", 175f08c3bdfSopenharmony_ci path); 176f08c3bdfSopenharmony_ci 177f08c3bdfSopenharmony_ci if (scan_shares_files(shares_pointer) != 0) 178f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, 179f08c3bdfSopenharmony_ci "From function scan_shares_files in %s ", fullpath); 180f08c3bdfSopenharmony_ci 181f08c3bdfSopenharmony_ci /* return val: -1 in case of function error, else 2 is min share value */ 182f08c3bdfSopenharmony_ci if ((fmyshares = read_shares_file(mysharesfile)) < 2) 183f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, "in reading shares files %s ", 184f08c3bdfSopenharmony_ci mysharesfile); 185f08c3bdfSopenharmony_ci 186f08c3bdfSopenharmony_ci if ((read_file(mytaskfile, GET_TASKS, &num_tasks)) < 0) 187f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, "in reading tasks files %s ", 188f08c3bdfSopenharmony_ci mytaskfile); 189f08c3bdfSopenharmony_ci 190f08c3bdfSopenharmony_ci exp_cpu_time = (double)(fmyshares * 100) / (total_shares * num_tasks); 191f08c3bdfSopenharmony_ci 192f08c3bdfSopenharmony_ci prev_time = time(NULL); /* Note down the time */ 193f08c3bdfSopenharmony_ci 194f08c3bdfSopenharmony_ci while (1) { 195f08c3bdfSopenharmony_ci /* Need to run some cpu intensive task, which also frequently checks the timer value */ 196f08c3bdfSopenharmony_ci double f = 274.345, mytime; /*just a float number to take sqrt */ 197f08c3bdfSopenharmony_ci alarm(TIME_INTERVAL); 198f08c3bdfSopenharmony_ci timer_expired = 0; 199f08c3bdfSopenharmony_ci while (!timer_expired) /* Let the task run on cpu for TIME_INTERVAL */ 200f08c3bdfSopenharmony_ci f = sqrt(f * f); /* Time of this operation should not be high otherwise we can 201f08c3bdfSopenharmony_ci * exceed the TIME_INTERVAL to measure cpu usage 202f08c3bdfSopenharmony_ci */ 203f08c3bdfSopenharmony_ci current_time = time(NULL); 204f08c3bdfSopenharmony_ci delta_time = current_time - prev_time; /* Duration in case its not exact TIME_INTERVAL */ 205f08c3bdfSopenharmony_ci 206f08c3bdfSopenharmony_ci getrusage(0, &cpu_usage); 207f08c3bdfSopenharmony_ci total_cpu_time = (cpu_usage.ru_utime.tv_sec + cpu_usage.ru_utime.tv_usec * 1e-6 + /* user time */ 208f08c3bdfSopenharmony_ci cpu_usage.ru_stime.tv_sec + cpu_usage.ru_stime.tv_usec * 1e-6); /* system time */ 209f08c3bdfSopenharmony_ci delta_cpu_time = total_cpu_time - prev_cpu_time; 210f08c3bdfSopenharmony_ci 211f08c3bdfSopenharmony_ci prev_cpu_time = total_cpu_time; 212f08c3bdfSopenharmony_ci prev_time = current_time; 213f08c3bdfSopenharmony_ci 214f08c3bdfSopenharmony_ci /* calculate % cpu time each task gets */ 215f08c3bdfSopenharmony_ci if (delta_time > TIME_INTERVAL) 216f08c3bdfSopenharmony_ci mytime = 217f08c3bdfSopenharmony_ci (delta_cpu_time * 100) / (delta_time * num_cpus); 218f08c3bdfSopenharmony_ci else 219f08c3bdfSopenharmony_ci mytime = 220f08c3bdfSopenharmony_ci (delta_cpu_time * 100) / (TIME_INTERVAL * num_cpus); 221f08c3bdfSopenharmony_ci 222f08c3bdfSopenharmony_ci fprintf(stdout, "Grp:-%3d task-%3d:CPU TIME{calc:-%6.2f(s)i.e. %6.2f(%%) exp:-%6.2f(%%)}\ 223f08c3bdfSopenharmony_ciwith %3u shares in %lu (s) INTERVAL\n", mygroup_num, task_num, delta_cpu_time, 224f08c3bdfSopenharmony_ci mytime, exp_cpu_time, fmyshares, delta_time); 225f08c3bdfSopenharmony_ci 226f08c3bdfSopenharmony_ci counter++; 227f08c3bdfSopenharmony_ci 228f08c3bdfSopenharmony_ci if (counter >= NUM_INTERVALS) { /* Take n sets of readings for each shares value */ 229f08c3bdfSopenharmony_ci switch (test_num) { 230f08c3bdfSopenharmony_ci case 9: /* Test 09 */ 231f08c3bdfSopenharmony_ci exit(0); /* This task is done with its job */ 232f08c3bdfSopenharmony_ci break; 233f08c3bdfSopenharmony_ci case 10: /* Test 10 */ 234f08c3bdfSopenharmony_ci exit(0); /* This task is done with its job */ 235f08c3bdfSopenharmony_ci break; 236f08c3bdfSopenharmony_ci default: 237f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, 238f08c3bdfSopenharmony_ci "Invalid test number passed"); 239f08c3bdfSopenharmony_ci break; 240f08c3bdfSopenharmony_ci 241f08c3bdfSopenharmony_ci } /* end switch */ 242f08c3bdfSopenharmony_ci } /* end if */ 243f08c3bdfSopenharmony_ci } /* end while */ 244f08c3bdfSopenharmony_ci} /* end main */ 245