~dave-terei/libmemcached/sasl-fixes

929.1.32 by Brian Aker
Reverting back to older version of memslap, and renaming other version
1
/*
2
 *  memslap
3
 *
4
 *  (c) Copyright 2009, Schooner Information Technology, Inc.
5
 *  All rights reserved.
6
 *  http://www.schoonerinfotech.com/
7
 *
8
 *  Use and distribution licensed under the BSD license.  See
9
 *  the COPYING file for full text.
10
 *
11
 *  Authors:
12
 *      Brian Aker
13
 *      Mingqiang Zhuang <mingqiangzhuang@hengtiansoft.com>
14
 *
15
 */
16
#include "config.h"
17
18
#include <stdlib.h>
19
#include <getopt.h>
20
#include <limits.h>
21
#if TIME_WITH_SYS_TIME
22
# include <sys/time.h>
23
# include <time.h>
24
#else
25
# if HAVE_SYS_TIME_H
26
#  include <sys/time.h>
27
# else
28
#  include <time.h>
29
# endif
30
#endif
31
32
33
#include "ms_sigsegv.h"
34
#include "ms_setting.h"
35
#include "ms_thread.h"
36
37
#define PROGRAM_NAME    "memslap"
38
#define PROGRAM_DESCRIPTION \
39
                        "Generates workload against memcached servers."
40
41
#ifdef __sun
42
  /* For some odd reason the option struct on solaris defines the argument
43
   * as char* and not const char*
44
   */
45
#define OPTIONSTRING char*
46
#else
47
#define OPTIONSTRING const char*
48
#endif
49
50
/* options */
51
static struct option long_options[]=
52
{
53
  { (OPTIONSTRING)"servers",        required_argument,            NULL,
54
    OPT_SERVERS            },
55
  { (OPTIONSTRING)"threads",        required_argument,            NULL,
56
    OPT_THREAD_NUMBER      },
57
  { (OPTIONSTRING)"concurrency",    required_argument,            NULL,
58
    OPT_CONCURRENCY        },
59
  { (OPTIONSTRING)"conn_sock",      required_argument,            NULL,
60
    OPT_SOCK_PER_CONN      },
61
  { (OPTIONSTRING)"execute_number", required_argument,            NULL,
62
    OPT_EXECUTE_NUMBER     },
63
  { (OPTIONSTRING)"time",           required_argument,            NULL,
64
    OPT_TIME               },
65
  { (OPTIONSTRING)"cfg_cmd",        required_argument,            NULL,
66
    OPT_CONFIG_CMD         },
67
  { (OPTIONSTRING)"win_size",       required_argument,            NULL,
68
    OPT_WINDOW_SIZE        },
69
  { (OPTIONSTRING)"fixed_size",     required_argument,            NULL,
70
    OPT_FIXED_LTH          },
71
  { (OPTIONSTRING)"verify",         required_argument,            NULL,
72
    OPT_VERIFY             },
73
  { (OPTIONSTRING)"division",       required_argument,            NULL,
74
    OPT_GETS_DIVISION      },
75
  { (OPTIONSTRING)"stat_freq",      required_argument,            NULL,
76
    OPT_STAT_FREQ          },
77
  { (OPTIONSTRING)"exp_verify",     required_argument,            NULL,
78
    OPT_EXPIRE             },
79
  { (OPTIONSTRING)"overwrite",      required_argument,            NULL,
80
    OPT_OVERWRITE          },
81
  { (OPTIONSTRING)"reconnect",      no_argument,                  NULL,
82
    OPT_RECONNECT          },
83
  { (OPTIONSTRING)"udp",            no_argument,                  NULL,
84
    OPT_UDP                },
85
  { (OPTIONSTRING)"facebook",       no_argument,                  NULL,
86
    OPT_FACEBOOK_TEST      },
87
  { (OPTIONSTRING)"binary",         no_argument,                  NULL,
88
    OPT_BINARY_PROTOCOL    },
89
  { (OPTIONSTRING)"tps",            required_argument,            NULL,
90
    OPT_TPS                },
91
  { (OPTIONSTRING)"rep_write",      required_argument,            NULL,
92
    OPT_REP_WRITE_SRV      },
93
  { (OPTIONSTRING)"verbose",        no_argument,                  NULL,
94
    OPT_VERBOSE            },
95
  { (OPTIONSTRING)"help",           no_argument,                  NULL,
96
    OPT_HELP               },
97
  { (OPTIONSTRING)"version",        no_argument,                  NULL,
98
    OPT_VERSION            },
99
  { 0, 0, 0, 0 },
100
};
101
102
/* Prototypes */
103
static void ms_sync_lock_init(void);
104
static void ms_sync_lock_destroy(void);
105
static void ms_global_struct_init(void);
106
static void ms_global_struct_destroy(void);
107
static void ms_version_command(const char *command_name);
108
static const char *ms_lookup_help(ms_options_t option);
109
static int64_t ms_parse_time(void);
110
static int64_t ms_parse_size(void);
111
static void ms_options_parse(int argc, char *argv[]);
112
static int ms_check_para(void);
113
static void ms_statistic_init(void);
114
static void ms_stats_init(void);
115
static void ms_print_statistics(int in_time);
116
static void ms_print_memslap_stats(struct timeval *start_time,
117
                                   struct timeval *end_time);
