Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 1-4 of 4 total  RSS 

Disk/flash benchmark

Adapted from a LKML posted program. I think I added write support, this for benchmarking random access writes on flash.

   1  
   2  /* Simple multi-threaded I/O benchmark program.
   3   * Copyright (C) Michael Tokarev, mjt@tls.msk.ru
   4   * Public domain.
   5   *
   6   * To compile:
   7   *   gcc -o iot iot.c -lpthread
   8   * To run:
   9   *   Either with disk device or with pre-existing file.
  10   *    ./iot [options] filename
  11   *   Filename is the file or device to test on.
  12   *   By default it uses 8Kb I/O blocks and does sequential read test
  13   *   until interrupted.
  14   *   To indicate when to stop:
  15   *     -t sec - run for this many seconds, say, 30, to eliminate random
  16   *       noise.
  17   *     -i num - perform this many I/O operations
  18   *   To indicate R/W mode:
  19   *     -wn, -Wn, -rn, -Rn --
  20   *       perform linear or random write (note: all data will be lost!),
  21   *       or linear or random read, using given number of threads (n).
  22   *   I/O modes:
  23   *    -s - syncronous write (O_SYNC)
  24   *    -d - direct I/O (O_DIRECT)
  25   *    -b bs - block size in bytes
  26   *   And finally:
  27   *    -h - display usage.
  28   * Example:
  29   *   ./iot -t30 -W4 -R4 -d -b8192 /dev/sdb
  30   * perform random read/write test (4 readers and 4 writers)
  31   * for 30 seconds using direct I/O and block size of 8Kb.
  32   *
  33   * Note: for small blocksize (<64Kb at least) and using direct random I/O,
  34   * nowadays drives sometimes gives transfer rates below 1Mb/sec - this is
  35   * expectable, don't be afraid of so low numbers.  The reason is simple:
  36   * in order to access a given block of data, a disk drive has to seek to the
  37   * right track (average seek time) and wait for the right sector to be near
  38   * the head (rotation latency).  Sum up the two, and divide 1 sec to the
  39   * result -- you'll have max number of requests/sec a drive can perform,
  40   * not counting the actual data transfer (which reduces this number further).
  41   * With, say, 5ms seek time + rotation latency, we'll have 200 requests/sec,
  42   * which, with 4Kb request size, will be about 800Kb/sec - which is below
  43   * 1Mb/sec, not counting the actual transfer...
  44   *
  45   */
  46  
  47  #define _GNU_SOURCE
  48  #define _BSD_SOURCE
  49  #define _LARGEFILE_SOURCE
  50  #define _FILE_OFFSET_BITS 64
  51  
  52  //#define USE_DEV_URANDOM       /* was not a good idea */
  53  
  54  #include <sys/types.h>
  55  #include <unistd.h>
  56  #include <fcntl.h>
  57  #include <errno.h>
  58  #include <stdlib.h>
  59  #include <stdio.h>
  60  #include <sys/time.h>
  61  #include <sys/ioctl.h>
  62  #include <signal.h>
  63  #include <pthread.h>
  64  #include <string.h>
  65  
  66  #ifndef BLKGETSIZE64
  67  #define BLKGETSIZE64 _IOR(0x12,114,size_t)
  68   /* linux-specific. return device size in bytes (u64 *arg) */
  69  #endif
  70  
  71  static void edie(const char *what) {
  72    fprintf(stderr, "%s: %m \n", what);
  73    exit(1);
  74  }
  75  
  76  #ifdef USE_DEV_URANDOM
  77  static int randfd;
  78  #endif
  79  static int oflags;              // open flags
  80  static char *fn;                // filename
  81  static unsigned bs = 8192;      // block size
  82  static unsigned bc;             // block count (device size in blocks)
  83  static unsigned bm;             // blocks to do
  84  
  85  #define MFrnd   1
  86  #define MFwrt   2
  87  #define LinRd   0
  88  #define RndRd   MFrnd
  89  #define LinWr   MFwrt
  90  #define RndWr   (MFrnd|MFwrt)
  91  
  92  struct state {
  93    int fd;
  94    char *buf;
  95    unsigned ioc;         // I/O count
  96    int (*workfn)(struct state *, unsigned blocknr);
  97    unsigned (*posfn)(struct state *s);
  98    unsigned opi;         // operation index
  99    unsigned i;           // curidx
 100    double stime;         // start time
 101    unsigned bn;          // current block number for linear i/o
 102  };
 103  static unsigned int alternate;
 104  static unsigned tioc;   // total i/o count
 105  static struct state *states;
 106  static unsigned nt[4];
 107  static unsigned ntt;
 108  static volatile unsigned running;
 109  static const char *const ion[4] = { "LinRd", "RndRd", "LinWr", "RndWr" };
 110  
 111  static pthread_mutex_t rnmtx = PTHREAD_MUTEX_INITIALIZER;
 112  static pthread_cond_t rncond = PTHREAD_COND_INITIALIZER;
 113  
 114  static double curtime(void) {
 115    struct timeval tv;
 116    gettimeofday(&tv, NULL);
 117    return tv.tv_sec + tv.tv_usec / 1000000.0;
 118  }
 119  
 120  static unsigned randpos(struct state *s) {
 121    unsigned n;
 122  #ifdef USE_DEV_URANDOM
 123    read(randfd, &n, sizeof(n));
 124  #else
 125    n = lrand48();
 126  #endif
 127    s = s;
 128    if(alternate == 1) {
 129      if(n > bc/2) {
 130        return bc-1;
 131      } else {
 132        return 0;
 133      }
 134    }
 135    return n % bc;
 136  }
 137  
 138  static unsigned linpos(struct state *s) {
 139    if (s->bn >= bc)
 140      s->bn = 0;
 141    return s->bn++;
 142  }
 143  
 144  static int wwriter(struct state *s, unsigned b) {
 145    return pwrite(s->fd, s->buf, bs, (off_t)b * bs);
 146  }
 147  static int wreader(struct state *s, unsigned b) {
 148    return pread(s->fd, s->buf, bs, (off_t)b * bs);
 149  }
 150  
 151  static void pst(FILE *f) {
 152    double ct = curtime();
 153    double r[4] = { 0, 0, 0, 0 };
 154    unsigned c[4] = { 0, 0, 0, 0 };
 155    unsigned i;
 156    double d;
 157    for(i = 0; i < ntt; ++i) {
 158      d = ct - states[i].stime;
 159      r[states[i].opi] += states[i].ioc / d;
 160      c[states[i].opi] += states[i].ioc;
 161    }
 162  #if 1
 163    for(i = 0; i < 4; ++i)
 164      if (c[i])
 165        fprintf(f, " %s %u %.2f", ion[i], c[i], r[i] * bs / 1024 / 1024);
 166  #endif
 167  }
 168  
 169  static void incc() {
 170    if (!(++tioc % 1000))
 171      pthread_cond_signal(&rncond);
 172  }
 173  static void decnr() {
 174    pthread_mutex_lock(&rnmtx);
 175    --running;
 176    pthread_mutex_unlock(&rnmtx);
 177    pthread_cond_broadcast(&rncond);
 178  }
 179  
 180  static volatile int term;
 181  
 182  void *worker(void *arg) {
 183    struct state *s = arg;
 184    s->workfn = s->opi & MFwrt ? wwriter : wreader;
 185    s->posfn  = s->opi & MFrnd ? randpos : linpos;
 186    s->fd = open(fn, (s->opi & MFwrt ? O_WRONLY : O_RDONLY) | oflags);
 187    if (s->fd < 0) {
 188      int e = errno;
 189      decnr();
 190      errno = e;
 191      edie(fn);
 192    }
 193    s->stime = curtime();
 194    for(;;) {
 195      if (term) break;
 196      if (s->workfn(s, s->posfn(s)) < 0) {
 197        perror(ion[s->opi]);
 198        break;
 199      }
 200      ++s->ioc;
 201      incc();
 202      if (bm && s->ioc >= bm) break;
 203    }
 204    decnr();
 205    return 0;
 206  }
 207  
 208  static void sig(int s) {
 209    term = s;
 210  }
 211  
 212  int main(int argc, char **argv) {
 213    int c;
 214    unsigned i, j;
 215    unsigned tm = 0;
 216    struct state *s;
 217    char *buf;
 218    struct timeval  first,
 219                  second,
 220                  lapsed;
 221  
 222    while((c = getopt(argc, argv, "r::R::w::W::adsb:n:i:t:h")) != EOF) switch(c) {
 223    case 'r': nt[LinRd] = optarg ? atoi(optarg) : 1; break;
 224    case 'R': nt[RndRd] = optarg ? atoi(optarg) : 1; break;
 225    case 'w': nt[LinWr] = optarg ? atoi(optarg) : 1; break;
 226    case 'W': nt[RndWr] = optarg ? atoi(optarg) : 1; break;
 227    case 'd': oflags |= O_DIRECT; break;
 228    case 's': oflags |= O_SYNC; break;
 229    case 'b': bs = atoi(optarg); break;
 230    case 'n': bc = atoi(optarg); break;
 231    case 'i': bm = atoi(optarg); break;
 232    case 't': tm = atoi(optarg); break;
 233    case 'a': alternate = 1; break;
 234    case 'h':
 235      puts(
 236  "iotest: perform I/O speed test\n"
 237  "Usage is: iotest [options] device-or-file\n"
 238  "options:\n"
 239  " -r[n] - linear read test (n readers)\n"
 240  " -R[n] - random read test (n readers)\n"
 241  " -w[n] - linear write test (n writers)\n"
 242  " -W[n] - random write test (n writers)\n"
 243  " -d - use direct I/O (O_DIRECT)\n"
 244  " -s - use syncronous I/O (O_SYNC)\n"
 245  " -b bs - blocksize (default is 8192)\n"
 246  " -n bc - block count (default is whole device/file)\n"
 247  " -i nb - number of I/O iterations to perform\n"
 248  " -t sec - time to spend on all I/O\n"
 249  " -h - this help\n"
 250  "It's ok to specify all, one or some of -r,-R,-w and -W\n"
 251  );
 252      return 0;
 253    default: fprintf(stderr, "try `iotest -h' for help\n"); exit(1);
 254    }
 255  
 256    if (optind + 1 != argc) {
 257      fprintf(stderr, "exactly one device/file argument expected\n");
 258      return 1;
 259    }
 260    fn = argv[optind];
 261  
 262    ntt = nt[0] + nt[1] + nt[2] + nt[3];
 263    if (!ntt)
 264      nt[LinRd] = ntt = 1;
 265  
 266    c = open(fn, (nt[LinWr] + nt[RndWr] ? O_RDWR : O_RDONLY) | oflags);
 267    if (c < 0) edie(fn);
 268    if (!bc) {
 269      unsigned long long sz;
 270      struct stat st;
 271      fstat(c, &st);
 272      if (st.st_size) sz = st.st_size;
 273      else ioctl(c, BLKGETSIZE64, &sz);
 274      bc = sz / bs;
 275      fprintf(stderr, "size = %lld (%u blocks)\n", sz, bc);
 276    }
 277    close(c);
 278    if (nt[RndRd] || nt[RndWr]) {
 279  #ifdef USE_DEV_URANDOM
 280      randfd = open("/dev/urandom", O_RDONLY);
 281      if (randfd < 0) edie("/dev/urandom");
 282  #else
 283  #if 0
 284      struct timeval tv;
 285      gettimeofday(&tv, NULL);
 286      srand48(tv.tv_usec ^ getpid());
 287  #else
 288      srand48(0xfeda432); // arbitrary, to get repeated values on repeated runs
 289  #endif
 290  #endif
 291    }
 292  
 293    gettimeofday(&first, NULL);
 294  
 295    states = calloc(ntt, sizeof(*states));
 296    s = states;
 297  
 298    buf = valloc(ntt * bs);
 299    if (tm) {
 300      signal(SIGALRM, sig);
 301      alarm(tm);
 302    }
 303    running = ntt;
 304    for(j = 0; j < 4; ++j)
 305      for(i = 0; i < nt[j]; ++i) {
 306        pthread_t t;
 307        s->buf = buf; buf += bs;
 308        s->opi = j;
 309        s->i = i;
 310        pthread_create(&t, NULL, worker, s++);
 311      }
 312    while(running) {
 313      pthread_cond_wait(&rncond, &rnmtx);
 314      putc('\r', stderr);
 315      pst(stderr);
 316    }
 317  
 318    putc('\r', stderr);
 319    pst(stdout);
 320    putc('\n', stdout);
 321  
 322    gettimeofday(&second, NULL);
 323  
 324    if (first.tv_usec > second.tv_usec) {
 325      second.tv_usec += 1000000;
 326      second.tv_sec--;
 327    }
 328  
 329    lapsed.tv_usec = second.tv_usec - first.tv_usec;
 330    lapsed.tv_sec  = second.tv_sec  - first.tv_sec;
 331  
 332  
 333  
 334    if (nt[RndRd] || nt[RndWr]) {
 335          printf("I/O latency: %f\n", (lapsed.tv_sec*1000+(lapsed.tv_usec/1000))/(float)tioc);
 336  
 337    }
 338  
 339    return 0;
 340  }
 341  

