"Fossies" - the Fresh Open Source Software Archive

Member "stress-1.0.5/src/stress.c" (2 Oct 2021, 20902 Bytes) of package /linux/privat/old/stress-1.0.5.tar.gz:


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 "stress.c" see the Fossies "Dox" file reference documentation.

    1 /* A program to put stress on a POSIX system (stress).
    2  *
    3  * Copyright 2001-2010 Amos Waterland <apw@rossby.metr.ou.edu>
    4  * Copyright 2021      Joao Eriberto Mota Filho <eriberto@eriberto.pro.br>
    5  *
    6  * This program is free software; you can redistribute it and/or modify it
    7  * under the terms of the GNU General Public License as published by the Free
    8  * Software Foundation; either version 2 of the License, or (at your option)
    9  * any later version.
   10  *
   11  * This program is distributed in the hope that it will be useful, but WITHOUT
   12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   14  * more details.
   15  *
   16  * You should have received a copy of the GNU General Public License along
   17  * with this program; if not, write to the Free Software Foundation, Inc., 59
   18  * Temple Place, Suite 330, Boston, MA  02111-1307  USA
   19  */
   20 
   21 #include <ctype.h>
   22 #include <errno.h>
   23 #include <libgen.h>
   24 #include <math.h>
   25 #include <stdio.h>
   26 #include <stdlib.h>
   27 #include <string.h>
   28 #include <signal.h>
   29 #include <time.h>
   30 #include <unistd.h>
   31 #include <sys/wait.h>
   32 #include "config.h"
   33 
   34 /* By default, print all messages of severity info and above.  */
   35 static int global_debug = 2;
   36 
   37 /* Name of this program */
   38 static char *global_progname = PACKAGE;
   39 
   40 /* Implemention of runtime-selectable severity message printing.  */
   41 #define dbg(OUT, STR, ARGS...) if (global_debug >= 3) \
   42     fprintf (stdout, "%s: dbug: [%lli] ", \
   43         global_progname, (long long)getpid()), \
   44         fprintf(OUT, STR, ##ARGS), fflush(OUT)
   45 #define out(OUT, STR, ARGS...) if (global_debug >= 2) \
   46     fprintf (stdout, "%s: info: [%lli] ", \
   47         global_progname, (long long)getpid()), \
   48         fprintf(OUT, STR, ##ARGS), fflush(OUT)
   49 #define wrn(OUT, STR, ARGS...) if (global_debug >= 1) \
   50     fprintf (stderr, "%s: WARN: [%lli] (%d) ", \
   51         global_progname, (long long)getpid(), __LINE__), \
   52         fprintf(OUT, STR, ##ARGS), fflush(OUT)
   53 #define err(OUT, STR, ARGS...) if (global_debug >= 0) \
   54     fprintf (stderr, "%s: FAIL: [%lli] (%d) ", \
   55         global_progname, (long long)getpid(), __LINE__), \
   56         fprintf(OUT, STR, ##ARGS), fflush(OUT)
   57 
   58 /* Implementation of check for option argument correctness.  */
   59 #define assert_arg(A) \
   60           if (++i == argc || ((arg = argv[i])[0] == '-' && \
   61               !isdigit ((int)arg[1]) )) \
   62             { \
   63               err (stderr, "missing argument to option '%s'\n", A); \
   64               exit (1); \
   65             }
   66 
   67 /* Prototypes for utility functions.  */
   68 int usage (int status);
   69 int version (int status);
   70 long long atoll_s (const char *nptr);
   71 long long atoll_b (const char *nptr);
   72 
   73 /* Prototypes for worker functions.  */
   74 int hogcpu (void);
   75 int hogio (void);
   76 int hogvm (long long bytes, long long stride, long long hang, int keep);
   77 int hoghdd (long long bytes);
   78 
   79 int
   80 main (int argc, char **argv)
   81 {
   82   int i, pid, children = 0, retval = 0;
   83   long starttime, stoptime, runtime, forks;
   84 
   85   /* Variables that indicate which options have been selected.  */
   86   int do_dryrun = 0;
   87   long long do_backoff = 3000;
   88   long long do_timeout = 0;
   89   long long do_cpu = 0;
   90   long long do_io = 0;
   91   long long do_vm = 0;
   92   long long do_vm_bytes = 256 * 1024 * 1024;
   93   long long do_vm_stride = 4096;
   94   long long do_vm_hang = -1;
   95   int do_vm_keep = 0;
   96   long long do_hdd = 0;
   97   long long do_hdd_bytes = 1024 * 1024 * 1024;
   98 
   99   /* Record our start time.  */
  100   if ((starttime = time (NULL)) == -1)
  101     {
  102       err (stderr, "failed to acquire current time: %s\n", strerror (errno));
  103       exit (1);
  104     }
  105 
  106   /* SuSv3 does not define any error conditions for this function.  */
  107   global_progname = basename (argv[0]);
  108 
  109   /* For portability, parse command line options without getopt_long.  */
  110   for (i = 1; i < argc; i++)
  111     {
  112       char *arg = argv[i];
  113 
  114       if (strcmp (arg, "--help") == 0 || strcmp (arg, "-?") == 0)
  115         {
  116           usage (0);
  117         }
  118       else if (strcmp (arg, "--version") == 0)
  119         {
  120           version (0);
  121         }
  122       else if (strcmp (arg, "--verbose") == 0 || strcmp (arg, "-v") == 0)
  123         {
  124           global_debug = 3;
  125         }
  126       else if (strcmp (arg, "--quiet") == 0 || strcmp (arg, "-q") == 0)
  127         {
  128           global_debug = 0;
  129         }
  130       else if (strcmp (arg, "--dry-run") == 0 || strcmp (arg, "-n") == 0)
  131         {
  132           do_dryrun = 1;
  133         }
  134       else if (strcmp (arg, "--backoff") == 0)
  135         {
  136           assert_arg ("--backoff");
  137           if (sscanf (arg, "%lli", &do_backoff) != 1)
  138             {
  139               err (stderr, "invalid number: %s\n", arg);
  140               exit (1);
  141             }
  142           if (do_backoff < 0)
  143             {
  144               err (stderr, "invalid backoff factor: %lli\n", do_backoff);
  145               exit (1);
  146             }
  147           dbg (stdout, "setting backoff coeffient to %llius\n", do_backoff);
  148         }
  149       else if (strcmp (arg, "--timeout") == 0 || strcmp (arg, "-t") == 0)
  150         {
  151           assert_arg ("--timeout");
  152           do_timeout = atoll_s (arg);
  153           if (do_timeout <= 0)
  154             {
  155               err (stderr, "invalid timeout value: %llis\n", do_timeout);
  156               exit (1);
  157             }
  158         }
  159       else if (strcmp (arg, "--cpu") == 0 || strcmp (arg, "-c") == 0)
  160         {
  161           assert_arg ("--cpu");
  162           do_cpu = atoll_b (arg);
  163           if (do_cpu <= 0)
  164             {
  165               err (stderr, "invalid number of cpu hogs: %lli\n", do_cpu);
  166               exit (1);
  167             }
  168         }
  169       else if (strcmp (arg, "--io") == 0 || strcmp (arg, "-i") == 0)
  170         {
  171           assert_arg ("--io");
  172           do_io = atoll_b (arg);
  173           if (do_io <= 0)
  174             {
  175               err (stderr, "invalid number of io hogs: %lli\n", do_io);
  176               exit (1);
  177             }
  178         }
  179       else if (strcmp (arg, "--vm") == 0 || strcmp (arg, "-m") == 0)
  180         {
  181           assert_arg ("--vm");
  182           do_vm = atoll_b (arg);
  183           if (do_vm <= 0)
  184             {
  185               err (stderr, "invalid number of vm hogs: %lli\n", do_vm);
  186               exit (1);
  187             }
  188         }
  189       else if (strcmp (arg, "--vm-bytes") == 0)
  190         {
  191           assert_arg ("--vm-bytes");
  192           do_vm_bytes = atoll_b (arg);
  193           if (do_vm_bytes <= 0)
  194             {
  195               err (stderr, "invalid vm byte value: %lli\n", do_vm_bytes);
  196               exit (1);
  197             }
  198         }
  199       else if (strcmp (arg, "--vm-stride") == 0)
  200         {
  201           assert_arg ("--vm-stride");
  202           do_vm_stride = atoll_b (arg);
  203           if (do_vm_stride <= 0)
  204             {
  205               err (stderr, "invalid stride value: %lli\n", do_vm_stride);
  206               exit (1);
  207             }
  208         }
  209       else if (strcmp (arg, "--vm-hang") == 0)
  210         {
  211           assert_arg ("--vm-hang");
  212           do_vm_hang = atoll_b (arg);
  213           if (do_vm_hang < 0)
  214             {
  215               err (stderr, "invalid value: %lli\n", do_vm_hang);
  216               exit (1);
  217             }
  218         }
  219       else if (strcmp (arg, "--vm-keep") == 0)
  220         {
  221           do_vm_keep = 1;
  222         }
  223       else if (strcmp (arg, "--hdd") == 0 || strcmp (arg, "-d") == 0)
  224         {
  225           assert_arg ("--hdd");
  226           do_hdd = atoll_b (arg);
  227           if (do_hdd <= 0)
  228             {
  229               err (stderr, "invalid number of hdd hogs: %lli\n", do_hdd);
  230               exit (1);
  231             }
  232         }
  233       else if (strcmp (arg, "--hdd-bytes") == 0)
  234         {
  235           assert_arg ("--hdd-bytes");
  236           do_hdd_bytes = atoll_b (arg);
  237           if (do_hdd_bytes <= 0)
  238             {
  239               err (stderr, "invalid hdd byte value: %lli\n", do_hdd_bytes);
  240               exit (1);
  241             }
  242         }
  243       else
  244         {
  245           err (stderr, "unrecognized option: %s\n", arg);
  246           exit (1);
  247         }
  248     }
  249 
  250   /* Print startup message if we have work to do, bail otherwise.  */
  251   if (do_cpu + do_io + do_vm + do_hdd)
  252     {
  253       out (stdout, "dispatching hogs: %lli cpu, %lli io, %lli vm, %lli hdd\n",
  254            do_cpu, do_io, do_vm, do_hdd);
  255     }
  256   else
  257     usage (0);
  258 
  259   /* Round robin dispatch our worker processes.  */
  260   while ((forks = (do_cpu + do_io + do_vm + do_hdd)))
  261     {
  262       long long backoff, timeout = 0;
  263 
  264       /* Calculate the backoff value so we get good fork throughput.  */
  265       backoff = do_backoff * forks;
  266       dbg (stdout, "using backoff sleep of %llius\n", backoff);
  267 
  268       /* If we are supposed to respect a timeout, calculate it.  */
  269       if (do_timeout)
  270         {
  271           long long currenttime;
  272 
  273           /* Acquire current time.  */
  274           if ((currenttime = time (NULL)) == -1)
  275             {
  276               perror ("error acquiring current time");
  277               exit (1);
  278             }
  279 
  280           /* Calculate timeout based on current time.  */
  281           timeout = do_timeout - (currenttime - starttime);
  282 
  283           if (timeout > 0)
  284             {
  285               dbg (stdout, "setting timeout to %llis\n", timeout);
  286             }
  287           else
  288             {
  289               wrn (stderr, "used up time before all workers dispatched\n");
  290               break;
  291             }
  292         }
  293 
  294       if (do_cpu)
  295         {
  296           switch (pid = fork ())
  297             {
  298             case 0:            /* child */
  299               alarm (timeout);
  300               usleep (backoff);
  301               if (do_dryrun)
  302                 exit (0);
  303               exit (hogcpu ());
  304             case -1:           /* error */
  305               err (stderr, "fork failed: %s\n", strerror (errno));
  306               break;
  307             default:           /* parent */
  308               dbg (stdout, "--> hogcpu worker %lli [%i] forked\n",
  309                    do_cpu, pid);
  310               ++children;
  311             }
  312           --do_cpu;
  313         }
  314 
  315       if (do_io)
  316         {
  317           switch (pid = fork ())
  318             {
  319             case 0:            /* child */
  320               alarm (timeout);
  321               usleep (backoff);
  322               if (do_dryrun)
  323                 exit (0);
  324               exit (hogio ());
  325             case -1:           /* error */
  326               err (stderr, "fork failed: %s\n", strerror (errno));
  327               break;
  328             default:           /* parent */
  329               dbg (stdout, "--> hogio worker %lli [%i] forked\n", do_io, pid);
  330               ++children;
  331             }
  332           --do_io;
  333         }
  334 
  335       if (do_vm)
  336         {
  337           switch (pid = fork ())
  338             {
  339             case 0:            /* child */
  340               alarm (timeout);
  341               usleep (backoff);
  342               if (do_dryrun)
  343                 exit (0);
  344               exit (hogvm
  345                     (do_vm_bytes, do_vm_stride, do_vm_hang, do_vm_keep));
  346             case -1:           /* error */
  347               err (stderr, "fork failed: %s\n", strerror (errno));
  348               break;
  349             default:           /* parent */
  350               dbg (stdout, "--> hogvm worker %lli [%i] forked\n", do_vm, pid);
  351               ++children;
  352             }
  353           --do_vm;
  354         }
  355 
  356       if (do_hdd)
  357         {
  358           switch (pid = fork ())
  359             {
  360             case 0:            /* child */
  361               alarm (timeout);
  362               usleep (backoff);
  363               if (do_dryrun)
  364                 exit (0);
  365               exit (hoghdd (do_hdd_bytes));
  366             case -1:           /* error */
  367               err (stderr, "fork failed: %s\n", strerror (errno));
  368               break;
  369             default:           /* parent */
  370               dbg (stdout, "--> hoghdd worker %lli [%i] forked\n",
  371                    do_hdd, pid);
  372               ++children;
  373             }
  374           --do_hdd;
  375         }
  376     }
  377 
  378   /* Wait for our children to exit.  */
  379   while (children)
  380     {
  381       int status, ret;
  382 
  383       if ((pid = wait (&status)) > 0)
  384         {
  385           --children;
  386 
  387           if (WIFEXITED (status))
  388             {
  389               if ((ret = WEXITSTATUS (status)) == 0)
  390                 {
  391                   dbg (stdout, "<-- worker %i returned normally\n", pid);
  392                 }
  393               else
  394                 {
  395                   err (stderr, "<-- worker %i returned error %i\n", pid, ret);
  396                   ++retval;
  397                   wrn (stderr, "now reaping child worker processes\n");
  398                   if (signal (SIGUSR1, SIG_IGN) == SIG_ERR)
  399                     err (stderr, "handler error: %s\n", strerror (errno));
  400                   if (kill (-1 * getpid (), SIGUSR1) == -1)
  401                     err (stderr, "kill error: %s\n", strerror (errno));
  402                 }
  403             }
  404           else if (WIFSIGNALED (status))
  405             {
  406               if ((ret = WTERMSIG (status)) == SIGALRM)
  407                 {
  408                   dbg (stdout, "<-- worker %i signalled normally\n", pid);
  409                 }
  410               else if ((ret = WTERMSIG (status)) == SIGUSR1)
  411                 {
  412                   dbg (stdout, "<-- worker %i reaped\n", pid);
  413                 }
  414               else
  415                 {
  416                   err (stderr, "<-- worker %i got signal %i\n", pid, ret);
  417                   ++retval;
  418                   wrn (stderr, "now reaping child worker processes\n");
  419                   if (signal (SIGUSR1, SIG_IGN) == SIG_ERR)
  420                     err (stderr, "handler error: %s\n", strerror (errno));
  421                   if (kill (-1 * getpid (), SIGUSR1) == -1)
  422                     err (stderr, "kill error: %s\n", strerror (errno));
  423                 }
  424             }
  425           else
  426             {
  427               err (stderr, "<-- worker %i exited abnormally\n", pid);
  428               ++retval;
  429             }
  430         }
  431       else
  432         {
  433           err (stderr, "error waiting for worker: %s\n", strerror (errno));
  434           ++retval;
  435           break;
  436         }
  437     }
  438 
  439   /* Record our stop time.  */
  440   if ((stoptime = time (NULL)) == -1)
  441     {
  442       err (stderr, "failed to acquire current time\n");
  443       exit (1);
  444     }
  445 
  446   /* Calculate our runtime.  */
  447   runtime = stoptime - starttime;
  448 
  449   /* Print final status message.  */
  450   if (retval)
  451     {
  452       err (stderr, "failed run completed in %lis\n", runtime);
  453     }
  454   else
  455     {
  456       out (stdout, "successful run completed in %lis\n", runtime);
  457     }
  458 
  459   exit (retval);
  460 }
  461 
  462 int
  463 hogcpu (void)
  464 {
  465   while (1)
  466     sqrt (rand ());
  467 
  468   return 0;
  469 }
  470 
  471 int
  472 hogio ()
  473 {
  474   while (1)
  475     sync ();
  476 
  477   return 0;
  478 }
  479 
  480 int
  481 hogvm (long long bytes, long long stride, long long hang, int keep)
  482 {
  483   long long i;
  484   char *ptr = 0;
  485   char c;
  486   int do_malloc = 1;
  487 
  488   while (1)
  489     {
  490       if (do_malloc)
  491         {
  492           dbg (stdout, "allocating %lli bytes ...\n", bytes);
  493           if (!(ptr = (char *) malloc (bytes * sizeof (char))))
  494             {
  495               err (stderr, "hogvm malloc failed: %s\n", strerror (errno));
  496               return 1;
  497             }
  498           if (keep)
  499             do_malloc = 0;
  500         }
  501 
  502       dbg (stdout, "touching bytes in strides of %lli bytes ...\n", stride);
  503       for (i = 0; i < bytes; i += stride)
  504         ptr[i] = 'Z';           /* Ensure that COW happens.  */
  505 
  506       if (hang == 0)
  507         {
  508           dbg (stdout, "sleeping forever with allocated memory\n");
  509           while (1)
  510             sleep (1024);
  511         }
  512       else if (hang > 0)
  513         {
  514           dbg (stdout, "sleeping for %llis with allocated memory\n", hang);
  515           sleep (hang);
  516         }
  517 
  518       for (i = 0; i < bytes; i += stride)
  519         {
  520           c = ptr[i];
  521           if (c != 'Z')
  522             {
  523               err (stderr, "memory corruption at: %p\n", ptr + i);
  524               return 1;
  525             }
  526         }
  527 
  528       if (do_malloc)
  529         {
  530           free (ptr);
  531           dbg (stdout, "freed %lli bytes\n", bytes);
  532         }
  533     }
  534 
  535   return 0;
  536 }
  537 
  538 int
  539 hoghdd (long long bytes)
  540 {
  541   long long i, j;
  542   int fd;
  543   int chunk = (1024 * 1024) - 1;        /* Minimize slow writing.  */
  544   char buff[chunk];
  545 
  546   /* Initialize buffer with some random ASCII data.  */
  547   dbg (stdout, "seeding %d byte buffer with random data\n", chunk);
  548   for (i = 0; i < chunk - 1; i++)
  549     {
  550       j = rand ();
  551       j = (j < 0) ? -j : j;
  552       j %= 95;
  553       j += 32;
  554       buff[i] = j;
  555     }
  556   buff[i] = '\n';
  557 
  558   while (1)
  559     {
  560       char name[] = "./stress.XXXXXX";
  561 
  562       if ((fd = mkstemp (name)) == -1)
  563         {
  564           err (stderr, "mkstemp failed: %s\n", strerror (errno));
  565           return 1;
  566         }
  567 
  568       dbg (stdout, "opened %s for writing %lli bytes\n", name, bytes);
  569 
  570       dbg (stdout, "unlinking %s\n", name);
  571       if (unlink (name) == -1)
  572         {
  573           err (stderr, "unlink of %s failed: %s\n", name, strerror (errno));
  574           return 1;
  575         }
  576 
  577       dbg (stdout, "fast writing to %s\n", name);
  578       for (j = 0; bytes == 0 || j + chunk < bytes; j += chunk)
  579         {
  580           if (write (fd, buff, chunk) == -1)
  581             {
  582               err (stderr, "write failed: %s\n", strerror (errno));
  583               return 1;
  584             }
  585         }
  586 
  587       dbg (stdout, "slow writing to %s\n", name);
  588       for (; bytes == 0 || j < bytes - 1; j++)
  589         {
  590           if (write (fd, &buff[j % chunk], 1) == -1)
  591             {
  592               err (stderr, "write failed: %s\n", strerror (errno));
  593               return 1;
  594             }
  595         }
  596       if (write (fd, "\n", 1) == -1)
  597         {
  598           err (stderr, "write failed: %s\n", strerror (errno));
  599           return 1;
  600         }
  601       ++j;
  602 
  603       dbg (stdout, "closing %s after %lli bytes\n", name, j);
  604       close (fd);
  605     }
  606 
  607   return 0;
  608 }
  609 
  610 /* Convert a string representation of a number with an optional size suffix
  611  * to a long long.
  612  */
  613 long long
  614 atoll_b (const char *nptr)
  615 {
  616   int pos;
  617   char suffix;
  618   long long factor = 0;
  619   long long value;
  620 
  621   if ((pos = strlen (nptr) - 1) < 0)
  622     {
  623       err (stderr, "invalid string\n");
  624       exit (1);
  625     }
  626 
  627   switch (suffix = nptr[pos])
  628     {
  629     case 'b':
  630     case 'B':
  631       factor = 0;
  632       break;
  633     case 'k':
  634     case 'K':
  635       factor = 10;
  636       break;
  637     case 'm':
  638     case 'M':
  639       factor = 20;
  640       break;
  641     case 'g':
  642     case 'G':
  643       factor = 30;
  644       break;
  645     default:
  646       if (suffix < '0' || suffix > '9')
  647         {
  648           err (stderr, "unrecognized suffix: %c\n", suffix);
  649           exit (1);
  650         }
  651     }
  652 
  653   if (sscanf (nptr, "%lli", &value) != 1)
  654     {
  655       err (stderr, "invalid number: %s\n", nptr);
  656       exit (1);
  657     }
  658 
  659   value = value << factor;
  660 
  661   return value;
  662 }
  663 
  664 /* Convert a string representation of a number with an optional time suffix
  665  * to a long long.
  666  */
  667 long long
  668 atoll_s (const char *nptr)
  669 {
  670   int pos;
  671   char suffix;
  672   long long factor = 1;
  673   long long value;
  674 
  675   if ((pos = strlen (nptr) - 1) < 0)
  676     {
  677       err (stderr, "invalid string\n");
  678       exit (1);
  679     }
  680 
  681   switch (suffix = nptr[pos])
  682     {
  683     case 's':
  684     case 'S':
  685       factor = 1;
  686       break;
  687     case 'm':
  688     case 'M':
  689       factor = 60;
  690       break;
  691     case 'h':
  692     case 'H':
  693       factor = 60 * 60;
  694       break;
  695     case 'd':
  696     case 'D':
  697       factor = 60 * 60 * 24;
  698       break;
  699     case 'y':
  700     case 'Y':
  701       factor = 60 * 60 * 24 * 365;
  702       break;
  703     default:
  704       if (suffix < '0' || suffix > '9')
  705         {
  706           err (stderr, "unrecognized suffix: %c\n", suffix);
  707           exit (1);
  708         }
  709     }
  710 
  711   if (sscanf (nptr, "%lli", &value) != 1)
  712     {
  713       err (stderr, "invalid number: %s\n", nptr);
  714       exit (1);
  715     }
  716 
  717   value = value * factor;
  718 
  719   return value;
  720 }
  721 
  722 int
  723 version (int status)
  724 {
  725   char *mesg = "%s %s\n";
  726 
  727   fprintf (stdout, mesg, global_progname, VERSION);
  728 
  729   if (status <= 0)
  730     exit (-1 * status);
  731 
  732   return 0;
  733 }
  734 
  735 int
  736 usage (int status)
  737 {
  738   char *mesg =
  739     "`%s' imposes certain types of compute stress on your system\n\n"
  740     "Usage: %s [OPTION [ARG]] ...\n"
  741     " -?, --help         show this help statement\n"
  742     "     --version      show version statement\n"
  743     " -v, --verbose      be verbose\n"
  744     " -q, --quiet        be quiet\n"
  745     " -n, --dry-run      show what would have been done\n"
  746     " -t, --timeout N    timeout after N seconds\n"
  747     "     --backoff N    wait factor of N microseconds before work starts\n"
  748     " -c, --cpu N        spawn N workers spinning on sqrt()\n"
  749     " -i, --io N         spawn N workers spinning on sync()\n"
  750     " -m, --vm N         spawn N workers spinning on malloc()/free()\n"
  751     "     --vm-bytes B   malloc B bytes per vm worker (default is 256MB)\n"
  752     "     --vm-stride B  touch a byte every B bytes (default is 4096)\n"
  753     "     --vm-hang N    sleep N secs before free (default none, 0 is inf)\n"
  754     "     --vm-keep      redirty memory instead of freeing and reallocating\n"
  755     " -d, --hdd N        spawn N workers spinning on write()/unlink()\n"
  756     "     --hdd-bytes B  write B bytes per hdd worker (default is 1GB)\n\n"
  757     "Example: %s --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10s\n\n"
  758     "Note: Numbers may be suffixed with s,m,h,d,y (time) or B,K,M,G (size).\n";
  759 
  760   fprintf (stdout, mesg, global_progname, global_progname, global_progname);
  761 
  762   if (status <= 0)
  763     exit (-1 * status);
  764 
  765   return 0;
  766 }