118
static void ms_monitor_slap_mode(void);
119
void ms_help_command(const char *command_name, const char *description);
120
121
122
/* initialize the global locks */
123
static void ms_sync_lock_init()
124
{
125
  ms_global.init_lock.count= 0;
126
  pthread_mutex_init(&ms_global.init_lock.lock, NULL);
127
  pthread_cond_init(&ms_global.init_lock.cond, NULL);
128
129
  ms_global.warmup_lock.count = 0;
130
  pthread_mutex_init(&ms_global.warmup_lock.lock, NULL);
131
  pthread_cond_init(&ms_global.warmup_lock.cond, NULL);
132
133
  ms_global.run_lock.count= 0;
134
  pthread_mutex_init(&ms_global.run_lock.lock, NULL);
135
  pthread_cond_init(&ms_global.run_lock.cond, NULL);
136
137
  pthread_mutex_init(&ms_global.quit_mutex, NULL);
138
  pthread_mutex_init(&ms_global.seq_mutex, NULL);
139
} /* ms_sync_lock_init */
140
141
142
/* destroy the global locks */
143
static void ms_sync_lock_destroy()
144
{
145
  pthread_mutex_destroy(&ms_global.init_lock.lock);
146
  pthread_cond_destroy(&ms_global.init_lock.cond);
147
148
  pthread_mutex_destroy(&ms_global.warmup_lock.lock);
149
  pthread_cond_destroy(&ms_global.warmup_lock.cond);
150
151
  pthread_mutex_destroy(&ms_global.run_lock.lock);
152
  pthread_cond_destroy(&ms_global.run_lock.cond);
153
154
  pthread_mutex_destroy(&ms_global.quit_mutex);
155
  pthread_mutex_destroy(&ms_global.seq_mutex);
156
157
  if (ms_setting.stat_freq > 0)
158
  {
159
    pthread_mutex_destroy(&ms_statistic.stat_mutex);
160
  }
161
} /* ms_sync_lock_destroy */
162
163
164
/* initialize the global structure */
165
static void ms_global_struct_init()
166
{
167
  ms_sync_lock_init();
168
  ms_global.finish_warmup= false;
169
  ms_global.time_out= false;
170
}
171
172
173
/* destroy the global structure */
174
static void ms_global_struct_destroy()
175
{
176
  ms_sync_lock_destroy();
177
}
178
179
180
/**
181
 * output the version information
182
 *
183
 * @param command_name, the string of this process
184
 */
185
static void ms_version_command(const char *command_name)
186
{
187
  printf("%s v%u.%u\n", command_name, 1U, 0U);
188
  exit(0);
189
}
190
191
192
/**
193
 * get the description of the option
194
 *
195
 * @param option, option of command line
196
 *
197
 * @return char*, description of the command option
198
 */