Descriptive errors in C using GCC macros

Function to generate descriptive errors (line number, function name, etc).

   1  
   2  #include <stdlib.h>
   3  #include <stdio.h>
   4  #include <stdarg.h>
   5  #include <string.h>
   6  
   7  #ifdef __OPTIMIZE__
   8  #define __OPT__ 1
   9  #else
  10  #define __OPT__ 0
  11  #endif
  12  
  13  #ifdef __OPTIMIZE_SIZE__
  14  #define __OPT_SIZE__ 1
  15  #else
  16  #define __OPT_SIZE__ 0
  17  #endif
  18  
  19  #define err_print(args...) __err_print(__FILE__, __FUNCTION__, __LINE__, __DATE__ " " __TIME__, __VERSION__, __OPT__, __OPT_SIZE__, ##args)
  20  void __err_print(char *file, char *function, int line, char *date, char *version, int opt, int opt_size, char *txt, ...)
  21  {
  22          va_list argp;
  23  
  24          puts("** ERROR! **");
  25          printf("File:                 \t %s\n",file);
  26          printf("Function:             \t %s\n",function);
  27          printf("Line:                 \t %d\n",line);
  28          printf("Compilation date:     \t %s\n",date);
  29          printf("Compilator version:   \t %s\n",version);
  30          printf("Optimization:         \t %s\n",opt==1 ? "Yes" : "No");
  31          printf("Size optimization:    \t %s\n",opt_size==1 ? "Yes" : "No");
  32  
  33          if (txt == NULL)
  34                  return;
  35          puts("Description:\n>>>");
  36          va_start(argp, txt);
  37          vprintf(txt, argp);
  38          va_end(argp);
  39          puts("\n<<<");
  40  }
  41  
  42  void other_function() {
  43          err_print("other %s (%d+%d=%d)", "description",2,2,5);
  44  }
  45  
  46  int main() {
  47          err_print("test %d", 2);
  48          puts("");
  49          other_function();
  50          return 0;
  51  }

Compiling on Ubuntu

sudo apt-get install build-essential

gcc #define

   1  
   2  gcc -E -dM -x c /dev/null
« Newer Snippets
Older Snippets »
Showing 1-4 of 4 total  RSS