home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / fsb.zip / fsbench.c next >
C/C++ Source or Header  |  1996-09-19  |  11KB  |  349 lines

  1. /********************************************************/
  2. /*                                                      */
  3. /*   F I L E - S Y S T E M     B E N C H M A R K S      */
  4. /*                                                      */
  5. /*        Radim Kolar , 2:423/66.111@FidoNet            */
  6. /*       radim_kolar@p111.f66.n423.z2.fido.cz           */
  7. /*           F R E E W A R E                            */
  8. /*                                                      */
  9. /*            version 0.22                              */
  10. /*                                                      */
  11. /* History:                                             */
  12. /* 0.01 - 28/02/1996 - Project started...               */
  13. /* 0.10 - 03/03/1996 - Fully functional FSB kernel      */
  14. /* 0.20 - 09/03/1996 - Config parsing + display         */
  15. /* 0.21 - 21/04/1996 - Emergency exit on SIGINT         */
  16. /* 0.22 - 13/06/1996 - DosForceDelete on Emergency exit */
  17. /*                     updated comments in config file  */
  18. /*                     corrected bug in emergency exit  */
  19. /*                      sometimes fsb don't exit        */
  20. /********************************************************/
  21.  
  22. #define FSBENCH_V "0.22"
  23.  
  24. #define INCL_DOSMISC
  25. #define INCL_DOSFILEMGR
  26. #define INCL_BASE
  27. #include <os2.h>
  28. #include <malloc.h>
  29. #include <ctype.h>
  30. #include <string.h>
  31. #include <stdio.h>
  32. #include <sys/time.h>
  33. #include <stdlib.h>
  34. #include <io.h>
  35. #include <signal.h>
  36.  
  37. /* Global vars. */
  38. #define TEST_FILENAME "test.tmp"
  39. #define TEST_FILESIZE 1024*1024*4
  40. HFILE h=0; /* handle prave otevreneho souboru */
  41. char *fn=NULL;  /* jmeno prave otevreneho souboru */
  42.  
  43.  
  44.  
  45. /* Vytvori testovaci soubor fn o velikosti fs bajtu */
  46. int CreateTestFile(char *fn,unsigned long fs)
  47. {
  48.  APIRET rc;
  49.  HFILE hnd;
  50.  ULONG act;
  51.  void *blok;
  52.  int i;
  53.  blok=malloc(512);
  54.  rc=DosOpen(fn,&hnd,&act,fs,FILE_NORMAL,OPEN_ACTION_CREATE_IF_NEW|
  55.             OPEN_ACTION_REPLACE_IF_EXISTS,OPEN_SHARE_DENYREADWRITE|
  56.             OPEN_ACCESS_READWRITE,NULL);
  57.  h=hnd;           
  58.  for(i=0;i<fs/512;i++)
  59.    DosWrite(hnd,blok,512,&act);
  60.  /* dodatek */
  61.  DosWrite(hnd,blok,fs-(fs/512)*512,&act);
  62.  DosClose(hnd);
  63.  h=0;
  64.  return rc;
  65. }
  66.  
  67. /* smaze testovaci soubor */
  68. int DeleteTestFile(char *fn)
  69. {
  70.  APIRET rc;
  71.  rc=DosForceDelete(fn);
  72.  return rc;
  73.  
  74. void sync(void)
  75. {
  76.  DosShutdown(1L);
  77.  DosSleep(5000);
  78. }
  79.  
  80. /* File-System testing Engine */
  81.  
  82. /* Cache flagy */
  83. #define C_NONE 1
  84. #define C_THR  2
  85. #define C_FULL 3
  86. /* seq. flagy */
  87. #define S_RND 1
  88. #define S_FOR 2
  89. #define S_BACK 3
  90. /* access flagy */
  91. #define A_READ 1
  92. #define A_WRITE 2
  93. #define A_REWRITE 3
  94.  
  95. int OpenTF(HFILE *hnd,char *fn,int cache,int seq,int acc)
  96. {
  97.  APIRET rc;
  98.  ULONG act;
  99.  ULONG omode;
  100.  /* acc flahy */
  101.  if (acc==A_READ) omode=OPEN_ACCESS_READONLY;
  102.           else    omode=OPEN_ACCESS_READWRITE;
  103.  /* cache flagy */
  104.  if (cache==C_THR) omode=omode|OPEN_FLAGS_WRITE_THROUGH;
  105.  if (cache==C_NONE) omode=omode|OPEN_FLAGS_NO_CACHE;
  106.  /* seq. flagy */
  107.  if (seq==S_RND) omode=omode|OPEN_FLAGS_RANDOM;
  108.  if (seq==S_FOR) omode=omode|OPEN_FLAGS_SEQUENTIAL;
  109.  if (seq==S_BACK) omode=omode|OPEN_FLAGS_RANDOMSEQUENTIAL;
  110.  
  111.  rc=DosOpen(fn,hnd,&act,0,FILE_NORMAL,OPEN_ACTION_FAIL_IF_NEW|
  112.     OPEN_ACTION_OPEN_IF_EXISTS,omode|OPEN_FLAGS_FAIL_ON_ERROR|
  113.     OPEN_SHARE_DENYREADWRITE,NULL);
  114.  return rc;       
  115. }            
  116.  
  117. int EngineFT(char *fn, unsigned long fs,unsigned long blocksize,
  118.            unsigned long times,int cache, int seq,int acc,double *etime)
  119. {
  120.  APIRET rc;
  121.  unsigned long loop;
  122.  void *buff;
  123.  ULONG bread;
  124. /* unsigned long times2;*/
  125.  double t1,t2;
  126.  struct timeval tv;
  127. /* times2=times;*/
  128.  if((rc=OpenTF(&h,fn,cache,seq,acc))) return 1;
  129. /* printf("File handle je %ld\n",h);*/
  130. /* printf("%ld Blocks/loop\n",fs/blocksize);*/
  131. /*printf("Blocksize: %ld\n",blocksize);*/
  132.  buff=malloc(blocksize);
  133.  if(!buff) return 5;
  134.  srand(1);
  135.  if(gettimeofday(&tv,NULL)) return 6;
  136.  t1=tv.tv_sec+tv.tv_usec/1000000.0;
  137. /* printf("Start: %f\n",t1);*/
  138.  while (times>0)
  139.  {
  140.   loop=fs/blocksize;
  141. /*  printf("%ld blocks to go\n",times);*/
  142.   if(seq==S_FOR) if(DosSetFilePtr(h,0,FILE_BEGIN,&bread)) { DosClose(h);h=0;free(buff);return 2;}
  143.   if(seq==S_BACK) if(DosSetFilePtr(h,-blocksize,FILE_END,&bread)) { DosClose(h);h=0;free(buff);return 2;}
  144.  
  145.   while ((times>0)&&(loop>0))
  146.   {
  147.    if (acc==A_READ) if(DosRead(h,buff,blocksize,&bread)) { DosClose(h);h=0;free(buff);return 3;}
  148.    if (acc==A_WRITE) if(DosWrite(h,buff,blocksize,&bread)) { DosClose(h);h=0;free(buff);return 3;}
  149.    if (acc==A_REWRITE)
  150.           {
  151.            if(DosRead(h,buff,blocksize,&bread)) { DosClose(h);h=0;free(buff);return 3;}
  152.            if(DosSetFilePtr(h,-blocksize,FILE_CURRENT,&bread)) { DosClose(h);h=0;free(buff);return 2;}
  153.            if(DosWrite(h,buff,blocksize,&bread)) { DosClose(h);h=0;free(buff);return 3;}
  154.           }
  155.    if(bread<blocksize-2) { DosClose(h);h=0;free(buff);return 4;}
  156. /* printf("%ld.",bread);*/
  157.    loop--;
  158.    times--;
  159.    if(seq==S_BACK) if(DosSetFilePtr(h,-blocksize*2,FILE_CURRENT,&bread)) { DosClose(h);free(buff);return 2;};
  160.    if(seq==S_RND) { 
  161.                    if(DosSetFilePtr(h,blocksize*(rand()/(1+(RAND_MAX/(fs/blocksize)))),FILE_BEGIN,&bread)) 
  162.                      { DosClose(h);h=0;free(buff);return 2;}
  163. /*                 printf("NP: %ld",bread);*/
  164.                   }
  165.   };
  166.  };  
  167.  if(gettimeofday(&tv,NULL)) return 6; 
  168.  t2=tv.tv_sec+tv.tv_usec/1000000.0;
  169. /* printf("Stop : %f\n",t2);*/
  170.  *etime=t2-t1;
  171. /*printf("  time %.2fs - ",t2-t1);*/
  172. /* printf("Precteno %ld K bajtu\n",times2*blocksize/1024L);*/
  173. /* printf("Transfer speed %.1f KB/s\n",((blocksize*times2)/1024L)/(t2-t1));*/
  174.  DosClose(h);
  175.  h=0;
  176.  free(buff);
  177.  return rc;
  178.  
  179. unsigned long pnumb(const char *n)
  180. {
  181.  int i;
  182.  unsigned long res;
  183.  res=0;
  184.  for (i=0;i<strlen(n);i++)
  185.    {
  186.    if (isdigit(n[i])) {
  187.                         res=res*10+((n[i])-'0');
  188.                         continue;
  189.                       }
  190.    if (toupper(n[i])=='K')
  191.                       {
  192.                        res=res*1024;
  193.                        continue;
  194.                       }
  195.                       
  196.    if (toupper(n[i])=='M')
  197.                       {
  198.                        res=res*1024*1024;
  199.                        continue;
  200.                       }
  201.                                         
  202.    }                       
  203.    return res;
  204. int config(void)
  205. {
  206.   FILE *c;
  207.   char *line;
  208.   char *keyw;
  209.   char *ar,*tmp;
  210.   unsigned long fs;
  211.   int i,j,n,p;
  212.   double etime,timer;
  213.   unsigned long blocksize;
  214.   unsigned long times;
  215.   int cache, seq, acc;
  216.  
  217.   c=fopen("fsbench.cnf","rt");
  218.   if (c==NULL) return 1;
  219.   if(DosQuerySysInfo(QSV_TIMER_INTERVAL,QSV_TIMER_INTERVAL,×,4)) return 2;
  220.   timer=(times/10.0)/1000.0;
  221. /*  printf("Timer=%f\n",timer);*/
  222.   line=malloc(2048);
  223.   ar  =malloc(2048);
  224.   keyw=malloc(2048);
  225.   fn=malloc(256);
  226.   tmp=malloc(2048);
  227.   if((!line)||(!ar)||(!keyw)||(!fn)||(!tmp)) { free(line);free(ar);free(keyw);free(fn);
  228.                                 free(tmp);
  229.                                 fclose(c); return 2;}
  230.   printf("\nAction  Direction   cache    times    blocksize   time   Filesystem speed\n");
  231.   printf("-------------------------------------------------------------------------------\n");
  232.   strcpy(fn,"fsbench.tmp");
  233.   fs=8*1024*1024;
  234.   while ((EOF!=fscanf(c,"%[^\n]%*[\n]",line)))
  235.     {
  236.     if (line[0]==';') continue;
  237. /*    printf("!%s\n",line);*/
  238.     /* predej param */
  239.     strcpy(keyw,"");
  240.     strcpy(ar,"");
  241.     sscanf(line,"%s %[^\n]",keyw,ar);
  242. /*  printf("KW: %s\nARG: %s\n",keyw,ar);*/
  243.     if (!stricmp(keyw,"SIZE")) fs=pnumb(ar);
  244.     if (!stricmp(keyw,"NAME")) strcpy(fn,ar);
  245.     if (!stricmp(keyw,"CREATE")) CreateTestFile(fn,fs);
  246.     if (!stricmp(keyw,"DELETE")) DeleteTestFile(fn);
  247.     if (!stricmp(keyw,"SAY")) printf("\n%s\n",ar);
  248.     if (!stricmp(keyw,"TEST"))
  249.     { 
  250.       j=0;n=1;acc=0;seq=0;cache=0;p=0;
  251.       times=0;blocksize=0;
  252.       /* pridam mezeru na konec */
  253.       ar[strlen(ar)+1]='\0';
  254.       ar[strlen(ar)]=' ';
  255.       for(i=0;i<strlen(ar);i++)
  256.         {  
  257.           if (ar[i]!=' ') {tmp[j++]=ar[i];p=0;continue;}
  258.           if (p==1) continue;
  259.           tmp[j]='\0';j=0;
  260.           /* ted'ka to zpracuju */
  261.           switch(n)
  262.           {
  263.            case 1: blocksize=pnumb(tmp);break;
  264.            case 2: times=pnumb(tmp);break;
  265.            case 3: if (tmp[0]=='R') acc=A_READ;
  266.                    if (tmp[0]=='W') acc=A_WRITE;
  267.                    if (tmp[0]=='E') acc=A_REWRITE;
  268.                    break;
  269.            case 4: if (tmp[0]=='F') seq=S_FOR;
  270.                    if (tmp[0]=='B') seq=S_BACK;
  271.                    if (tmp[0]=='R') seq=S_RND;
  272.                    break;
  273.            case 5: if (tmp[0]=='F') cache=C_FULL;
  274.                    if (tmp[0]=='N') cache=C_NONE;
  275.                    if (tmp[0]=='W') cache=C_THR;
  276.                    break;
  277.           }
  278.           n++;p=1;
  279.         }  
  280.        if ((!acc)||(!seq)||(!cache)||(!blocksize)||(!times)) continue;
  281.        sync();
  282.        /* vytiskni co delas */
  283.        switch(acc)
  284.        {
  285.        case A_READ   : printf("Read     ");break;
  286.        case A_WRITE  : printf("Write    ");break;
  287.        case A_REWRITE: printf("Rewrite  ");
  288.        }
  289.        switch(seq)
  290.        {
  291.        case S_FOR : printf("Forward  ");break;
  292.        case S_BACK: printf("Backward ");break;
  293.        case S_RND:  printf("Random   ");
  294.        }
  295.        switch(cache)
  296.        {
  297.        case C_FULL:  printf("use cache ");break;
  298.        case C_NONE:  printf("no cache  ");break;
  299.        case C_THR:   printf("w through ");
  300.        }
  301.        printf("%6ldx ",times);
  302.        printf("%5ld bytes ",blocksize);
  303.        j=EngineFT(fn,fs,blocksize,times,cache,seq,acc,&etime);
  304.        if(j) printf ("ERROR(%d)\n",j);
  305.         else
  306.         { 
  307.          printf("%6.2fs ",etime);
  308.          printf("(%6.0f ",(blocksize*times/1024)/etime);
  309.          /* pocitani chyby mereni v KB */
  310.          printf("+/- %5.1f) KB/s\n",(((blocksize*times/1024)/(etime-timer))-
  311.                 ((blocksize*times/1024)/(etime+timer)))/2);
  312.         } 
  313.     }
  314.     if(EOF==(i=getc(c))) break;
  315.                   else 
  316.                     ungetc(i,c);
  317.  
  318.     
  319. /*  if (eof(c)) break;*/
  320.     }
  321. /*printf("FSIZE=%ld\n",fs);  */
  322.   free(line);free(ar);free(keyw);free(fn);free(tmp);
  323.   fclose(c);
  324.   return 0;
  325. }
  326.  
  327. void Uklid(int i)
  328. {
  329.  printf("\nEmergency exit..\n");
  330.  if (h) { DosClose(h);}
  331.  DosForceDelete(fn);
  332.  exit(255);
  333. /* signal(i,SIG_ACK);*/
  334. }
  335.  
  336. void main(void)
  337. {
  338.  if(DosSetPriority(PRTYS_PROCESS,PRTYC_FOREGROUNDSERVER,PRTYD_MAXIMUM,0)) 
  339.   printf("Error setting priority\n");
  340.  if(SIG_ERR==signal(SIGINT,Uklid)) printf("Error catching signal SIGINT\n"); 
  341.  printf("File system benchmark program, version "FSBENCH_V"\n");
  342.  printf("Compiled "__DATE__" using GCC "__VERSION__"\n");
  343.  config();
  344.  return;
  345. }
  346.