199
static const char *ms_lookup_help(ms_options_t option)
200
{
201
  switch (option)
202
  {
203
  case OPT_SERVERS:
204
    return
205
      "List one or more servers to connect. Servers count must be less than\n"
206
      "        threads count. e.g.: --servers=localhost:1234,localhost:11211";
207
208
  case OPT_VERSION:
209
    return "Display the version of the application and then exit.";
210
211
  case OPT_HELP:
212
    return "Display this message and then exit.";
213
214
  case OPT_EXECUTE_NUMBER:
215
    return "Number of operations(get and set) to execute for the\n"
216
           "        given test. Default 1000000.";
217
218
  case OPT_THREAD_NUMBER:
219
    return
220
      "Number of threads to startup, better equal to CPU numbers. Default 8.";
221
222
  case OPT_CONCURRENCY:
223
    return "Number of concurrency to simulate with load. Default 128.";
224
225
  case OPT_FIXED_LTH:
226
    return "Fixed length of value.";
227
228
  case OPT_VERIFY:
229
    return "The proportion of date verification, e.g.: --verify=0.01";
230
231
  case OPT_GETS_DIVISION:
232
    return "Number of keys to multi-get once. Default 1, means single get.";
233
234
  case OPT_TIME:
235
    return
236
      "How long the test to run, suffix: s-seconds, m-minutes, h-hours,\n"
237
      "        d-days e.g.: --time=2h.";
238
239
  case OPT_CONFIG_CMD:
240
    return
241
      "Load the configure file to get command,key and value distribution list.";
242
243
  case OPT_WINDOW_SIZE:
244
    return
245
      "Task window size of each concurrency, suffix: K, M e.g.: --win_size=10k.\n"
246
      "        Default 10k.";
247
248
  case OPT_UDP:
249
    return
250
      "UDP support, default memslap uses TCP, TCP port and UDP port of\n"
251
      "        server must be same.";
252
253
  case OPT_EXPIRE:
254
    return
255
      "The proportion of objects with expire time, e.g.: --exp_verify=0.01.\n"
256
      "        Default no object with expire time";
257
258
  case OPT_OVERWRITE:
259
    return
260
      "The proportion of objects need overwrite, e.g.: --overwrite=0.01.\n"
261
      "        Default never overwrite object.";
262
263
  case OPT_STAT_FREQ:
264
    return
265
      "Frequency of dumping statistic information. suffix: s-seconds,\n"
266
      "        m-minutes, e.g.: --resp_freq=10s.";
267
268
  case OPT_SOCK_PER_CONN:
269
    return "Number of TCP socks per concurrency. Default 1.";
270
271
  case OPT_RECONNECT:
272
    return
273
      "Reconnect support, when connection is closed it will be reconnected.";
274
275
  case OPT_VERBOSE:
276
    return
277
      "Whether it outputs detailed information when verification fails.";
278
279
  case OPT_FACEBOOK_TEST:
280
    return
281
      "Whether it enables facebook test feature, set with TCP and multi-get with UDP.";
282
283
  case OPT_BINARY_PROTOCOL:
284
    return
285
      "Whether it enables binary protocol. Default with ASCII protocol.";
286
287
  case OPT_TPS:
288
    return "Expected throughput, suffix: K, e.g.: --tps=10k.";
289
290
  case OPT_REP_WRITE_SRV:
291
    return "The first nth servers can write data, e.g.: --rep_write=2.";
292
293
  default:
294
    return "Forgot to document this option :)";
295
  } /* switch */
296
} /* ms_lookup_help */
297
298
299
/**
300
 * output the help information
301
 *
302
 * @param command_name, the string of this process
303
 * @param description, description of this process
304
 * @param long_options, global options array
305
 */
