1f08c3bdfSopenharmony_ci/****************************************************************************** 2f08c3bdfSopenharmony_ci * 3f08c3bdfSopenharmony_ci * Copyright © International Business Machines Corp., 2006, 2008 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 * NAME 20f08c3bdfSopenharmony_ci * gtod_infinite.c 21f08c3bdfSopenharmony_ci * 22f08c3bdfSopenharmony_ci * DESCRIPTION 23f08c3bdfSopenharmony_ci * This 'test' is designed to run forever. It must manually be killed, 24f08c3bdfSopenharmony_ci * so it is not ideally suited tobe part of a validation suite of tests. 25f08c3bdfSopenharmony_ci * This test was initially designed to look for 'delays' between two 26f08c3bdfSopenharmony_ci * calls to clock_gettime(), and helped locate SMI induced delays on 27f08c3bdfSopenharmony_ci * several hardware platforms. 28f08c3bdfSopenharmony_ci * 29f08c3bdfSopenharmony_ci * As mentioned above, this test is designed to be run on a system for 30f08c3bdfSopenharmony_ci * an unspecified period of time. It would not be unusual to let this 31f08c3bdfSopenharmony_ci * test run for several days. 32f08c3bdfSopenharmony_ci * 33f08c3bdfSopenharmony_ci * During startup, the test will print out the 'maximum' delay between 34f08c3bdfSopenharmony_ci * clock_gettime() calls. It starts with a predefined maximum of 35f08c3bdfSopenharmony_ci * START_MAX(300ns) to eliminate noise during startup. In addition, 36f08c3bdfSopenharmony_ci * it will print out every delay that exceeds REPORT_MIN (1000000ns). 37f08c3bdfSopenharmony_ci * 38f08c3bdfSopenharmony_ci * USAGE: 39f08c3bdfSopenharmony_ci * Use run_auto.sh script in current directory to build and run test. 40f08c3bdfSopenharmony_ci * 41f08c3bdfSopenharmony_ci * AUTHOR 42f08c3bdfSopenharmony_ci * Darren Hart <dvhltc@us.ibm.com> 43f08c3bdfSopenharmony_ci * 44f08c3bdfSopenharmony_ci * HISTORY 45f08c3bdfSopenharmony_ci * 2006-Aug-17: Initial version by Darren Hart <dvhltc@us.ibm.com> 46f08c3bdfSopenharmony_ci * 47f08c3bdfSopenharmony_ci *****************************************************************************/ 48f08c3bdfSopenharmony_ci 49f08c3bdfSopenharmony_ci#include <stdio.h> 50f08c3bdfSopenharmony_ci#include <stdlib.h> 51f08c3bdfSopenharmony_ci#include <time.h> 52f08c3bdfSopenharmony_ci#include <sched.h> 53f08c3bdfSopenharmony_ci#include <librttest.h> 54f08c3bdfSopenharmony_ci#include <sys/mman.h> 55f08c3bdfSopenharmony_ci#include <unistd.h> 56f08c3bdfSopenharmony_ci#include <signal.h> 57f08c3bdfSopenharmony_ci 58f08c3bdfSopenharmony_ci#define CLOCK_TO_USE CLOCK_MONOTONIC 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_ci#define START_MAX 3000 61f08c3bdfSopenharmony_ci#define REPORT_MIN 1000000 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_cistatic unsigned int max_window = 0; /* infinite, don't use a window */ 64f08c3bdfSopenharmony_cistatic unsigned int test_duration = 0; /* infinite duration */ 65f08c3bdfSopenharmony_cistatic int test_stop = 0; /* 1 to stop */ 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_civoid usage(void) 68f08c3bdfSopenharmony_ci{ 69f08c3bdfSopenharmony_ci rt_help(); 70f08c3bdfSopenharmony_ci printf("gtod_infinite specific options:\n"); 71f08c3bdfSopenharmony_ci printf 72f08c3bdfSopenharmony_ci (" -wWINDOW iterations in max value window (default inf)\n"); 73f08c3bdfSopenharmony_ci printf(" -tDURATION test duration in finite hours (default inf)\n"); 74f08c3bdfSopenharmony_ci} 75f08c3bdfSopenharmony_ci 76f08c3bdfSopenharmony_ciint parse_args(int c, char *v) 77f08c3bdfSopenharmony_ci{ 78f08c3bdfSopenharmony_ci int handled = 1; 79f08c3bdfSopenharmony_ci switch (c) { 80f08c3bdfSopenharmony_ci case 'h': 81f08c3bdfSopenharmony_ci usage(); 82f08c3bdfSopenharmony_ci exit(0); 83f08c3bdfSopenharmony_ci case 'w': 84f08c3bdfSopenharmony_ci max_window = atoi(v); 85f08c3bdfSopenharmony_ci break; 86f08c3bdfSopenharmony_ci case 't': 87f08c3bdfSopenharmony_ci test_duration = atoi(v); 88f08c3bdfSopenharmony_ci break; 89f08c3bdfSopenharmony_ci default: 90f08c3bdfSopenharmony_ci handled = 0; 91f08c3bdfSopenharmony_ci break; 92f08c3bdfSopenharmony_ci } 93f08c3bdfSopenharmony_ci return handled; 94f08c3bdfSopenharmony_ci} 95f08c3bdfSopenharmony_ci 96f08c3bdfSopenharmony_civoid alarm_handler(int sig) 97f08c3bdfSopenharmony_ci{ 98f08c3bdfSopenharmony_ci /* Stop test execution */ 99f08c3bdfSopenharmony_ci test_stop = 1; 100f08c3bdfSopenharmony_ci} 101f08c3bdfSopenharmony_ci 102f08c3bdfSopenharmony_ciint main(int argc, char *argv[]) 103f08c3bdfSopenharmony_ci{ 104f08c3bdfSopenharmony_ci int /* i, */ rc; 105f08c3bdfSopenharmony_ci struct timespec ts, p_ts; 106f08c3bdfSopenharmony_ci nsec_t s_time, e_time, diff_time; 107f08c3bdfSopenharmony_ci nsec_t max_time = START_MAX; 108f08c3bdfSopenharmony_ci// cpu_set_t mask; 109f08c3bdfSopenharmony_ci struct sched_param param; 110f08c3bdfSopenharmony_ci time_t tt; 111f08c3bdfSopenharmony_ci unsigned int wi; 112f08c3bdfSopenharmony_ci struct sigaction sact; 113f08c3bdfSopenharmony_ci setup(); 114f08c3bdfSopenharmony_ci 115f08c3bdfSopenharmony_ci /* Set signal handler for SIGALRM */ 116f08c3bdfSopenharmony_ci sigfillset(&sact.sa_mask); 117f08c3bdfSopenharmony_ci sact.sa_handler = alarm_handler; 118f08c3bdfSopenharmony_ci rc = sigaction(SIGALRM, &sact, NULL); 119f08c3bdfSopenharmony_ci if (rc) { 120f08c3bdfSopenharmony_ci perror("sigaction"); 121f08c3bdfSopenharmony_ci exit(1); 122f08c3bdfSopenharmony_ci } 123f08c3bdfSopenharmony_ci/* 124f08c3bdfSopenharmony_ci CPU_ZERO(&mask); 125f08c3bdfSopenharmony_ci CPU_SET(0, &mask); 126f08c3bdfSopenharmony_ci rc = sched_setaffinity(0, sizeof(mask), &mask); 127f08c3bdfSopenharmony_ci if (rc) { 128f08c3bdfSopenharmony_ci perror("sched_setaffinity"); 129f08c3bdfSopenharmony_ci exit(1); 130f08c3bdfSopenharmony_ci } 131f08c3bdfSopenharmony_ci*/ 132f08c3bdfSopenharmony_ci rt_init("hw:t:", parse_args, argc, argv); 133f08c3bdfSopenharmony_ci 134f08c3bdfSopenharmony_ci mlockall(MCL_CURRENT | MCL_FUTURE); 135f08c3bdfSopenharmony_ci 136f08c3bdfSopenharmony_ci if (max_window > 0) { 137f08c3bdfSopenharmony_ci printf("%d iterations in max calculation window\n", max_window); 138f08c3bdfSopenharmony_ci } 139f08c3bdfSopenharmony_ci 140f08c3bdfSopenharmony_ci param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 80; 141f08c3bdfSopenharmony_ci rc = sched_setscheduler(0, SCHED_FIFO, ¶m); 142f08c3bdfSopenharmony_ci if (rc) { 143f08c3bdfSopenharmony_ci perror("sched_setscheduler"); 144f08c3bdfSopenharmony_ci exit(1); 145f08c3bdfSopenharmony_ci } 146f08c3bdfSopenharmony_ci 147f08c3bdfSopenharmony_ci rc = clock_gettime(CLOCK_TO_USE, &p_ts); 148f08c3bdfSopenharmony_ci if (rc) { 149f08c3bdfSopenharmony_ci perror("clock_gettime"); 150f08c3bdfSopenharmony_ci exit(1); 151f08c3bdfSopenharmony_ci } 152f08c3bdfSopenharmony_ci 153f08c3bdfSopenharmony_ci /* Set alarm for test duration, if specified */ 154f08c3bdfSopenharmony_ci if (test_duration > 0) { 155f08c3bdfSopenharmony_ci rc = alarm(test_duration * 60 * 60); 156f08c3bdfSopenharmony_ci if (rc) { 157f08c3bdfSopenharmony_ci perror("alarm"); 158f08c3bdfSopenharmony_ci exit(1); 159f08c3bdfSopenharmony_ci } 160f08c3bdfSopenharmony_ci } 161f08c3bdfSopenharmony_ci 162f08c3bdfSopenharmony_ci wi = 0; 163f08c3bdfSopenharmony_ci while (test_stop != 1) { 164f08c3bdfSopenharmony_ci rc = clock_gettime(CLOCK_TO_USE, &p_ts); 165f08c3bdfSopenharmony_ci rc = clock_gettime(CLOCK_TO_USE, &ts); 166f08c3bdfSopenharmony_ci if (rc) { 167f08c3bdfSopenharmony_ci perror("clock_gettime"); 168f08c3bdfSopenharmony_ci exit(1); 169f08c3bdfSopenharmony_ci } 170f08c3bdfSopenharmony_ci 171f08c3bdfSopenharmony_ci ts_to_nsec(&p_ts, &s_time); 172f08c3bdfSopenharmony_ci ts_to_nsec(&ts, &e_time); 173f08c3bdfSopenharmony_ci 174f08c3bdfSopenharmony_ci diff_time = e_time - s_time; 175f08c3bdfSopenharmony_ci 176f08c3bdfSopenharmony_ci if (max_window > 0 || 177f08c3bdfSopenharmony_ci ((diff_time > max_time) || (diff_time > REPORT_MIN))) { 178f08c3bdfSopenharmony_ci if (diff_time > max_time) 179f08c3bdfSopenharmony_ci max_time = diff_time; 180f08c3bdfSopenharmony_ci 181f08c3bdfSopenharmony_ci if (max_window == 0 || ++wi == max_window) { 182f08c3bdfSopenharmony_ci tt = (time_t) ts.tv_sec; 183f08c3bdfSopenharmony_ci printf("Task delayed for %lld nsec!!! %s", 184f08c3bdfSopenharmony_ci max_time, ctime(&tt)); 185f08c3bdfSopenharmony_ci fflush(stdout); 186f08c3bdfSopenharmony_ci 187f08c3bdfSopenharmony_ci if (wi == max_window) { 188f08c3bdfSopenharmony_ci max_time = 0; 189f08c3bdfSopenharmony_ci wi = 0; 190f08c3bdfSopenharmony_ci } 191f08c3bdfSopenharmony_ci } 192f08c3bdfSopenharmony_ci 193f08c3bdfSopenharmony_ci } 194f08c3bdfSopenharmony_ci } 195f08c3bdfSopenharmony_ci 196f08c3bdfSopenharmony_ci return 0; 197f08c3bdfSopenharmony_ci} 198