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 * preempt_timing.c 21f08c3bdfSopenharmony_ci * 22f08c3bdfSopenharmony_ci * DESCRIPTION 23f08c3bdfSopenharmony_ci * This program indicated the preemption delays that may be encountered 24f08c3bdfSopenharmony_ci * by realtime apps. The program runs with the scheduling policy of 25f08c3bdfSopenharmony_ci * SCHED_FIFO at a maximum SCHED_FIFO priority. It is bound to a single 26f08c3bdfSopenharmony_ci * processor and its address space is locked as well. It makes successive 27f08c3bdfSopenharmony_ci * calls to the gettimeofday() function(via inlined assembly to read the 28f08c3bdfSopenharmony_ci * TSC).The value returned between two such consecutive calls is reported 29f08c3bdfSopenharmony_ci * as the latency. 30f08c3bdfSopenharmony_ci * The maximum, minimum and average delays are reported for x pairs of such 31f08c3bdfSopenharmony_ci * calls. 32f08c3bdfSopenharmony_ci * 33f08c3bdfSopenharmony_ci * USAGE: 34f08c3bdfSopenharmony_ci * Use run_auto.sh script in current directory to build and run test. 35f08c3bdfSopenharmony_ci * 36f08c3bdfSopenharmony_ci * AUTHOR 37f08c3bdfSopenharmony_ci * 38f08c3bdfSopenharmony_ci * 39f08c3bdfSopenharmony_ci * HISTORY 40f08c3bdfSopenharmony_ci * 41f08c3bdfSopenharmony_ci * 42f08c3bdfSopenharmony_ci *****************************************************************************/ 43f08c3bdfSopenharmony_ci 44f08c3bdfSopenharmony_ci#include <stdio.h> 45f08c3bdfSopenharmony_ci#include <stdlib.h> 46f08c3bdfSopenharmony_ci#include <unistd.h> 47f08c3bdfSopenharmony_ci#include <sys/time.h> 48f08c3bdfSopenharmony_ci#include <sys/types.h> 49f08c3bdfSopenharmony_ci#include <sched.h> 50f08c3bdfSopenharmony_ci#include <string.h> 51f08c3bdfSopenharmony_ci#include <errno.h> 52f08c3bdfSopenharmony_ci#include <sys/mman.h> 53f08c3bdfSopenharmony_ci#include <stdint.h> 54f08c3bdfSopenharmony_ci#include <librttest.h> 55f08c3bdfSopenharmony_ci 56f08c3bdfSopenharmony_ci#include "tst_tsc.h" 57f08c3bdfSopenharmony_ci 58f08c3bdfSopenharmony_ci#define ITERATIONS 1000000ULL 59f08c3bdfSopenharmony_ci#define INTERVALS 10 60f08c3bdfSopenharmony_ci 61f08c3bdfSopenharmony_civoid usage(void) 62f08c3bdfSopenharmony_ci{ 63f08c3bdfSopenharmony_ci rt_help(); 64f08c3bdfSopenharmony_ci printf("preempt_timing specific options:\n"); 65f08c3bdfSopenharmony_ci} 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_ciint parse_args(int c, char *v) 68f08c3bdfSopenharmony_ci{ 69f08c3bdfSopenharmony_ci 70f08c3bdfSopenharmony_ci int handled = 1; 71f08c3bdfSopenharmony_ci switch (c) { 72f08c3bdfSopenharmony_ci case 'h': 73f08c3bdfSopenharmony_ci usage(); 74f08c3bdfSopenharmony_ci exit(0); 75f08c3bdfSopenharmony_ci default: 76f08c3bdfSopenharmony_ci handled = 0; 77f08c3bdfSopenharmony_ci break; 78f08c3bdfSopenharmony_ci } 79f08c3bdfSopenharmony_ci return handled; 80f08c3bdfSopenharmony_ci} 81f08c3bdfSopenharmony_ci 82f08c3bdfSopenharmony_ciunsigned long long sample_list[ITERATIONS]; 83f08c3bdfSopenharmony_ciint main(int argc, char *argv[]) 84f08c3bdfSopenharmony_ci{ 85f08c3bdfSopenharmony_ci unsigned long long i, j, delta, min, max, avg; 86f08c3bdfSopenharmony_ci struct sched_param param; 87f08c3bdfSopenharmony_ci cpu_set_t mask; 88f08c3bdfSopenharmony_ci int err; 89f08c3bdfSopenharmony_ci 90f08c3bdfSopenharmony_ci#ifdef TSC_UNSUPPORTED 91f08c3bdfSopenharmony_ci printf("Error: test cannot be executed on an arch wihout TSC.\n"); 92f08c3bdfSopenharmony_ci return ENOTSUP; 93f08c3bdfSopenharmony_ci#endif 94f08c3bdfSopenharmony_ci 95f08c3bdfSopenharmony_ci max = avg = 0; 96f08c3bdfSopenharmony_ci min = -1; 97f08c3bdfSopenharmony_ci setup(); 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_ci rt_init("h", parse_args, argc, argv); 100f08c3bdfSopenharmony_ci 101f08c3bdfSopenharmony_ci /* switch to SCHED_FIFO 99 */ 102f08c3bdfSopenharmony_ci param.sched_priority = sched_get_priority_max(SCHED_FIFO); 103f08c3bdfSopenharmony_ci err = sched_setscheduler(0, SCHED_FIFO, ¶m); 104f08c3bdfSopenharmony_ci 105f08c3bdfSopenharmony_ci /* Check that the user has the appropriate privileges */ 106f08c3bdfSopenharmony_ci if (err) { 107f08c3bdfSopenharmony_ci if (errno == EPERM) { 108f08c3bdfSopenharmony_ci fprintf(stderr, 109f08c3bdfSopenharmony_ci "This program runs with a scheduling policy of SCHED_FIFO at priority %d\n", 110f08c3bdfSopenharmony_ci param.sched_priority); 111f08c3bdfSopenharmony_ci fprintf(stderr, 112f08c3bdfSopenharmony_ci "You don't have the necessary privileges to create such a real-time process.\n"); 113f08c3bdfSopenharmony_ci } else { 114f08c3bdfSopenharmony_ci fprintf(stderr, "Failed to set scheduler, errno %d\n", 115f08c3bdfSopenharmony_ci errno); 116f08c3bdfSopenharmony_ci } 117f08c3bdfSopenharmony_ci exit(1); 118f08c3bdfSopenharmony_ci } 119f08c3bdfSopenharmony_ci 120f08c3bdfSopenharmony_ci /* BIND TO A SINGLE CPU */ 121f08c3bdfSopenharmony_ci CPU_ZERO(&mask); 122f08c3bdfSopenharmony_ci CPU_SET(0, &mask); 123f08c3bdfSopenharmony_ci err = sched_setaffinity(0, sizeof(mask), &mask); 124f08c3bdfSopenharmony_ci if (err < 0) { 125f08c3bdfSopenharmony_ci printf("Can't set affinity: %d %s\n", err, strerror(err)); 126f08c3bdfSopenharmony_ci exit(-1); 127f08c3bdfSopenharmony_ci } 128f08c3bdfSopenharmony_ci 129f08c3bdfSopenharmony_ci for (j = 0; j < INTERVALS; j++) { 130f08c3bdfSopenharmony_ci /* Collect samples */ 131f08c3bdfSopenharmony_ci for (i = 0; i < ITERATIONS; i++) 132f08c3bdfSopenharmony_ci rdtscll(sample_list[i]); 133f08c3bdfSopenharmony_ci 134f08c3bdfSopenharmony_ci /* Process samples */ 135f08c3bdfSopenharmony_ci for (i = 0; i < (ITERATIONS - 1); i++) { 136f08c3bdfSopenharmony_ci delta = sample_list[i + 1] - sample_list[i]; 137f08c3bdfSopenharmony_ci if (delta < min) 138f08c3bdfSopenharmony_ci min = delta; 139f08c3bdfSopenharmony_ci if (delta > max) 140f08c3bdfSopenharmony_ci max = delta; 141f08c3bdfSopenharmony_ci if (delta > 100000) 142f08c3bdfSopenharmony_ci printf("maxd(%llu:%llu): %llu %llu = %llu\n", j, 143f08c3bdfSopenharmony_ci i, sample_list[i], sample_list[i + 1], 144f08c3bdfSopenharmony_ci delta); 145f08c3bdfSopenharmony_ci avg += delta; 146f08c3bdfSopenharmony_ci } 147f08c3bdfSopenharmony_ci usleep(100); /*let necessary things happen */ 148f08c3bdfSopenharmony_ci } 149f08c3bdfSopenharmony_ci avg /= (ITERATIONS * INTERVALS); 150f08c3bdfSopenharmony_ci 151f08c3bdfSopenharmony_ci printf("%lld pairs of gettimeofday() calls completed\n", 152f08c3bdfSopenharmony_ci ITERATIONS * INTERVALS); 153f08c3bdfSopenharmony_ci printf("Time between calls:\n"); 154f08c3bdfSopenharmony_ci printf("Minimum: %llu \n", min); 155f08c3bdfSopenharmony_ci printf("Maximum: %llu \n", max); 156f08c3bdfSopenharmony_ci printf("Average: %llu \n", avg); 157f08c3bdfSopenharmony_ci 158f08c3bdfSopenharmony_ci return 0; 159f08c3bdfSopenharmony_ci} 160