306
void ms_help_command(const char *command_name, const char *description)
307
{
308
  char *help_message= NULL;
309
310
  printf("%s v%u.%u\n", command_name, 1U, 0U);
311
  printf("    %s\n\n", description);
312
  printf(
313
    "Usage:\n"
314
    "    memslap -hV | -s servers [-F config_file] [-t time | -x exe_num] [...]\n\n"
315
    "Options:\n");
316
317
  for (int x= 0; long_options[x].name; x++)
318
  {
319
    printf("    -%c, --%s%c\n", long_options[x].val, long_options[x].name,
320
           long_options[x].has_arg ? '=' : ' ');
321
322
    if ((help_message= (char *)ms_lookup_help(long_options[x].val)) != NULL)
323
    {
324
      printf("        %s\n", help_message);
325
    }
326
  }
327
328
  printf(
329
    "\nExamples:\n"
330
    "    memslap -s 127.0.0.1:11211 -S 5s\n"
331
    "    memslap -s 127.0.0.1:11211 -t 2m -v 0.2 -e 0.05 -b\n"
332
    "    memslap -s 127.0.0.1:11211 -F config -t 2m -w 40k -S 20s -o 0.2\n"
333
    "    memslap -s 127.0.0.1:11211 -F config -t 2m -T 4 -c 128 -d 20 -P 40k\n"
334
    "    memslap -s 127.0.0.1:11211 -F config -t 2m -d 50 -a -n 40\n"
335
    "    memslap -s 127.0.0.1:11211,127.0.0.1:11212 -F config -t 2m\n"
336
    "    memslap -s 127.0.0.1:11211,127.0.0.1:11212 -F config -t 2m -p 2\n\n");
337
338
  exit(0);
339
} /* ms_help_command */
340
341
342
/* used to parse the time string  */
343
static int64_t ms_parse_time()
344
{
345
  int64_t ret= 0;
346
  char unit= optarg[strlen(optarg) - 1];
347
348
  optarg[strlen(optarg) - 1]= '\0';
349
  ret= atoi(optarg);
350
351
  switch (unit)
352
  {
353
  case 'd':
354
  case 'D':
355
    ret*= 24;
356
357
  case 'h':
358
  case 'H':
359
    ret*= 60;
360
361
  case 'm':
362
  case 'M':
363
    ret*= 60;
364
365
  case 's':
366
  case 'S':
367
    break;
368
369
  default:
370
    ret= -1;
371
    break;
372
  } /* switch */
373
374
  return ret;
375
} /* ms_parse_time */
376
377
378
/* used to parse the size string */
379
static int64_t ms_parse_size()
380
{
381
  int64_t ret= -1;
382
  char unit= optarg[strlen(optarg) - 1];
383
384
  optarg[strlen(optarg) - 1]= '\0';
385
  ret= strtoll(optarg, (char **)NULL, 10);
386
387
  switch (unit)
388
  {
389
  case 'k':
390
  case 'K':
391
    ret*= 1024;
392
    break;
393
394
  case 'm':
395
  case 'M':
396
    ret*= 1024 * 1024;
397
    break;
398
399
  case 'g':
400
  case 'G':
401
    ret*= 1024 * 1024 * 1024;
402
    break;
403
404
  default:
405
    ret= -1;
406
    break;
407
  } /* switch */
408
409
  return ret;
410
} /* ms_parse_size */
411
412
413
/* used to parse the options of command line */
414
static void ms_options_parse(int argc, char *argv[])
415
{
416
  int option_index= 0;
417
  int option_rv;
418
419
  while ((option_rv= getopt_long(argc, argv, "VhURbaBs:x:T:c:X:v:d:"
420
                                             "t:S:F:w:e:o:n:P:p:",
421
                                 long_options, &option_index)) != -1)
422
  {
423
    switch (option_rv)
424
    {
425
    case 0:
426
      break;
427
428
    case OPT_VERSION:     /* --version or -V */
429
      ms_version_command(PROGRAM_NAME);
430
      break;
431
432
    case OPT_HELP:     /* --help or -h */
433
      ms_help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION);
434
      break;
435
436
    case OPT_SERVERS:     /* --servers or -s */
437
      ms_setting.srv_str= strdup(optarg);
438
      break;
439
440
    case OPT_CONCURRENCY:       /* --concurrency or -c */
441
      ms_setting.nconns= (uint32_t)strtoul(optarg, (char **) NULL, 10);
442
      if (ms_setting.nconns <= 0)
443
      {
444
        fprintf(stderr, "Concurrency must be greater than 0.:-)\n");
445
        exit(1);
446
      }
447
      break;
448
449
    case OPT_EXECUTE_NUMBER:        /* --execute_number or -x */
450
      ms_setting.exec_num= (int)strtol(optarg, (char **) NULL, 10);
451
      if (ms_setting.exec_num <= 0)
452
      {
453
        fprintf(stderr, "Execute number must be greater than 0.:-)\n");
454
        exit(1);
455
      }
456
      break;
457
458
    case OPT_THREAD_NUMBER:     /* --threads or -T */
459
      ms_setting.nthreads= (uint32_t)strtoul(optarg, (char **) NULL, 10);
460
      if (ms_setting.nthreads <= 0)
461
      {
462
        fprintf(stderr, "Threads number must be greater than 0.:-)\n");
463
        exit(1);
464
      }
465
      break;
466
467
    case OPT_FIXED_LTH:         /* --fixed_size or -X */
468
      ms_setting.fixed_value_size= (size_t)strtoull(optarg, (char **) NULL, 10);
469
      if ((ms_setting.fixed_value_size <= 0)
470
          || (ms_setting.fixed_value_size > MAX_VALUE_SIZE))
471
      {
472
        fprintf(stderr, "Value size must be between 0 and 1M.:-)\n");
473
        exit(1);
474
      }
475
      break;
476
477
    case OPT_VERIFY:        /* --verify or -v */
478
      ms_setting.verify_percent= atof(optarg);
479
      if ((ms_setting.verify_percent <= 0)
480
          || (ms_setting.verify_percent > 1.0))
481
      {
482
        fprintf(stderr, "Data verification rate must be "
483
                        "greater than 0 and less than 1.0. :-)\n");
484
        exit(1);
485
      }
486
      break;
487
488
    case OPT_GETS_DIVISION:         /* --division or -d */
489
      ms_setting.mult_key_num= (int)strtol(optarg, (char **) NULL, 10);
490
      if (ms_setting.mult_key_num <= 0)
491
      {
492
        fprintf(stderr, "Multi-get key number must be greater than 0.:-)\n");
493
        exit(1);
494
      }
495
      break;
496
497
    case OPT_TIME:      /* --time or -t */
498
      ms_setting.run_time= (int)ms_parse_time();
499
      if (ms_setting.run_time == -1)
500
      {
501
        fprintf(stderr, "Please specify the run time. :-)\n"
502
                        "'s' for second, 'm' for minute, 'h' for hour, "
503
                        "'d' for day. e.g.: --time=24h (means 24 hours).\n");
504
        exit(1);
505
      }
506
507
      if (ms_setting.run_time == 0)
508
      {
509
        fprintf(stderr, "Running time can not be 0. :-)\n");
510
        exit(1);
511
      }
512
      break;
513
514
    case OPT_CONFIG_CMD:        /* --cfg_cmd or -F */
515
      ms_setting.cfg_file= strdup(optarg);
516
      break;
517
518
    case OPT_WINDOW_SIZE:       /* --win_size or -w */
519
      ms_setting.win_size= (size_t)ms_parse_size();
520
      if (ms_setting.win_size == (size_t)-1)
521
      {
522
        fprintf(
523
          stderr,
524
          "Please specify the item window size. :-)\n"
525
          "e.g.: --win_size=10k (means 10k task window size).\n");
526
        exit(1);
527
      }
528
      break;
529
530
    case OPT_UDP:       /* --udp or -U*/
531
      ms_setting.udp= true;
532
      break;
533
534
    case OPT_EXPIRE:        /* --exp_verify or -e */
535
      ms_setting.exp_ver_per= atof(optarg);
536
      if ((ms_setting.exp_ver_per <= 0) || (ms_setting.exp_ver_per > 1.0))
537
      {
538
        fprintf(stderr, "Expire time verification rate must be "
539
                        "greater than 0 and less than 1.0. :-)\n");
540
        exit(1);
541
      }
542
      break;
543
544
    case OPT_OVERWRITE:         /* --overwrite or -o */
545
      ms_setting.overwrite_percent= atof(optarg);
546
      if ((ms_setting.overwrite_percent <= 0)
547
          || (ms_setting.overwrite_percent > 1.0))
548
      {
549
        fprintf(stderr, "Objects overwrite rate must be "
550
                        "greater than 0 and less than 1.0. :-)\n");
551
        exit(1);
552
      }
553
      break;
554
555
    case OPT_STAT_FREQ:         /* --stat_freq or -S */
556
      ms_setting.stat_freq= (int)ms_parse_time();
557
      if (ms_setting.stat_freq == -1)
558
      {
559
        fprintf(stderr, "Please specify the frequency of dumping "
560
                        "statistic information. :-)\n"
561
                        "'s' for second, 'm' for minute, 'h' for hour, "
562
                        "'d' for day. e.g.: --time=24h (means 24 hours).\n");
563
        exit(1);
564
      }
565
566
      if (ms_setting.stat_freq == 0)
567
      {
568
        fprintf(stderr, "The frequency of dumping statistic information "
569
                        "can not be 0. :-)\n");
570
        exit(1);
571
      }
572
      break;
573
574
    case OPT_SOCK_PER_CONN:         /* --conn_sock or -n */
575
      ms_setting.sock_per_conn= (uint32_t)strtoul(optarg, (char **) NULL, 10);
576
      if (ms_setting.sock_per_conn <= 0)
577
      {
578
        fprintf(stderr, "Number of socks of each concurrency "
579
                        "must be greater than 0.:-)\n");
580
        exit(1);
581
      }
582
      break;
583
584
    case OPT_RECONNECT:     /* --reconnect or -R */
585
      ms_setting.reconnect= true;
586
      break;
587
588
    case OPT_VERBOSE:       /* --verbose or -b */
589
      ms_setting.verbose= true;
590
      break;
591
592
    case OPT_FACEBOOK_TEST:         /* --facebook or -a */
593
      ms_setting.facebook_test= true;
594
      break;
595
596
    case OPT_BINARY_PROTOCOL:       /* --binary or -B */
1049.1.10 by Brian Aker
cppcheck warnings fixed.
597
      ms_setting.binary_prot_= true;
929.1.32 by Brian Aker
Reverting back to older version of memslap, and renaming other version
598
      break;
599
600
    case OPT_TPS:       /* --tps or -P */
601
      ms_setting.expected_tps= (int)ms_parse_size();
602
      if (ms_setting.expected_tps == -1)
603
      {
604
        fprintf(stderr,
605
                "Please specify the item expected throughput. :-)\n"
606
                "e.g.: --tps=10k (means 10k throughput).\n");
607
        exit(1);
608
      }
609
      break;
610
611
    case OPT_REP_WRITE_SRV:         /* --rep_write or -p */
612
      ms_setting.rep_write_srv= (uint32_t)strtoul(optarg, (char **) NULL, 10);
613
      if (ms_setting.rep_write_srv <= 0)
614
      {
615
        fprintf(stderr,
616
                "Number of replication writing server must be greater "
617
                "than 0.:-)\n");
618
        exit(1);
619
      }
620
      break;
621
622
    case '?':
623
      /* getopt_long already printed an error message. */
624
      exit(1);
625
626
    default:
627
      abort();
628
    } /* switch */
629
  }
