diff options
| author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2008-01-16 17:38:44 +0200 | 
|---|---|---|
| committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2008-01-16 17:38:44 +0200 | 
| commit | f3f219527f69d581a1839e93b749c29545eb0119 (patch) | |
| tree | b8604340671673911f6a0c94d843785081c7bdb9 /jittertest | |
| parent | d78b73e2ca216777e17066091ef449e9cdaffae7 (diff) | |
tests: move jittertest to tests directory
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'jittertest')
| -rw-r--r-- | jittertest/COPYING | 340 | ||||
| -rw-r--r-- | jittertest/JitterTest.c | 1044 | ||||
| -rw-r--r-- | jittertest/Makefile | 46 | ||||
| -rw-r--r-- | jittertest/README | 197 | ||||
| -rw-r--r-- | jittertest/filljffs2.sh | 16 | ||||
| -rw-r--r-- | jittertest/plotJittervsFill.c | 312 | 
6 files changed, 0 insertions, 1955 deletions
diff --git a/jittertest/COPYING b/jittertest/COPYING deleted file mode 100644 index 60549be..0000000 --- a/jittertest/COPYING +++ /dev/null @@ -1,340 +0,0 @@ -		    GNU GENERAL PUBLIC LICENSE -		       Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. -                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -			    Preamble - -  The licenses for most software are designed to take away your -freedom to share and change it.  By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users.  This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it.  (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.)  You can apply it to -your programs, too. - -  When we speak of free software, we are referring to freedom, not -price.  Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - -  To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - -  For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have.  You must make sure that they, too, receive or can get the -source code.  And you must show them these terms so they know their -rights. - -  We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - -  Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software.  If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - -  Finally, any free program is threatened constantly by software -patents.  We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary.  To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - -  The precise terms and conditions for copying, distribution and -modification follow. - -		    GNU GENERAL PUBLIC LICENSE -   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - -  0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License.  The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language.  (Hereinafter, translation is included without limitation in -the term "modification".)  Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope.  The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - -  1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - -  2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - -    a) You must cause the modified files to carry prominent notices -    stating that you changed the files and the date of any change. - -    b) You must cause any work that you distribute or publish, that in -    whole or in part contains or is derived from the Program or any -    part thereof, to be licensed as a whole at no charge to all third -    parties under the terms of this License. - -    c) If the modified program normally reads commands interactively -    when run, you must cause it, when started running for such -    interactive use in the most ordinary way, to print or display an -    announcement including an appropriate copyright notice and a -    notice that there is no warranty (or else, saying that you provide -    a warranty) and that users may redistribute the program under -    these conditions, and telling the user how to view a copy of this -    License.  (Exception: if the Program itself is interactive but -    does not normally print such an announcement, your work based on -    the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole.  If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works.  But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - -  3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - -    a) Accompany it with the complete corresponding machine-readable -    source code, which must be distributed under the terms of Sections -    1 and 2 above on a medium customarily used for software interchange; or, - -    b) Accompany it with a written offer, valid for at least three -    years, to give any third party, for a charge no more than your -    cost of physically performing source distribution, a complete -    machine-readable copy of the corresponding source code, to be -    distributed under the terms of Sections 1 and 2 above on a medium -    customarily used for software interchange; or, - -    c) Accompany it with the information you received as to the offer -    to distribute corresponding source code.  (This alternative is -    allowed only for noncommercial distribution and only if you -    received the program in object code or executable form with such -    an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it.  For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable.  However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - -  4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License.  Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - -  5. You are not required to accept this License, since you have not -signed it.  However, nothing else grants you permission to modify or -distribute the Program or its derivative works.  These actions are -prohibited by law if you do not accept this License.  Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - -  6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions.  You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - -  7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License.  If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all.  For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices.  Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - -  8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded.  In such case, this License incorporates -the limitation as if written in the body of this License. - -  9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time.  Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number.  If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation.  If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - -  10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission.  For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this.  Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - -			    NO WARRANTY - -  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - -  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - -		     END OF TERMS AND CONDITIONS - -	    How to Apply These Terms to Your New Programs - -  If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - -  To do so, attach the following notices to the program.  It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - -    <one line to give the program's name and a brief idea of what it does.> -    Copyright (C) 19yy  <name of author> - -    This program is free software; you can redistribute it and/or modify -    it under the terms of the GNU General Public License as published by -    the Free Software Foundation; either version 2 of the License, or -    (at your option) any later version. - -    This program is distributed in the hope that it will be useful, -    but WITHOUT ANY WARRANTY; without even the implied warranty of -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -    GNU General Public License for more details. - -    You should have received a copy of the GNU General Public License -    along with this program; if not, write to the Free Software -    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - -    Gnomovision version 69, Copyright (C) 19yy name of author -    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. -    This is free software, and you are welcome to redistribute it -    under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License.  Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary.  Here is a sample; alter the names: - -  Yoyodyne, Inc., hereby disclaims all copyright interest in the program -  `Gnomovision' (which makes passes at compilers) written by James Hacker. - -  <signature of Ty Coon>, 1 April 1989 -  Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs.  If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library.  If this is what you want to do, use the GNU Library General -Public License instead of this License. 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*/ diff --git a/jittertest/Makefile b/jittertest/Makefile deleted file mode 100644 index 2f11329..0000000 --- a/jittertest/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -CC=gcc -# uncomment following for performance -CCFLAGS=-O3 -Wall -m486 -fomit-frame-pointer - -# uncomment following for debugging. Uncomment either this or the one above. Not both. -# CCFLAGS=-Wall -g - - -all: JitterTest plotJittervsFill - -JitterTest: JitterTest.c Makefile -	 gcc $(CCFLAGS) -lm JitterTest.c -o JitterTest - -plotJittervsFill: plotJittervsFill.c Makefile -	 gcc $(CCFLAGS) plotJittervsFill.c -o plotJittervsFill - -clean: -	 rm -rf *~ -	 rm -rf core -	 rm -rf *.o -	 rm -rf JitterTest - - -dep: -	makedepend -I./ *.c -# DO NOT DELETE - -JitterTest.o: /usr/include/stdio.h /usr/include/features.h -JitterTest.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h -JitterTest.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h -JitterTest.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h -JitterTest.o: /usr/include/bits/types.h /usr/include/libio.h -JitterTest.o: /usr/include/_G_config.h /usr/include/bits/stdio_lim.h -JitterTest.o: /usr/include/string.h /usr/include/stdlib.h -JitterTest.o: /usr/include/sys/types.h /usr/include/time.h -JitterTest.o: /usr/include/endian.h /usr/include/bits/endian.h -JitterTest.o: /usr/include/sys/select.h /usr/include/bits/select.h -JitterTest.o: /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h -JitterTest.o: /usr/include/alloca.h /usr/include/sys/time.h -JitterTest.o: /usr/include/bits/time.h /usr/include/signal.h -JitterTest.o: /usr/include/bits/signum.h /usr/include/bits/siginfo.h -JitterTest.o: /usr/include/bits/sigaction.h /usr/include/bits/sigcontext.h -JitterTest.o: /usr/include/asm/sigcontext.h /usr/include/bits/sigstack.h -JitterTest.o: /usr/include/sched.h /usr/include/bits/sched.h -JitterTest.o: /usr/include/unistd.h /usr/include/bits/posix_opt.h -JitterTest.o: /usr/include/bits/confname.h /usr/include/getopt.h diff --git a/jittertest/README b/jittertest/README deleted file mode 100644 index f411a2c..0000000 --- a/jittertest/README +++ /dev/null @@ -1,197 +0,0 @@ -$Id: README,v 1.2 2001/08/10 19:23:11 vipin Exp $ - -This is the README file for the JitterTest (and friends) -program. - -This program is used to measure what the jitter of a -real time task would be under "standard" Linux. - -More particularly, what is the effect of running -a real time task under Linux with background -JFFS file system activity. - -The jitter is measured in milli seconds (ms) from -the expected time of arrival of a signal from a  -periodic timer (set by the task) to when the -task actually gets the signal. - -This jitter is then stored in a file specified -(or the default output file "jitter.dat"). - -The data  may also be sent out to the console by -writing to /dev/console (See help options. This is -highly desirable specially if you have redirected  -your console to the serial port and are storing it -as a minicom log on another computer for later analysis -using some tools provided here). - -This is particularly useful if you have a serial -console and are outputting "interesting" info -from inside some kernel task or driver. -(or something as simple as a "df" program running -periodically and redirecting o/p to the console). - -One "interesting" thing that I have measured -is the effect of FLASH chip erases on the jitter -of a real time task. - -One can do that by putting a printk at the -beginning of the flash erase routine in the MTD -flash chip driver. - -Now you will get jitter data interspersed with -flash sector erase events. Other printk's can also -be placed at suspected jitter causing locations in -the system. - - - -EXECUTING THE PROGRAM "JitterTest" - -You may specify a file to be read by the -program every time it wakes up (every cycle). -This file is created and filled with some junk -data. The purpose of this is to test the jitter -of the program if it were reading from- say -a JFFS (Journaling Flash File System) file system. - -By specifying the complete paths of the read and write -(o/p) files you can test the jitter a POSIX type -real time task will experience under Linux, under -various conditions. - -These can be as follows: - -1. O/P file on ram file system, no i/p file. - - In this case you would presumably generate other -"typical" background activity for your system and -examine the worst case jitter experienced by -a task that is neither reading nor writing to -a file system. - -Other cases could be: - -2. O/P to ram fs, I/P from JFFS (type) fs: - - This is specially useful to test the proper -operation of erase suspend type of operation -in JFFS file systems (with an MTD layer that -supports it). - -  In this test you would generate some background -write/erase type activity that would generate -chip erases. Since this program is reading from -the same file system, you contrast the latencies  -with those obtained with writes going to the same -fs. - -3. Both read and writes to (or just write to) JFFS -file system: - -  Here you would test for latencies experienced by -a program if it were writing (and optionally also  -reading) from a JFFS fs. - - - - -Grabing a kernel profile: - -This program can also conditionally grab a kernel profile. -Specify --grab_kprofile on the cmd line as well as  -a "threshold" parameter (see help options by -?). - -Any jitter greater than this "threshold" will cause the -program to read the /proc/profile file and dump it in -a local file with increasing file numbers. It will also -output the filename at that time to the console file specified. -This will allow you to corelate later in time the various profiles -with data in your console file and what was going on at that time. - -These profile files may then be later examined by running them through -ksymoops. - -Make sure you specify "profile=2" on the kernel command line -when you boot the kernel if you want to use this functionality. - - - -Signalling the JFFS[2] GC task: - -You can also force this program to send a SIGSTOP/SIGCONT to the  -JFFS (or JFFS2) gc task by specifing --siggc <pid> on the cmd line. - -This will let you investigate the effect of forcing the gc task to  -wake up and do its thing when you are not writing to the fs and to -force it to sleep when you want to write to the fs. - -These are just various tools to investigate the possibility of -achieving minimal read/write latency when using JFFS[2]. - -You need to manually do a "ps aux" and look up the PID of the gc -thread and provide it to the program.  - - - - -EXECUTING THE PROGRAM "plotJittervsFill" - -This program is a post processing tool that will extract the jitter -times as printed by the JitterTest program in its console log file -as well as the data printed by the "df" command. - -This "df" data happens to be in the console log because you will -run the shell file fillJffs2.sh on a console when you are doing -your jitter test. - -This shell script copies a specified file to another specified file -every programmable seconds. It also does a "df" and redirects output -to /dev/console where it is mixed with the output from JitterTest. - -All this console data is stored on another computer, as all this data -is being outputted to the serial port as you have redirected the console -to the serial port (that is the only guaranteed way to not loose any -console log or printk data). - -You can then run this saved console log through this program and it -will output a very nice text file with the %fill in one col and -corrosponding jitter values in the second. gnuplot then does a  -beautifull plot of this resulting file showing you graphically the -jitters encountered at different fill % of your JFFS[2] fs. - - - -OTHER COMMENTS: - -Use the "-w BYTES" cmd line parameter to simulate your test case. -Not everyone has the same requirements. Someone may want to measure -the jitter of JFFS2 with 500 bytes being written every 500ms. Others -may want to measure the system performance writing 2048 bytes every -5 seconds. - -RUNNING MULTIPLE INSTANCES: - -Things get real interesting when you run multiple instances of this -program *at the same time*. - -You could have one version running as a real time task (by specifing -the priority with the -p cmd line parameter), not interacting with -any fs or at the very least not reading and writing to JFFS[2]. - -At the same time you could have another version running as a regular -task (by not specifing any priority) but reading and writing to JFFS[2]. - -This way you can easily measure the blocking performance of the real time -task while another non-real time task interacts with JFFS[2] in the back ground. - -You get the idea. - - -WATCH OUT! - -Be particularly careful of running this program as a real time task AND -writing to JFFS[2]. Any blocks will cause your whole system to block till -any garbage collect initiated by writes by this task complete. I have measured -these blocks to be of the order of 40-50 seconds on a reasonably powerful -32 bit embedded system. diff --git a/jittertest/filljffs2.sh b/jittertest/filljffs2.sh deleted file mode 100644 index 10651f4..0000000 --- a/jittertest/filljffs2.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -# Pass following cmd line: -# 1st - file to copy -# 2nd - file to copy to -# 3rd - time to sleep between copies - -while [ $(( 1 )) -gt $(( 0 )) ] -do -   cp $1 $2 -   rm $2  -   df |grep mtd > /dev/console -   echo "sleeping $3" -   sleep $3 -done - diff --git a/jittertest/plotJittervsFill.c b/jittertest/plotJittervsFill.c deleted file mode 100644 index f8a5660..0000000 --- a/jittertest/plotJittervsFill.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - *********************************************************************** - * - *  Copyright:          Daniel Measurement and Control, Inc. - *                           9753 Pine Lake Drive - *                             Houston, TX 77055 - * - *  Created by: Vipin Malik - *  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. - * -  File: plotJittervsFill.c -  By: Vipin Malik - -  About: This program reads in a jitter log file as created -  by the JitterTest.c program and extracts all the jitters -  in the file that are greater than a threshold specified -  as a parameter on the cmd line. It also extracts the -  amount of disk space at (form the "df" out that should also -  be present in the log file) after the jitter extracted. - -  It writes the data to the stderr (where you may redirect it). -  It is suitable for plotting, as the data is written as -  COL1=UsedSpace COL2=Jitter - -  $Id: plotJittervsFill.c,v 1.6 2005/11/07 11:15:21 gleixner Exp $ -  $Log: plotJittervsFill.c,v $ -  Revision 1.6  2005/11/07 11:15:21  gleixner -  [MTD / JFFS2] Clean up trailing white spaces - -  Revision 1.5  2001/08/10 19:23:11  vipin -  Ready to be released under GPL! Added proper headers etc. - -  Revision 1.4  2001/07/02 22:25:40  vipin -  Fixed couple of minor cosmetic typos. - -  Revision 1.3  2001/07/02 14:46:46  vipin -  Added a debug option where it o/p's line numbers to debug funky values. - -  Revision 1.2  2001/06/26 19:48:57  vipin -  Now prints out jitter values found at end of log file, after which -  no new "df" disk usage values were encountered. The last "df" disk usage -  encountered is printed for these orphaned values. - -  Revision 1.1  2001/06/25 19:13:55  vipin -  Added new file- plotJittervsFill.c- that mines the data log file -  outputed from the fillFlash.sh script file and JitterTest.c file -  and produces output suitable to be plotted. -  This output plot may be examined to see visually the relationship -  of the Jitter vs disk usage of the fs under test. - - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> - -static char Version_string[] = "$Id: plotJittervsFill.c,v 1.6 2005/11/07 11:15:21 gleixner Exp $"; -static char LogFile[250] = "InputLogFile.log"; - -static int JitterThreshold_ms = 1000; -static int Debug = 0; /* Debug level. Each "-d" on the cmd line increases the level */ - -#define TRUE  1 -#define FALSE 0 - -#define MIN_JITTER_THRESHOLD 1 /* ms minimum jitter threshold */ - -void PrintHelpInfo(void) -{ -    printf("Usage: plotJittervsFill [options] -f [--file] <input log file name> -t [--jitter_threshold] <jitter threshold in ms>\n"); -    printf("[options]:\n-v [--version] Print version and exit\n"); -    printf("-d Debug. Prints input file line number for each data point picked up.\n"); -    printf("-h [--help] [-?] Print this help screen and exit.\n"); -} - - - -/*********************************************************************** - *                             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") == 0) || -                (strcmp(argv[argNum],"-v")        == 0)) { -                /* Print version information and exit. */ -                printf("%s\n", Version_string); -                exit(0); -            } - -            else if ((strcmp(argv[argNum],"--help") == 0) || -                     (strcmp(argv[argNum],"-h")     == 0) || -                     (strcmp(argv[argNum],"-?")     == 0)) { -                /* Print help information and exit. */ -                PrintHelpInfo(); -                exit(0); -            } - -            else if ((strcmp(argv[argNum],"--file") == 0) || -                     (strcmp(argv[argNum],"-f")     == 0)) { -                /* Set the name of the output file. */ -                ++argNum; -                if (argNum < argc) { -                    strncpy(LogFile, argv[argNum], sizeof(LogFile)); -                } -                else { -                    printf("*** Input file name not specified. ***\n"); -                    exit(0); -                } -            } - -            else if ((strcmp(argv[argNum],"--jitter_threshold") == 0) || -                     (strcmp(argv[argNum],"-t") == 0)) { -                /* Set the file to read*/ -                ++argNum; - -                JitterThreshold_ms = atoi(argv[argNum]); - -                if(JitterThreshold_ms < MIN_JITTER_THRESHOLD) -                { -                    printf("A jitter threshold less than %i ms is not allowed. Bye.\n", -                           MIN_JITTER_THRESHOLD); -                    exit(0); -                } -            } - -            else if ((strcmp(argv[argNum],"-d") == 0)) -            { -                /* Increment debug level */ - -                Debug++; -            } - -            else { -                /* Unknown argument. Print help information and exit. */ -                printf("Invalid option %s\n", argv[argNum]); -                printf("Try 'plotJittervsFill --help' for more information.\n"); -                exit(0); -            } -        } -    } - -    return; -} - - - - - -int main( -    int argc, -    char *argv[]) -{ - -    char lineBuf[1024]; /* how long a single line be? */ -    int converted; -    int lineNo = 0; -    int cnt; - -    FILE *fp; - -    int junkInt1, junkInt2, junkInt3; -    float junkFloat1; -    float jitter_ms; - -#define MAX_SAVE_BUFFER 1000 /* How many values will be picked up while searching for -                          a % disk full line (i.e. before they can be printed out) -                        */ -    int saveJitter[MAX_SAVE_BUFFER]; /* lets us record multiple jitter values that exceed -                            our threshold till we find a "df" field- which is when -                            we can o/p all these values. -                         */ -    int dataLineNo[MAX_SAVE_BUFFER]; /* The saved line #'s for the above. Printed if debug specified. */ - -    int saveJitterCnt = 0; -    int lookFor_df = FALSE; -    int dfPercent = -1; /* will be >= 0 if at least one found. The init value is a flag. */ - -    char junkStr1[500], junkStr2[500]; - -    HandleCmdLineArgs(argc, argv); - -    if((fp = fopen(LogFile, "r")) == NULL) -    { -        printf("Unable to open input log file %s for read.\b", LogFile); -        perror("Error:"); -        exit(1); -    } - - - -    while(fgets(lineBuf, sizeof(lineBuf), fp) != NULL) -    { -        lineNo++; - - -        /* Are we looking for a "df" o/p line? (to see how full -           the flash is?)*/ - -        /* is there a "%" in this line? */ -        if((strstr(lineBuf, "%") != NULL) && (lookFor_df)) -        { -            converted = sscanf(lineBuf, "%s %i %i %i %i\n", -                               junkStr1, &junkInt1, &junkInt2, &junkInt3, &dfPercent); -            if(converted < 5) -            { -                printf("Line %i contains \"%%\", but expected fileds not found. Skipping.\n", lineNo); -            }else -            { -                /* Now print out the saved jitter values (in col2) with this dfPercent value as the col1. */ -                for(cnt = 0; cnt < saveJitterCnt; cnt++) -                { -                    if(Debug) -                    { -                        fprintf(stderr, "%i\t%i\t%i\n", (int)dataLineNo[cnt], -                                dfPercent, (int)saveJitter[cnt]); -                    }else -                    { -                        fprintf(stderr, "%i\t%i\n", dfPercent, (int)saveJitter[cnt]); -                    } - - -                } - -                saveJitterCnt = 0; /* all flushed. Reset for next saves. */ -                lookFor_df = FALSE; -            } - -        } - - -        /* is there a "ms" in this line?*/ -        if(strstr(lineBuf, "ms") == NULL) -        { -            continue; -        } - -        /* grab the ms jitter value */ -        converted = sscanf(lineBuf, "%f %s %f %s\n", &junkFloat1, junkStr1, &jitter_ms, junkStr2); -        if(converted < 4) -        { -            printf("Line %i contains \"ms\", but expected fileds not found. Converted %i, Skipping.", -                   lineNo, converted); -            printf("1=%i, 2=%s.\n", junkInt1, junkStr1); -            continue; /* not our jitter line*/ -        } - -        /* Is the jitter value > threshold value? */ -        if(abs(jitter_ms) > JitterThreshold_ms) -        { -            /* Found a jitter line that matches our crietrion. -               Now set flag to be on the look out for the next -               "df" output so that we can see how full the flash is. -            */ - -            if(saveJitterCnt < MAX_SAVE_BUFFER) -            { -                saveJitter[saveJitterCnt] = (int)abs(jitter_ms); /* why keep the (ms) jitter in float */ -                dataLineNo[saveJitterCnt] = lineNo; -                saveJitterCnt++; -                lookFor_df = TRUE; -            } -            else -            { -                printf("Oops! I've run out of buffer space before I found a %% use line. Dropping itter value. Increase MAX_SAVE_BUFFER and recompile.\n"); -            } - - -        } - -    } - - -    /* Now print out any saved jitter values that were not printed out because we did not find -       and "df" after these were picked up. Only print if a "df" disk usage was ever found. -     */ -    if(lookFor_df && (dfPercent >= 0)) -    { -        /* Now print out the saved jitter values (in col2) with this dfPercent value as the col1. */ -        for(cnt = 0; cnt < saveJitterCnt; cnt++) -        { -            fprintf(stderr, "%i\t%i\n", dfPercent, (int)saveJitter[cnt]); -        } -    } - -    return 0; - - -}/* end main() */ - - - -  | 
