/* * License: GPL v2 [GNU Public License v2] * original: sched_jitter.c * 15-Jan-2004 posted to LKML by Der Herr Hofrat (der.herr@hofr.at) * 14-Apr-2005 modified and changed name to sched2.c by Atomu Hidaka (hidaka@devdrv.com) */ #include #include #include #include #include #include #include #include #include #include #include #include #include void usage(void); char *myname; __inline__ unsigned long long int hwtime(void) { unsigned long long int x; __asm__ __volatile__("rdtsc\n\t" :"=A" (x)); return x; } void usage(void) { printf("usage: %s -s tsc_scaler\n", myname); } void co_process(void) { /* always SCHED_RR process */ struct sched_param param; param.sched_priority = sched_get_priority_max(SCHED_RR); if(sched_setscheduler(getpid(),SCHED_RR,¶m)){ printf("sched_setscheduler failed - exiting\n"); exit(-1); } while(1) { usleep(500); } } #define GRAPH_SIZE 500 int main(int argc, char **argv) { int i; char *optstr = "hs:"; char c; unsigned long long graph[3][GRAPH_SIZE+1]; unsigned long long hwtime1,hwtime2,jitt; unsigned long long jitt_max[3]; unsigned long scale = 1; unsigned long policy; unsigned long long n,loops; struct sched_param param; pid_t cpid; myname = argv[0]; while ( (c = getopt(argc, argv, optstr)) != -1 ) { switch (c) { case 's': /* tsc scaling factor */ scale = strtol( optarg, NULL, 0); break; case 'h': /* verbose */ usage(); exit(0); default: fprintf(stderr,"time: Unknown option \'-%c\', exitting.\n", c); fprintf(stderr," use \'time -h\' for help\n"); exit(1); } } cpid = fork(); if (!cpid) { /* child */ co_process(); exit(0); } /* from linux/include/sched.h * #define SCHED_NORMAL 0 * #define SCHED_FIFO 1 * #define SCHED_RR 2 */ memset(graph,0,sizeof(graph)); /* just run with SCHED_FIFO and then SCHED_RR */ for(policy=0;policy<3;policy++){ //nice(-20); param.sched_priority = sched_get_priority_max(policy); // param.sched_priority = sched_get_priority_min(policy); if(sched_setscheduler(getpid(),policy,¶m)){ printf("sched_setscheduler failed - exiting\n"); exit(-1); } jitt_max[policy]=0LL; n=0LL; loops=1000000000LL; //// loops= 200000000LL; // for debug while(n < loops){ unsigned long long index=0; hwtime2 = hwtime(); hwtime1 = hwtime(); jitt=hwtime1-hwtime2; index=jitt/scale; if(index >= GRAPH_SIZE){ graph[policy][GRAPH_SIZE] += 1; } else { graph[policy][index] += 1; } if(jitt > jitt_max[policy]){ jitt_max[policy]=jitt; } n++; } } kill(cpid, SIGKILL); wait(NULL); /* dump data */ for(policy=0;policy<3;policy++){ if(jitt_max[policy]/scale < GRAPH_SIZE){ printf("\nworst case delay in run with policy %ld = %lld us\n", policy, jitt_max[policy]/scale); } else { printf("\nworst case delay in run with policy %ld = %lld us out of bounds - results are unreliable !\n", policy, jitt_max[policy]/scale); } printf("\n"); for(i=0;i= GRAPH_SIZE){ printf("OutBnd.: %16lld \n",graph[policy][GRAPH_SIZE]); } } return 0; }