630
} /* ms_options_parse */
631
632
633
static int ms_check_para()
634
{
635
  if (ms_setting.srv_str == NULL)
636
  {
637
    char *temp;
638
639
    if ((temp= getenv("MEMCACHED_SERVERS")))
640
    {
641
      ms_setting.srv_str= strdup(temp);
642
    }
643
    else
644
    {
645
      fprintf(stderr, "No Servers provided\n\n");
646
      return -1;
647
    }
648
  }
649
650
  if (ms_setting.nconns % (uint32_t)ms_setting.nthreads != 0)
651
  {
652
    fprintf(stderr, "Concurrency must be the multiples of threads count.\n");
653
    return -1;
654
  }
655
656
  if (ms_setting.win_size % UNIT_ITEMS_COUNT != 0)
657
  {
658
    fprintf(stderr, "Window size must be the multiples of 1024.\n\n");
659
    return -1;
660
  }
661
662
  return EXIT_SUCCESS;
663
} /* ms_check_para */
664
665
666
/* initialize the statistic structure */
667
static void ms_statistic_init()
668
{
669
  pthread_mutex_init(&ms_statistic.stat_mutex, NULL);
670
  ms_init_stats(&ms_statistic.get_stat, "Get");
671
  ms_init_stats(&ms_statistic.set_stat, "Set");
672
  ms_init_stats(&ms_statistic.total_stat, "Total");
673
} /* ms_statistic_init */
674
675
676
/* initialize the global state structure */
677
static void ms_stats_init()
678
{
679
  memset(&ms_stats, 0, sizeof(ms_stats_t));
680
  if (ms_setting.stat_freq > 0)
681
  {
682
    ms_statistic_init();
683
  }
684
} /* ms_stats_init */
685
686
687
/* use to output the statistic */
688
static void ms_print_statistics(int in_time)
689
{
690
  int obj_size= (int)(ms_setting.avg_key_size + ms_setting.avg_val_size);
691
692
  printf("\033[1;1H\033[2J\n");
693
  ms_dump_format_stats(&ms_statistic.get_stat, in_time,
694
                       ms_setting.stat_freq, obj_size);
695
  ms_dump_format_stats(&ms_statistic.set_stat, in_time,
696
                       ms_setting.stat_freq, obj_size);
697
  ms_dump_format_stats(&ms_statistic.total_stat, in_time,
698
                       ms_setting.stat_freq, obj_size);
699
} /* ms_print_statistics */
700
701
702
/* used to print the states of memslap */
703
static void ms_print_memslap_stats(struct timeval *start_time,
704
                                   struct timeval *end_time)
