diff options
Diffstat (limited to 'jittertest/JitterTest.c')
-rw-r--r-- | jittertest/JitterTest.c | 1044 |
1 files changed, 0 insertions, 1044 deletions
diff --git a/jittertest/JitterTest.c b/jittertest/JitterTest.c deleted file mode 100644 index 13c64d9..0000000 --- a/jittertest/JitterTest.c +++ /dev/null @@ -1,1044 +0,0 @@ -/*********************************************************************** - * - * Copyright: Daniel Measurement and Control, Inc. - * 9753 Pine Lake Drive - * Houston, TX 77055 - * - * Created by: Vipin Malik and Gail Murray - * Released under GPL by permission of Daniel Industries. - * - * This software is licensed under the GPL version 2. Plese see the file - * COPYING for details on the license. - * - * NO WARRANTY: Absolutely no claims of warranty or fitness of purpose - * are made in this software. Please use at your own risk. - * - * Filename: JitterTest.c - * - * Description: Program to be used to measure wake jitter. - * See README file for more info. - * - * - * Revision History: - * $Id: JitterTest.c,v 1.13 2005/11/07 11:15:20 gleixner Exp $ - * $Log: JitterTest.c,v $ - * Revision 1.13 2005/11/07 11:15:20 gleixner - * [MTD / JFFS2] Clean up trailing white spaces - * - * Revision 1.12 2001/08/10 19:23:11 vipin - * Ready to be released under GPL! Added proper headers etc. - * - * Revision 1.11 2001/07/09 15:35:50 vipin - * Couple of new features:1. The program runs by default as a "regular" - * (SCHED_OTHER) task by default, unless the -p n cmd line parameter is - * specified. It then runs as SCHED_RR at that priority. - * 2. Added ability to send SIGSTOP/SIGCONT to a specified PID. This - * would presumably be the PID of the JFFS2 GC task. SIGSTOP is sent - * before writing to the fs, and a SIGCONT after the write is done. - * 3. The "pad" data now written to the file on the "fs under test" is - * random, not sequential as previously. - * - * Revision 1.10 2001/06/27 19:14:24 vipin - * Now console file to log at can be specified from cmd line. This can enable - * you to run two instances of the program- one logging to the /dev/console - * and another to a regular file (if you want the data) or /dev/null if you don't. - * - * Revision 1.9 2001/06/25 20:21:31 vipin - * This is the latest version, NOT the one last checked in! - * - * Revision 1.7 2001/06/18 22:36:19 vipin - * Fix minor typo that excluded '\n' from msg on console. - * - * Revision 1.6 2001/06/18 21:17:50 vipin - * Added option to specify the amount of data written to outfile each period. - * The regular info is written, but is then padded to the requested size. - * This will enable testing of different sized writes to JFFS fs. - * - * Revision 1.5 2001/06/08 19:36:23 vipin - * All write() are now checked for return err code. - * - * Revision 1.4 2001/06/06 23:10:31 vipin - * Added README file. - * In JitterTest.c: Changed operation of periodic timer to one shot. The timer is now - * reset when the task wakes. This way every "jitter" is from the last time and - * jitters from previous times are not accumulated and screw aroud with our display. - * - * All jitter is now +ve. (as it should be). Also added a "read file" functionality - * to test for jitter in task if we have to read from JFFS fs. - * The program now also prints data to console- where it can be logged, interspersed with - * other "interesting" printk's from the kernel and drivers (flash sector erases etc.) - * - * Revision 1.3 2001/03/01 19:20:39 gmurray - * Add priority scheduling. Shortened name of default output file. - * Changed default interrupt period. Output delta time and jitter - * instead of time of day. - * - * Revision 1.2 2001/02/28 16:20:19 vipin - * Added version control Id and log fields. - * - ***********************************************************************/ -/*************************** Included Files ***************************/ -#include <stdio.h> /* fopen, printf, fprintf, fclose */ -#include <string.h> /* strcpy, strcmp */ -#include <stdlib.h> /* exit, atol, atoi */ -#include <sys/time.h> /* setitimer, settimeofday, gettimeofday */ -#include <signal.h> /* signal */ -#include <sched.h> /* sched_setscheduler, sched_get_priority_min,*/ -/* sched_get_priority_max */ -#include <unistd.h> /* gettimeofday, sleep */ -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/mman.h> - - - -/**************************** Enumerations ****************************/ -enum timerActions - { - ONESHOT, - AUTORESETTING - }; - - - -/****************************** Constants *****************************/ -/* Exit error codes */ -#define EXIT_FILE_OPEN_ERR (1) /* error opening output file*/ -#define EXIT_REG_SIGALRM_ERR (2) /* error registering SIGALRM*/ -#define EXIT_REG_SIGINT_ERR (3) /* error registering SIGINT */ -#define EXIT_INV_INT_PERIOD (4) /* error invalid int. period*/ -#define EXIT_MIN_PRIORITY_ERR (5) /* error, minimum priority */ -#define EXIT_MAX_PRIORITY_ERR (6) /* error, maximum priority */ -#define EXIT_INV_SCHED_PRIORITY (7) /* error, invalid priority */ -#define EXIT_SET_SCHEDULER_ERR (8) /* error, set scheduler */ -#define EXIT_PREV_TIME_OF_DAY_ERR (9) /* error, init. prev. */ -/* time of day */ - -#define MAX_FILE_NAME_LEN (32) /* maximum file name length */ - -#define STRINGS_EQUAL ((int) 0) /* strcmp value if equal */ - -#define MIN_INT_PERIOD_MILLISEC ( 5L) /* minimum interrupt period */ -#define MAX_INT_PERIOD_MILLISEC (5000L) /* maximum interrupt period */ -#define DEF_INT_PERIOD_MILLISEC ( 10L) /* default interrupt period */ - -#define READ_FILE_MESSAGE "This is a junk file. Must contain at least 1 byte though!\n" - -/* The user can specify that the program pad out the write file to - a given number of bytes. But a minimum number needs to be written. This - will contain the jitter info. -*/ -#define MIN_WRITE_BYTES 30 -#define DEFAULT_WRITE_BYTES 30 -#define MAX_WRITE_BYTES 4096 - -/* used for gen a printable ascii random # between spc and '~' */ -#define MIN_ASCII 32 /* <SPACE> can be char*/ -#define MAX_ASCII 126.0 /* needs to be float. See man rand() */ - -/*---------------------------------------------------------------------- - * It appears that the preprocessor can't handle multi-line #if - * statements. Thus, the check on the default is divided into two - * #if statements. - *---------------------------------------------------------------------*/ -#if (DEF_INT_PERIOD_MILLISEC < MIN_INT_PERIOD_MILLISEC) -#error *** Invalid default interrupt period. *** -#endif - -#if (DEF_INT_PERIOD_MILLISEC > MAX_INT_PERIOD_MILLISEC) -#error *** Invalid default interrupt period. *** -#endif - - -#define TRUE 1 /* Boolean true value */ -#define FALSE 0 - -/* Time conversion constants. */ -#define MILLISEC_PER_SEC (1000L) /* milliseconds per second */ -#define MICROSEC_PER_MILLISEC (1000L) /* microsecs per millisec */ -#define MICROSEC_PER_SEC (1000000L) /* microsecs per second */ - -#define PRIORITY_POLICY ((int) SCHED_RR) /* If specified iwth "-p" */ - - - -/************************** Module Variables **************************/ -/* version identifier (value supplied by CVS)*/ -static const char Version[] = "$Id: JitterTest.c,v 1.13 2005/11/07 11:15:20 gleixner Exp $"; - -static char OutFileName[MAX_FILE_NAME_LEN+1]; /* output file name */ -static char LogFile[MAX_FILE_NAME_LEN+1] = "/dev/console"; /* default */ -static char ReadFile[MAX_FILE_NAME_LEN+1]; /* This file is read. Should - contain at least 1 byte */ - -static int WriteBytes = DEFAULT_WRITE_BYTES; /* pad out file to these many bytes. */ -static int Fd1; /* fd where the above buffer if o/p */ -static int Cfd; /* fd to console (or file specified) */ -static int Fd2; /* fd for the ReadFile */ -static int DoRead = FALSE; /* should we attempt to ReadFile?*/ -static long InterruptPeriodMilliSec; /* interrupt period, millisec */ -static int MinPriority; /* minimum scheduler priority */ -static int MaxPriority; /* maximum scheduler priority */ -static int RequestedPriority; /* requested priority */ -static struct itimerval ITimer; /* interrupt timer structure */ -static struct timeval PrevTimeVal; /* previous time structure */ -static struct timeval CurrTimeVal; /* current time structure */ -static long LastMaxDiff = 0; /* keeps track of worst jitter encountered */ - -static int GrabKProfile = FALSE; /* To help determine system bottle necks - this parameter can be set. This causes - the /proc/profile file to be read and - stored in unique filenames in current - dir, and indication to be o/p on the - /dev/console also. - */ -static long ProfileTriggerMSecs = 15000l; /* Jitter time in seconds that triggers - a snapshot of the profile to be taken - - */ -static int SignalGCTask = FALSE; /* should be signal SIGSTOP/SIGCONT to gc task?*/ -static int GCTaskPID; - -static int RunAsRTTask = FALSE; /* default action unless priority is - specified on cmd line */ - - -/********************* Local Function Prototypes **********************/ -void HandleCmdLineArgs(int argc, char *argv[]); -void SetFileName(char * pFileName); -void SetInterruptPeriod(char * pASCIIInterruptPeriodMilliSec); -void SetSchedulerPriority(char * pASCIISchedulerPriority); - -void PrintVersionInfo(void); -void PrintHelpInfo(void); - -int Write(int fd, void *buf, size_t bytes, int lineNo); - -void InitITimer(struct itimerval * pITimer, int action); - -/* For catching timer interrupts (SIGALRM). */ -void AlarmHandler(int sigNum); - -/* For catching Ctrl+C SIGINT. */ -void SignalHandler(int sigNum); - - - -/*********************************************************************** - * main function - * return: exit code - ***********************************************************************/ -int main( - int argc, - char *argv[]) -{ - struct sched_param schedParam; - - int mypri; - char tmpBuf[200]; - - - strcpy(OutFileName,"jitter.dat"); - InterruptPeriodMilliSec = MIN_INT_PERIOD_MILLISEC; - - /* Get the minimum and maximum priorities. */ - MinPriority = sched_get_priority_min(PRIORITY_POLICY); - MaxPriority = sched_get_priority_max(PRIORITY_POLICY); - if (MinPriority == -1) { - printf("\n*** Unable to get minimum priority. ***\n"); - exit(EXIT_MIN_PRIORITY_ERR); - } - if (MaxPriority == -1) { - printf("\n*** Unable to get maximum priority. ***\n"); - exit(EXIT_MAX_PRIORITY_ERR); - } - - /* Set requested priority to minimum value as default. */ - RequestedPriority = MinPriority; - - HandleCmdLineArgs(argc, argv); - - if(mlockall(MCL_CURRENT|MCL_FUTURE) < 0){ - printf("Could not lock task into memory. Bye\n"); - perror("Error"); - } - - if(RunAsRTTask){ - - /* Set the priority. */ - schedParam.sched_priority = RequestedPriority; - if (sched_setscheduler( - 0, - PRIORITY_POLICY, - &schedParam) != (int) 0) { - printf("Exiting: Unsuccessful sched_setscheduler.\n"); - close(Fd1); - exit(EXIT_SET_SCHEDULER_ERR); - } - - - /* Double check as I have some doubts that it's really - running at realtime priority! */ - if((mypri = sched_getscheduler(0)) != RequestedPriority) - { - printf("Not running with request priority %i. running with priority %i instead!\n", - RequestedPriority, mypri); - }else - { - printf("Running with %i priority. Good!\n", mypri); - } - - } - - /*------------------------- Initializations --------------------------*/ - if((Fd1 = open(OutFileName, O_RDWR|O_CREAT|O_SYNC)) <= 0) - { - perror("Cannot open outfile for write:"); - exit(1); - } - - /* If a request is made to read from a specified file, then create that - file and fill with junk data so that there is something there to read. - */ - if(DoRead) - { - - if((Fd2 = open(ReadFile, O_RDWR|O_CREAT|O_SYNC|O_TRUNC)) <= 0) - { - perror("cannot open read file:"); - exit(1); - }else - { - - /* Don't really care how much we write here */ - if(write(Fd2, READ_FILE_MESSAGE, strlen(READ_FILE_MESSAGE)) < 0) - { - perror("Problems writing to readfile:"); - exit(1); - } - lseek(Fd2, 0, SEEK_SET); /* position back to byte #0 */ - } - } - - - - /* Also log output to console. This way we can capture it - on a serial console to a log file. - */ - if((Cfd = open(LogFile, O_WRONLY|O_SYNC)) <= 0) - { - perror("cannot open o/p logfile:"); - exit(1); - } - - - /* Set-up handler for periodic interrupt. */ - if (signal(SIGALRM, &AlarmHandler) == SIG_ERR) { - printf("Couldn't register signal handler for SIGALRM.\n"); - sprintf(tmpBuf, - "Couldn't register signal handler for SIGALRM.\n"); - Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); - - close(Fd1); - exit(EXIT_REG_SIGALRM_ERR); - } - - /* Set-up handler for Ctrl+C to exit the program. */ - if (signal(SIGINT, &SignalHandler) == SIG_ERR) { - printf("Couldn't register signal handler for SIGINT.\n"); - sprintf(tmpBuf, - "Couldn't register signal handler for SIGINT.\n"); - Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); - - close(Fd1); - exit(EXIT_REG_SIGINT_ERR); - } - - printf("Press Ctrl+C to exit the program.\n"); - printf("Output File: %s\n", OutFileName); - printf("Scheduler priority: %d\n", RequestedPriority); - sprintf(tmpBuf, "\nScheduler priority: %d\n", - RequestedPriority); - Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); - - Write(Cfd, tmpBuf, strlen(tmpBuf), __LINE__); - - printf("Interrupt period: %ld milliseconds\n", - InterruptPeriodMilliSec); - sprintf(tmpBuf, "Interrupt period: %ld milliseconds\n", - InterruptPeriodMilliSec); - - Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); - - Write(Cfd, tmpBuf, strlen(tmpBuf), __LINE__); - - - fflush(0); - - - - /* Initialize the periodic timer. */ - InitITimer(&ITimer, ONESHOT); - - /* Initialize "previous" time. */ - if (gettimeofday(&PrevTimeVal, NULL) != (int) 0) { - printf("Exiting - "); - printf("Unable to initialize previous time of day.\n"); - sprintf(tmpBuf, "Exiting - "); - Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); - - sprintf(tmpBuf, - "Unable to initialize previous time of day.\n"); - - Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); - - } - - /* Start the periodic timer. */ - setitimer(ITIMER_REAL, &ITimer, NULL); - - - while(TRUE) { /* Intentional infinite loop. */ - /* Sleep for one second. */ - sleep((unsigned int) 1); - } - - /* Just in case. File should be closed in SignalHandler. */ - close(Fd1); - close(Cfd); - - return 0; -} - - - - -/*********************************************************************** - * SignalHandler - * This is a handler for the SIGINT signal. It is assumed that the - * SIGINT is due to the user pressing Ctrl+C to halt the program. - * output: N/A - ***********************************************************************/ -void SignalHandler( - int sigNum) -{ - - char tmpBuf[200]; - - /* Note sigNum not used. */ - printf("Ctrl+C detected. Worst Jitter time was:%fms.\nJitterTest exiting.\n", - (float)LastMaxDiff/1000.0); - - sprintf(tmpBuf, - "\nCtrl+C detected. Worst Jitter time was:%fms\nJitterTest exiting.\n", - (float)LastMaxDiff/1000.0); - Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); - - Write(Cfd, tmpBuf, strlen(tmpBuf), __LINE__); - - close(Fd1); - close(Cfd); - exit(0); -} - - - - - -/* - A snapshot of the /proc/profile needs to be taken. - This is stored as a new file every time, and the - stats reset by doing a (any) write to the /proc/profile - file. - */ -void doGrabKProfile(int jitterusec, char *fileName) -{ - int fdSnapshot; - int fdProfile; - int readBytes; - char readBuf[4096]; - - if((fdSnapshot = open(fileName, O_WRONLY | O_CREAT)) <= 0) - { - fprintf(stderr, "Could not open file %s.\n", fileName); - perror("Error:"); - return; - } - - if((fdProfile = open("/proc/profile", O_RDWR)) <= 0) - { - fprintf(stderr, "Could not open file /proc/profile. Make sure you booted with profile=2\n"); - close(fdSnapshot); - return; - } - - while((readBytes = read(fdProfile, readBuf, sizeof(readBuf))) > 0) - { - write(fdSnapshot, readBuf, readBytes); - } - - close(fdSnapshot); - - if(write(fdProfile, readBuf, 1) != 1) - { - perror("Could Not clear profile by writing to /proc/profile:"); - } - - close(fdProfile); - - - -}/* end doGrabKProfile()*/ - - -/* - Call this routine to clear the kernel profiling buffer /proc/profile -*/ -void clearProfileBuf(void){ - - - int fdProfile; - char readBuf[10]; - - - if((fdProfile = open("/proc/profile", O_RDWR)) <= 0) - { - fprintf(stderr, "Could not open file /proc/profile. Make sure you booted with profile=2\n"); - return; - } - - - if(write(fdProfile, readBuf, 1) != 1) - { - perror("Could Not clear profile by writing to /proc/profile:"); - } - - close(fdProfile); - - -}/* end clearProfileBuf() */ - - - - - -/*********************************************************************** - * AlarmHandler - * This is a handler for the SIGALRM signal (due to the periodic - * timer interrupt). It prints the time (seconds) to - * the output file. - * output: N/A - ***********************************************************************/ -void AlarmHandler( - int sigNum) /* signal number (not used) */ -{ - - long timeDiffusec; /* diff time in micro seconds */ - long intervalusec; - - - char tmpBuf[MAX_WRITE_BYTES]; - int cntr; - char padChar; - - static int profileFileNo = 0; - char profileFileName[150]; - - static int seedStarter = 0; /* carries over rand info to next time - where time() will be the same as this time - if invoked < 1sec apart. - */ - - if (gettimeofday(&CurrTimeVal, NULL) == (int) 0) { - - /*---------------------------------------------------------------- - * Compute the elapsed time between the current and previous - * time of day values and store the result. - * - * Print the elapsed time to the output file. - *---------------------------------------------------------------*/ - - timeDiffusec = (long)(((((long long)CurrTimeVal.tv_sec) * 1000000L) + CurrTimeVal.tv_usec) - - (((long long)PrevTimeVal.tv_sec * 1000000L) + PrevTimeVal.tv_usec)); - - sprintf(tmpBuf," %f ms ", (float)timeDiffusec/1000.0); - - intervalusec = InterruptPeriodMilliSec * 1000L; - - timeDiffusec = timeDiffusec - intervalusec; - - sprintf(&tmpBuf[strlen(tmpBuf)]," %f ms", (float)timeDiffusec/1000.0); - - - /* should we send a SIGSTOP/SIGCONT to the specified PID? */ - if(SignalGCTask){ - - if(kill(GCTaskPID, SIGSTOP) < 0){ - - perror("error:"); - } - } - - - /* Store some historical #'s */ - if(abs(timeDiffusec) > LastMaxDiff) - { - LastMaxDiff = abs(timeDiffusec); - sprintf(&tmpBuf[strlen(tmpBuf)],"!"); - - if((GrabKProfile == TRUE) && (ProfileTriggerMSecs < (abs(timeDiffusec)/1000))) - { - sprintf(profileFileName, "JitterTest.profilesnap-%i", profileFileNo); - - /* go and grab the kernel performance profile. */ - doGrabKProfile(timeDiffusec, profileFileName); - profileFileNo++; /* unique name next time */ - - /* Say so on the console so that a marker gets put in the console log */ - sprintf(&tmpBuf[strlen(tmpBuf)],"<Profile saved in file:%s>", - profileFileName); - - } - - } - - - - - sprintf(&tmpBuf[strlen(tmpBuf)],"\n"); /* CR for the data going out of the console */ - - Write(Cfd, tmpBuf, strlen(tmpBuf), __LINE__); - - - /* The "-1" below takes out the '\n' at the end that we appended for the msg printed on - the console.*/ - sprintf(&tmpBuf[strlen(tmpBuf)-1]," PadBytes:"); - - /* Now pad the output file if requested by user. */ - if(WriteBytes > MIN_WRITE_BYTES) - { - - /* start from a new place every time */ - srand(time(NULL) + seedStarter); - - /* already written MIN_WRITE_BYTES by now */ - for(cntr = strlen(tmpBuf); cntr < WriteBytes - 1 ; cntr++) /* "-1" adj for '\n' at end */ - { - /* don't accept any # < 'SPACE' */ - padChar = (char)(MIN_ASCII+(int)((MAX_ASCII-(float)MIN_ASCII)*rand()/(RAND_MAX+1.0))); - - - /* - padChar = (cntr % (126-33)) + 33; - */ - - tmpBuf[cntr] = padChar; - } - - seedStarter = tmpBuf[cntr-1]; /* save for next time */ - - tmpBuf[cntr] = '\n'; /* CR for the data going into the outfile. */ - tmpBuf[cntr+1] = '\0'; /* NULL terminate the string */ - } - - /* write out the entire line to the output file. */ - Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); - - - /* Read a byte from the specified file */ - if(DoRead) - { - - read(Fd2, tmpBuf, 1); - lseek(Fd2, 0, SEEK_SET); /* back to start */ - } - - - /* Start the periodic timer again. */ - setitimer(ITIMER_REAL, &ITimer, NULL); - - - /* Update previous time with current time. */ - PrevTimeVal.tv_sec = CurrTimeVal.tv_sec; - PrevTimeVal.tv_usec = CurrTimeVal.tv_usec; - } - - else { - sprintf(tmpBuf, "gettimeofday error \n"); - Write(Fd1, tmpBuf, strlen(tmpBuf), __LINE__); - - printf("gettimeofday error \n"); - } - - /* now clear the profiling buffer */ - if(GrabKProfile == TRUE){ - - clearProfileBuf(); - } - - /* should we send a SIGSTOP/SIGCONT to the specified PID? */ - if(SignalGCTask){ - - if(kill(GCTaskPID, SIGCONT) < 0){ - - perror("error:"); - } - } - - - return; -} - - - -/*********************************************************************** - * InitITimer - * This function initializes the 'struct itimerval' structure whose - * address is passed to interrupt every InterruptPeriodMilliSec. - * output: N/A - ***********************************************************************/ -void InitITimer( - struct itimerval * pITimer, /* pointer to interrupt timer struct*/ - int action) /* ONESHOT or autosetting? */ -{ - long seconds; /* seconds portion of int. period */ - long microSeconds; /* microsec. portion of int. period */ - - /*-------------------------------------------------------------------- - * Divide the desired interrupt period into its seconds and - * microseconds components. - *-------------------------------------------------------------------*/ - if (InterruptPeriodMilliSec < MILLISEC_PER_SEC) { - seconds = 0L; - microSeconds = InterruptPeriodMilliSec * MICROSEC_PER_MILLISEC; - } - else { - seconds = InterruptPeriodMilliSec / MILLISEC_PER_SEC; - microSeconds = - (InterruptPeriodMilliSec - (seconds * MILLISEC_PER_SEC)) * - MICROSEC_PER_MILLISEC; - } - - /* Initialize the interrupt period structure. */ - pITimer->it_value.tv_sec = seconds; - pITimer->it_value.tv_usec = microSeconds; - - if(action == ONESHOT) - { - /* This will (should) prevent the timer from restarting itself */ - pITimer->it_interval.tv_sec = 0; - pITimer->it_interval.tv_usec = 0; - }else - { - pITimer->it_interval.tv_sec = seconds; - pITimer->it_interval.tv_usec = microSeconds; - - } - - return; -} - - -/*********************************************************************** - * HandleCmdLineArgs - * This function handles the command line arguments. - * output: stack size - ***********************************************************************/ -void HandleCmdLineArgs( - int argc, /* number of command-line arguments */ - char *argv[]) /* ptrs to command-line arguments */ -{ - int argNum; /* argument number */ - - if (argc > (int) 1) { - - for (argNum = (int) 1; argNum < argc; argNum++) { - - /* The command line contains an argument. */ - - if ((strcmp(argv[argNum],"--version") == STRINGS_EQUAL) || - (strcmp(argv[argNum],"-v") == STRINGS_EQUAL)) { - /* Print version information and exit. */ - PrintVersionInfo(); - exit(0); - } - - else if ((strcmp(argv[argNum],"--help") == STRINGS_EQUAL) || - (strcmp(argv[argNum],"-h") == STRINGS_EQUAL) || - (strcmp(argv[argNum],"-?") == STRINGS_EQUAL)) { - /* Print help information and exit. */ - PrintHelpInfo(); - exit(0); - } - - else if ((strcmp(argv[argNum],"--file") == STRINGS_EQUAL) || - (strcmp(argv[argNum],"-f") == STRINGS_EQUAL)) { - /* Set the name of the output file. */ - ++argNum; - if (argNum < argc) { - SetFileName(argv[argNum]); - } - else { - printf("*** Output file name not specified. ***\n"); - printf("Default output file name will be used.\n"); - } - } - - else if ((strcmp(argv[argNum],"--time") == STRINGS_EQUAL) || - (strcmp(argv[argNum],"-t") == STRINGS_EQUAL)) { - /* Set the interrupt period. */ - ++argNum; - if (argNum < argc) { - SetInterruptPeriod(argv[argNum]); - } - else { - printf("*** Interrupt period not specified. ***\n"); - printf("Default interrupt period will be used.\n"); - } - - } - - else if ((strcmp(argv[argNum],"--priority") == - STRINGS_EQUAL) || - (strcmp(argv[argNum],"-p") == STRINGS_EQUAL)) { - /* Set the scheduler priority. */ - ++argNum; - if (argNum < argc) { - SetSchedulerPriority(argv[argNum]); - } - else { - printf("*** Scheduler priority not specified. ***\n"); - printf("Default scheduler priority will be used.\n"); - } - - } - - else if ((strcmp(argv[argNum],"--readfile") == - STRINGS_EQUAL) || - (strcmp(argv[argNum],"-r") == STRINGS_EQUAL)) { - /* Set the file to read*/ - ++argNum; - - strncpy(ReadFile, argv[argNum], sizeof(ReadFile)); - DoRead = TRUE; - } - - else if ((strcmp(argv[argNum],"--write_bytes") == - STRINGS_EQUAL) || - (strcmp(argv[argNum],"-w") == STRINGS_EQUAL)) { - /* Set the file to read*/ - ++argNum; - - WriteBytes = atoi(argv[argNum]); - - if(WriteBytes < MIN_WRITE_BYTES) - { - printf("Writing less than %i bytes is not allowed. Bye.\n", - MIN_WRITE_BYTES); - exit(0); - } - - - } - - else if ((strcmp(argv[argNum],"--consolefile") == - STRINGS_EQUAL) || - (strcmp(argv[argNum],"-c") == STRINGS_EQUAL)) { - /* Set the file to log console log on. */ - ++argNum; - - strncpy(LogFile, argv[argNum], sizeof(LogFile)); - } - - else if ((strcmp(argv[argNum],"--grab_kprofile") == - STRINGS_EQUAL)) - { - /* We will read the /proc/profile file on configurable timeout */ - GrabKProfile = TRUE; - - ++argNum; - - /* If the jittter is > this #, then the profile is grabbed. */ - ProfileTriggerMSecs = (long) atoi(argv[argNum]); - - if(ProfileTriggerMSecs <= 0){ - - printf("Illegal value for profile trigger threshold.\n"); - exit(0); - } - } - - else if ((strcmp(argv[argNum],"--siggc") == - STRINGS_EQUAL)) - { - /* We will SIGSTOP/SIGCONT the specified pid */ - SignalGCTask = TRUE; - - ++argNum; - - GCTaskPID = atoi(argv[argNum]); - - if(ProfileTriggerMSecs <= 0){ - - printf("Illegal value for JFFS(2) GC task pid.\n"); - exit(0); - } - } - - - else { - /* Unknown argument. Print help information and exit. */ - printf("Invalid option %s\n", argv[argNum]); - printf("Try 'JitterTest --help' for more information.\n"); - exit(0); - } - } - } - - return; -} - - -/*********************************************************************** - * SetFileName - * This function sets the output file name. - * output: N/A - ***********************************************************************/ -void SetFileName( - char * pFileName) /* ptr to desired output file name */ -{ - size_t fileNameLen; /* file name length (bytes) */ - - /* Check file name length. */ - fileNameLen = strlen(pFileName); - if (fileNameLen > (size_t) MAX_FILE_NAME_LEN) { - printf("File name %s exceeds maximum length %d.\n", - pFileName, MAX_FILE_NAME_LEN); - exit(0); - } - - /* File name length is OK so save the file name. */ - strcpy(OutFileName, pFileName); - - return; -} - - -/*********************************************************************** - * SetInterruptPeriod - * This function sets the interrupt period. - * output: N/A - ***********************************************************************/ -void SetInterruptPeriod( - char * /* ptr to desired interrupt period */ - pASCIIInterruptPeriodMilliSec) -{ - long period; /* interrupt period */ - - period = atol(pASCIIInterruptPeriodMilliSec); - if ((period < MIN_INT_PERIOD_MILLISEC) || - (period > MAX_INT_PERIOD_MILLISEC)) { - printf("Invalid interrupt period: %ld ms.\n", period); - exit(EXIT_INV_INT_PERIOD); - } - else { - InterruptPeriodMilliSec = period; - } - return; -} - - -/*********************************************************************** - * SetSchedulerPriority - * This function sets the desired scheduler priority. - * output: N/A - ***********************************************************************/ -void SetSchedulerPriority( - char * pASCIISchedulerPriority) /* ptr to desired scheduler priority*/ -{ - int priority; /* desired scheduler priority value */ - - priority = atoi(pASCIISchedulerPriority); - if ((priority < MinPriority) || - (priority > MaxPriority)) { - printf("Scheduler priority %d outside of range [%d, %d]\n", - priority, MinPriority, MaxPriority); - exit(EXIT_INV_SCHED_PRIORITY); - } - else { - RequestedPriority = priority; - RunAsRTTask = TRUE; /* We shall run as a POSIX real time task */ - } - return; -} - - -/*********************************************************************** - * PrintVersionInfo - * This function prints version information. - * output: N/A - ***********************************************************************/ -void PrintVersionInfo(void) -{ - printf("JitterTest version %s\n", Version); - printf("Copyright (c) 2001, Daniel Industries, Inc.\n"); - return; -} - - -/*********************************************************************** - * PrintHelpInfo - * This function prints help information. - * output: N/A - ***********************************************************************/ -void PrintHelpInfo(void) -{ - printf("Usage: JitterTest [options]\n"); - printf(" *** Requires root privileges. ***\n"); - printf("Option:\n"); - printf(" [-h, --help, -?] Print this message and exit.\n"); - printf(" [-v, --version] "); - printf( "Print the version number of JitterTest and exit.\n"); - printf(" [-f FILE, --file FILE] Set output file name to FILE. Typically you would put this on the fs under test\n"); - printf(" [-c FILE, --consolefile] Set device or file to write the console log to.\n\tTypically you would set this to /dev/console and save it on another computer.\n"); - printf(" [-w BYTES, --write_bytes BYTES Write BYTES to FILE each period.\n"); - printf(" [-r FILE, --readfile FILE] Also read 1 byte every cycle from FILE. FILE will be created and filled with data.\n"); - printf(" [-t <n>, --time <n>] "); - printf( "Set interrupt period to <n> milliseconds.\n"); - printf(" "); - printf( "Range: [%ld, %ld] milliseconds.\n", - MIN_INT_PERIOD_MILLISEC, MAX_INT_PERIOD_MILLISEC); - printf(" [-p <n>, --priority <n>] "); - printf( "Set scheduler priority to <n>.\n"); - printf(" "); - printf( "Range: [%d, %d] (higher number = higher priority)\n", - MinPriority, MaxPriority); - printf(" [--grab_kprofile <THRESHOLD in ms>] Read the /proc/profile if jitter is > THRESHOLD and store in file.\n"); - printf(" [--siggc <PID>] Before writing to fs send SIGSTOP to PID. After write send SIGCONT\n"); - return; - -} - - -/* A common write that checks for write errors and exits. Pass it __LINE__ for lineNo */ -int Write(int fd, void *buf, size_t bytes, int lineNo) -{ - - int err; - - err = write(fd, buf, bytes); - - if(err < bytes) - { - - printf("Write Error at line %i! Wanted to write %i bytes, but wrote only %i bytes.\n", - lineNo, bytes, err); - perror("Write did not complete. Error. Bye:"); /* show error from errno. */ - exit(1); - - } - - return err; - -}/* end Write*/ |