"Fossies" - the Fresh Open Source Software Archive

Member "bonnie++-2.00a/getc_putc.cpp" (15 Sep 2018, 6236 Bytes) of package /linux/privat/bonnie++-2.00a.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "getc_putc.cpp" see the Fossies "Dox" file reference documentation.

    1 #include "bonnie.h"
    2 
    3 #include <unistd.h>
    4 #include <sys/utsname.h>
    5 #include <stdlib.h>
    6 #include <cstring>
    7 #include <vector>
    8 
    9 #include "duration.h"
   10 #include "getc_putc.h"
   11 
   12 static void usage()
   13 {
   14   fprintf(stderr, "usage:\n"
   15     "getc_putc [-d scratch-dir] [-s size(KiB)] [-m machine-name]\n"
   16     "[-u uid-to-use:gid-to-use] [-g gid-to-use]\n"
   17     "\nVersion: " BON_VERSION "\n");
   18   exit(eParam);
   19 }
   20 
   21 enum getc_tests_t
   22 {
   23   Write = 0,
   24   Read,
   25   PutcNoTh,
   26   GetcNoTh,
   27   Putc,
   28   Getc,
   29   PutcUnlocked,
   30   GetcUnlocked,
   31   GetcTestCount
   32 };
   33 
   34 static void print_stat(FILE *fp, double elapsed, int test_size, bool csv);
   35 static void print_all_res(CPCCHAR machine, FILE *fp, double *res, int size, bool csv);
   36 
   37 #define WRITE_SIZE_FACT 64
   38 
   39 int main(int argc, char *argv[])
   40 {
   41   int file_size = 512 << 10;
   42   PCCHAR dir = ".";
   43   bool quiet = false;
   44   char *userName = NULL, *groupName = NULL;
   45   PCCHAR machine = NULL;
   46 
   47   int int_c;
   48   while(-1 != (int_c = getopt(argc, argv, "d:s:u:g:m:q")) )
   49   {
   50     switch(char(int_c))
   51     {
   52       case '?':
   53       case ':':
   54         usage();
   55       break;
   56       case 'd':
   57         dir = optarg;
   58       break;
   59       case 's':
   60         file_size = size_from_str(optarg, "m");
   61       break;
   62       case 'q':
   63         quiet = true;
   64       break;
   65       case 'm':
   66         machine = optarg;
   67       break;
   68       case 'g':
   69         if(groupName)
   70           usage();
   71         groupName = optarg;
   72       break;
   73       case 'u':
   74       {
   75         if(userName)
   76           usage();
   77         userName = strdup(optarg);
   78         int i;
   79         for(i = 0; userName[i] && userName[i] != ':'; i++) {}
   80 
   81         if(userName[i] == ':')
   82         {
   83           if(groupName)
   84             usage();
   85           userName[i] = '\0';
   86           groupName = &userName[i + 1];
   87         }
   88       }
   89       break;
   90     }
   91   }
   92 
   93   if(userName || groupName)
   94   {
   95     if(bon_setugid(userName, groupName, quiet))
   96       return 1;
   97     if(userName)
   98       free(userName);
   99   }
  100   else if(geteuid() == 0)
  101   {
  102     fprintf(stderr, "You must use the \"-u\" switch when running as root.\n");
  103     usage();
  104   }
  105 
  106   if(machine == NULL)
  107   {
  108     struct utsname utsBuf;
  109     if(uname(&utsBuf) != -1)
  110       machine = utsBuf.nodename;
  111   }
  112 
  113   file_size -= (file_size % WRITE_SIZE_FACT);
  114   file_size = file_size << 10;
  115   if(!file_size)
  116     usage();
  117 
  118   char *fname = new char[22 + strlen(dir)];
  119 
  120   sprintf(fname, "%s/getc_putc.%d", dir, getpid());
  121 
  122   int fd = open(fname, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
  123   if(fd < 0)
  124   {
  125     fprintf(stderr, "Can't create file \"%s\".\n", fname);
  126     usage();
  127   }
  128   if(dup2(fd, FILE_FD) != FILE_FD)
  129   {
  130     fprintf(stderr, "Can't dup2() the file handle.");
  131     return 1;
  132   }
  133   close(fd);
  134 
  135   if(!quiet)
  136     printf("Extending file...");
  137   fflush(NULL);
  138   char buf[1 << 20];
  139 
  140   int size = 0, wrote;
  141   while(size < file_size)
  142   {
  143     wrote = write(FILE_FD, buf, min(sizeof(buf), (size_t)file_size - size));
  144     if(wrote < 0)
  145     {
  146       fprintf(stderr, "Can't extend file - disk full?\n");
  147       return 1;
  148     }
  149     size += wrote;
  150   }
  151   fsync(FILE_FD);
  152   volatile char c;
  153   int i;
  154   Duration dur;
  155   double res[GetcTestCount];
  156 
  157   if(lseek(FILE_FD, 0, SEEK_SET) != 0)
  158   {
  159     fprintf(stderr, "Can't seek.\n");
  160     return 1;
  161   }
  162   size = file_size / WRITE_SIZE_FACT;
  163   TEST_FUNC_WRITE("write(fd, &c, 1)", if(write(FILE_FD, (void *)&c, 1) != 1), res[Write]);
  164   fsync(FILE_FD);
  165   if(lseek(FILE_FD, 0, SEEK_SET) != 0)
  166   {
  167     fprintf(stderr, "Can't seek.\n");
  168     return 1;
  169   }
  170   TEST_FUNC_READ("read(fd, &c, 1)", if(read(FILE_FD, (void *)&c, 1) != 1), res[Read]);
  171 
  172   char *prog = new char[strlen(argv[0]) + 30];
  173   sprintf(prog, "%s_helper %d", argv[0], file_size);
  174   if(quiet)
  175     strcat(prog, "q");
  176   FILE *child = popen(prog, "r");
  177   if(!child)
  178   {
  179     fprintf(stderr, "Can't execute \"%s\".\n", prog);
  180     return 1;
  181   }
  182   if(fread(&res[PutcNoTh], sizeof(double) * 2, 1, child) != 1)
  183   {
  184     fprintf(stderr, "Can't get results from child.\n");
  185     return 1;
  186   }
  187   fclose(child);
  188 
  189   FILE *fp = fdopen(FILE_FD, "w+");
  190   if(!fp)
  191   {
  192     fprintf(stderr, "Can't reopen for putc.\n");
  193     return 1;
  194   }
  195   if(fseek(fp, 0, SEEK_SET) != 0)
  196   {
  197     fprintf(stderr, "Can't seek.\n");
  198     return 1;
  199   }
  200   fflush(NULL);
  201   size = file_size;
  202   TEST_FUNC_WRITE("putc(c, fp)", if(putc(c, fp) == EOF), res[Putc]);
  203   if(fseek(fp, 0, SEEK_SET) != 0)
  204   {
  205     fprintf(stderr, "Can't seek.\n");
  206     return 1;
  207   }
  208   fflush(NULL);
  209   TEST_FUNC_READ("getc()", if( (c = getc(fp)) == EOF), res[Getc]);
  210   if(fseek(fp, 0, SEEK_SET) != 0)
  211   {
  212     fprintf(stderr, "Can't seek.\n");
  213     return 1;
  214   }
  215   fflush(NULL);
  216   size = file_size;
  217   TEST_FUNC_WRITE("putc_unlocked(c, fp)", if(putc_unlocked(c, fp) == EOF), res[PutcUnlocked]);
  218   if(fseek(fp, 0, SEEK_SET) != 0)
  219   {
  220     fprintf(stderr, "Can't seek.\n");
  221     return 1;
  222   }
  223   fflush(NULL);
  224   TEST_FUNC_READ("getc_unlocked()", if( (c = getc_unlocked(fp)) == EOF), res[GetcUnlocked]);
  225 
  226   if(!quiet)
  227     printf("done\n");
  228   fclose(fp);
  229   unlink(fname);
  230   size = size / 1024;
  231   print_all_res(machine, stderr, res, size, false);
  232   print_all_res(machine, stdout, res, size, true);
  233 
  234   return 0;
  235 }
  236 
  237 static void print_all_res(CPCCHAR machine, FILE *fp, double *res, int size, bool csv)
  238 {
  239   if(!csv)
  240   {
  241     fprintf(fp, "Version %5s          write   read putcNT getcNT   putc   getc  putcU  getcU\n", BON_VERSION);
  242     fprintf(fp, "%-20s ", machine);
  243   }
  244   else
  245   {
  246     fprintf(fp, "%s", machine);
  247   }
  248   print_stat(fp, res[Write], size / WRITE_SIZE_FACT, csv);
  249   print_stat(fp, res[Read], size / WRITE_SIZE_FACT, csv);
  250   print_stat(fp, res[PutcNoTh], size, csv);
  251   print_stat(fp, res[GetcNoTh], size, csv);
  252   print_stat(fp, res[Putc], size, csv);
  253   print_stat(fp, res[Getc], size, csv);
  254   print_stat(fp, res[PutcUnlocked], size, csv);
  255   print_stat(fp, res[GetcUnlocked], size, csv);
  256   fprintf(fp, "\n");
  257 }
  258 
  259 static void print_stat(FILE *fp, double elapsed, int test_size, bool csv)
  260 {
  261   if(elapsed == 0.0)
  262   {
  263     if(!csv)
  264       fprintf(fp, "       ");
  265     else
  266       fprintf(fp, ",");
  267   }
  268   else if(elapsed < MinTime)
  269   {
  270     if(!csv)
  271       fprintf(fp, " ++++++");
  272     else
  273       fprintf(fp, ",++++++");
  274   }
  275   else
  276   {
  277     double speed = double(test_size) / elapsed;
  278     if(!csv)
  279       fprintf(fp, " %6d", int(speed));
  280     else
  281       fprintf(fp, ",%d", int(speed));
  282   }
  283 }