705
{
706
  char buf[1024];
707
  char *pos= buf;
708
709
  pos+= snprintf(pos,
710
                 sizeof(buf), "cmd_get: %lu\n",
711
                 (unsigned long) ms_stats.cmd_get);
712
  pos+= snprintf(pos,
713
                 sizeof(buf) - (size_t)(pos -buf),
714
                 "cmd_set: %lu\n",
715
                 (unsigned long) ms_stats.cmd_set);
716
  pos+= snprintf(pos,
717
                 sizeof(buf) - (size_t)(pos -buf),
718
                 "get_misses: %lu\n",
719
                 (unsigned long) ms_stats.get_misses);
720
721
  if (ms_setting.verify_percent > 0)
722
  {
723
    pos+= snprintf(pos,
724
                   sizeof(buf) - (size_t)(pos -buf),
725
                   "verify_misses: %lu\n",
726
                   (unsigned long) ms_stats.vef_miss);
727
    pos+= snprintf(pos,
728
                   sizeof(buf) - (size_t)(pos -buf),
729
                   "verify_failed: %lu\n",
730
                   (unsigned long) ms_stats.vef_failed);
731
  }
732
733
  if (ms_setting.exp_ver_per > 0)
734
  {
735
    pos+= snprintf(pos,
736
                   sizeof(buf) - (size_t)(pos -buf),
737
                   "expired_get: %lu\n",
738
                   (unsigned long) ms_stats.exp_get);
739
    pos+= snprintf(pos,
740
                   sizeof(buf) - (size_t)(pos -buf),
741
                   "unexpired_unget: %lu\n",
742
                   (unsigned long) ms_stats.unexp_unget);
743
  }
744
745
  pos+= snprintf(pos,
746
                 sizeof(buf) - (size_t)(pos -buf),
747
                 "written_bytes: %lu\n",
748
                 (unsigned long) ms_stats.bytes_written);
749
  pos+= snprintf(pos,
750
                 sizeof(buf) - (size_t)(pos -buf),
751
                 "read_bytes: %lu\n",
752
                 (unsigned long) ms_stats.bytes_read);
753
  pos+= snprintf(pos,
754
                 sizeof(buf) - (size_t)(pos -buf),
755
                 "object_bytes: %lu\n",
756
                 (unsigned long) ms_stats.obj_bytes);
757
758
  if (ms_setting.udp || ms_setting.facebook_test)
759
  {
760
    pos+= snprintf(pos,
761
                   sizeof(buf) - (size_t)(pos -buf),
762
                   "packet_disorder: %lu\n",
763
                   (unsigned long) ms_stats.pkt_disorder);
764
    pos+= snprintf(pos,
765
                   sizeof(buf) - (size_t)(pos -buf),
766
                   "packet_drop: %lu\n",
767
                   (unsigned long)ms_stats.pkt_drop);
768
    pos+= snprintf(pos,
769
                   sizeof(buf) - (size_t)(pos -buf),
770
                   "udp_timeout: %lu\n",
771
                   (unsigned long)ms_stats.udp_timeout);
772
  }
773
774
  if (ms_setting.stat_freq > 0)
775
  {
776
    ms_dump_stats(&ms_statistic.get_stat);
777
    ms_dump_stats(&ms_statistic.set_stat);
778
    ms_dump_stats(&ms_statistic.total_stat);
779
  }
780
781
  int64_t time_diff= ms_time_diff(start_time, end_time);
782
  pos+= snprintf(pos,
783
                 sizeof(buf) - (size_t)(pos -buf),
784
                 "\nRun time: %.1fs Ops: %llu TPS: %.0Lf Net_rate: %.1fM/s\n",
785
                 (double)time_diff / 1000000,
786
                 (unsigned long long)(ms_stats.cmd_get + ms_stats.cmd_set),
787
                 (ms_stats.cmd_get
788
                  + ms_stats.cmd_set) / ((long double)time_diff / 1000000),
789
                 (double)(
790
                          ms_stats.bytes_written
791
                          + ms_stats.bytes_read) / 1024 / 1024
792
                 / ((double)time_diff / 1000000));
793
  assert(pos <= buf);
794
795
  fprintf(stdout, "%s", buf);
796
  fflush(stdout);
797
} /* ms_print_memslap_stats */
798
799
800
/* the loop of the main thread, wait the work threads to complete */
801
static void ms_monitor_slap_mode()
802
{
803
  struct timeval start_time, end_time;
804
805
  /* Wait all the threads complete initialization. */
806
  pthread_mutex_lock(&ms_global.init_lock.lock);
807
  while (ms_global.init_lock.count < ms_setting.nthreads)
808
  {
809
    pthread_cond_wait(&ms_global.init_lock.cond,
810
                      &ms_global.init_lock.lock);
811
  }
812
  pthread_mutex_unlock(&ms_global.init_lock.lock);
813
814
  /* only when there is no set operation it need warm up */
815
  if (ms_setting.cmd_distr[CMD_SET].cmd_prop < PROP_ERROR)
816
  {
817
    /* Wait all the connects complete warm up. */
818
    pthread_mutex_lock(&ms_global.warmup_lock.lock);
819
    while (ms_global.warmup_lock.count < ms_setting.nconns)
820
    {
821
      pthread_cond_wait(&ms_global.warmup_lock.cond, &ms_global.warmup_lock.lock);
822
    }
823
    pthread_mutex_unlock(&ms_global.warmup_lock.lock);
824
  }
825
  ms_global.finish_warmup= true;
826
827
  /* running in "run time" mode, user specify run time */
828
  if (ms_setting.run_time > 0)
829
  {
1049.1.10 by Brian Aker
cppcheck warnings fixed.
830
    int second= 0;
929.1.32 by Brian Aker
Reverting back to older version of memslap, and renaming other version
831
    gettimeofday(&start_time, NULL);
832
    while (1)
833
    {
834
      sleep(1);
835
      second++;
836
837
      if ((ms_setting.stat_freq > 0) && (second % ms_setting.stat_freq == 0)
838
          && (ms_stats.active_conns >= ms_setting.nconns)
839
          && (ms_stats.active_conns <= INT_MAX))
840
      {
841
        ms_print_statistics(second);
842
      }
843
844
      if (ms_setting.run_time <= second)
845
      {
846
        ms_global.time_out= true;
847
        break;
848
      }
849
850
      /* all connections disconnect */
851
      if ((second > 5) && (ms_stats.active_conns == 0))
852
      {
853
        break;
854
      }
855
    }
856
    gettimeofday(&end_time, NULL);
857
    sleep(1);       /* wait all threads clean up */
858
  }
859
  else
860
  {
861
    /* running in "execute number" mode, user specify execute number */
862
    gettimeofday(&start_time, NULL);
863
864
    /*
865
     * We loop until we know that all connects have cleaned up.
866
     */
867
    pthread_mutex_lock(&ms_global.run_lock.lock);
868
    while (ms_global.run_lock.count < ms_setting.nconns)
869
    {
870
      pthread_cond_wait(&ms_global.run_lock.cond, &ms_global.run_lock.lock);
871
    }
872
    pthread_mutex_unlock(&ms_global.run_lock.lock);
873
874
    gettimeofday(&end_time, NULL);
875
  }
876
877
  ms_print_memslap_stats(&start_time, &end_time);
878
} /* ms_monitor_slap_mode */
879
880
881
/* the main function */
882
int main(int argc, char *argv[])
883
{
884
  srandom((unsigned int)time(NULL));
885
  ms_global_struct_init();
886
887
  /* initialization */
888
  ms_setting_init_pre();
889
  ms_options_parse(argc, argv);
890
  if (ms_check_para())
891
  {
892
    ms_help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION);
893
    exit(1);
894
  }
895
  ms_setting_init_post();
896
  ms_stats_init();
897
  ms_thread_init();
898
899
  /* waiting work thread complete its task */
900
  ms_monitor_slap_mode();
901
902
  /* clean up */
903
  ms_thread_cleanup();
904
  ms_global_struct_destroy();
905
  ms_setting_cleanup();
906
907
  return EXIT_SUCCESS;
908
} /* main */