From b6bf3b8d6efb995d4ca7b91ff41709c57753d632 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 27 Feb 2009 10:23:45 -0800 Subject: CALLOC changed to calloc in rdd.c and several other cleanup and moved rdd.c into more appropriate "benchmarking" directory. Signed-off-by: Anand V. Avati --- configure.ac | 1 - extras/benchmarking/rdd.c | 492 ++++++++++++++++++++++++++++++++++++++++++++++ extras/test/Makefile.am | 3 - extras/test/rdd.c | 457 ------------------------------------------ 4 files changed, 492 insertions(+), 461 deletions(-) create mode 100644 extras/benchmarking/rdd.c delete mode 100644 extras/test/Makefile.am delete mode 100644 extras/test/rdd.c diff --git a/configure.ac b/configure.ac index 205a69c08b5..4d90307023f 100644 --- a/configure.ac +++ b/configure.ac @@ -127,7 +127,6 @@ AC_CONFIG_FILES([Makefile extras/init.d/Makefile extras/init.d/glusterfs-server.plist extras/benchmarking/Makefile - extras/test/Makefile glusterfs.spec]) AC_CANONICAL_HOST diff --git a/extras/benchmarking/rdd.c b/extras/benchmarking/rdd.c new file mode 100644 index 00000000000..d30660b5017 --- /dev/null +++ b/extras/benchmarking/rdd.c @@ -0,0 +1,492 @@ +/* + Copyright (c) 2008 Z RESEARCH, Inc. + This file is part of GlusterFS. + + GlusterFS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3 of the License, + or (at your option) any later version. + + GlusterFS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see + . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TWO_POWER(power) (2UL << (power)) + +#define RDD_INTEGER_VALUE ((TWO_POWER ((sizeof (int) * 8))) - 1) + +#ifndef UNIX_PATH_MAX +#define UNIX_PATH_MAX 108 +#endif + +struct rdd_file { + char path[UNIX_PATH_MAX]; + struct stat st; + int fd; +}; + +struct rdd_config { + long iters; + long max_ops_per_seq; + size_t max_bs; + size_t min_bs; + int thread_count; + pthread_t *threads; + pthread_barrier_t barrier; + pthread_mutex_t lock; + struct rdd_file in_file; + struct rdd_file out_file; +}; +static struct rdd_config rdd_config; + +enum rdd_keys { + RDD_MIN_BS_KEY = 1, + RDD_MAX_BS_KEY, +}; + +static error_t +rdd_parse_opts (int key, char *arg, + struct argp_state *_state) +{ + switch (key) { + case 'o': + { + int len = 0; + len = strlen (arg); + if (len > UNIX_PATH_MAX) { + fprintf (stderr, "output file name too long (%s)\n", + arg); + return -1; + } + + strncpy (rdd_config.out_file.path, arg, len); + } + break; + + case 'i': + { + int len = 0; + len = strlen (arg); + if (len > UNIX_PATH_MAX) { + fprintf (stderr, "input file name too long (%s)\n", + arg); + return -1; + } + + strncpy (rdd_config.in_file.path, arg, len); + } + break; + + case RDD_MIN_BS_KEY: + { + char *tmp = NULL; + long bs = 0; + bs = strtol (arg, &tmp, 10); + if ((bs == LONG_MAX) || (bs == LONG_MIN) || (tmp && *tmp)) { + fprintf (stderr, "invalid argument for minimum block" + "size (%s)\n", arg); + return -1; + } + + rdd_config.min_bs = bs; + } + break; + + case RDD_MAX_BS_KEY: + { + char *tmp = NULL; + long bs = 0; + bs = strtol (arg, &tmp, 10); + if ((bs == LONG_MAX) || (bs == LONG_MIN) || (tmp && *tmp)) { + fprintf (stderr, "invalid argument for maximum block" + "size (%s)\n", arg); + return -1; + } + + rdd_config.max_bs = bs; + } + break; + + case 'r': + { + char *tmp = NULL; + long iters = 0; + iters = strtol (arg, &tmp, 10); + if ((iters == LONG_MAX) || + (iters == LONG_MIN) || + (tmp && *tmp)) { + fprintf (stderr, "invalid argument for iterations" + "(%s)\n", arg); + return -1; + } + + rdd_config.iters = iters; + } + break; + + case 'm': + { + char *tmp = NULL; + long max_ops = 0; + max_ops = strtol (arg, &tmp, 10); + if ((max_ops == LONG_MAX) || + (max_ops == LONG_MIN) || + (tmp && *tmp)) { + fprintf (stderr, "invalid argument for max-ops" + "(%s)\n", arg); + return -1; + } + + rdd_config.max_ops_per_seq = max_ops; + } + break; + + case 't': + { + char *tmp = NULL; + long threads = 0; + threads = strtol (arg, &tmp, 10); + if ((threads == LONG_MAX) || + (threads == LONG_MIN) || + (tmp && *tmp)) { + fprintf (stderr, "invalid argument for thread count" + "(%s)\n", arg); + return -1; + } + + rdd_config.thread_count = threads; + } + break; + + case ARGP_KEY_NO_ARGS: + break; + case ARGP_KEY_ARG: + break; + case ARGP_KEY_END: + if (_state->argc == 1) { + argp_usage (_state); + } + + } + + return 0; +} + +static struct argp_option rdd_options[] = { + {"if", 'i', "INPUT_FILE", 0, "input-file"}, + {"of", 'o', "OUTPUT_FILE", 0, "output-file"}, + {"threads", 't', "COUNT", 0, "number of threads to spawn (defaults to 2)"}, + {"min-bs", RDD_MIN_BS_KEY, "MIN_BLOCK_SIZE", 0, + "Minimum block size in bytes (defaults to 1024)"}, + {"max-bs", RDD_MAX_BS_KEY, "MAX_BLOCK_SIZE", 0, + "Maximum block size in bytes (defaults to 4096)"}, + {"iters", 'r', "ITERS", 0, + "Number of read-write sequences (defaults to 1000000)"}, + {"max-ops", 'm', "MAXOPS", 0, + "maximum number of read-writes to be performed in a sequence (defaults to 1)"}, + {0, 0, 0, 0, 0} +}; + +static struct argp argp = { + rdd_options, + rdd_parse_opts, + "", + "random dd - tool to do a sequence of random block-sized continuous" + "read writes starting at a random offset" +}; + + +static void +rdd_default_config (void) +{ + rdd_config.thread_count = 2; + rdd_config.iters = 1000000; + rdd_config.max_bs = 4096; + rdd_config.min_bs = 1024; + rdd_config.in_file.fd = rdd_config.out_file.fd = -1; + rdd_config.max_ops_per_seq = 1; + + return; +} + + +static char +rdd_valid_config (void) +{ + char ret = 1; + int fd = -1; + + fd = open (rdd_config.in_file.path, O_RDONLY); + if (fd == -1) { + ret = 0; + goto out; + } + close (fd); + + if (rdd_config.min_bs > rdd_config.max_bs) { + ret = 0; + goto out; + } + + if (strlen (rdd_config.out_file.path) == 0) { + sprintf (rdd_config.out_file.path, "%s.rddout", + rdd_config.in_file.path); + } + +out: + return ret; +} + + +static void * +rdd_read_write (void *arg) +{ + int i = 0, ret = 0; + size_t bs = 0; + off_t offset = 0; + long rand = 0; + long max_ops = 0; + char *buf = NULL; + + buf = calloc (1, rdd_config.max_bs); + if (!buf) { + fprintf (stderr, "calloc failed (%s)\n", strerror (errno)); + ret = -1; + goto out; + } + + for (i = 0; i < rdd_config.iters; i++) + { + pthread_mutex_lock (&rdd_config.lock); + { + int bytes = 0; + rand = random (); + + if (rdd_config.min_bs == rdd_config.max_bs) { + bs = rdd_config.max_bs; + } else { + bs = rdd_config.min_bs + + (rand % + (rdd_config.max_bs - + rdd_config.min_bs)); + } + + offset = rand % rdd_config.in_file.st.st_size; + max_ops = rand % rdd_config.max_ops_per_seq; + if (!max_ops) { + max_ops ++; + } + + ret = lseek (rdd_config.in_file.fd, offset, SEEK_SET); + if (ret != offset) { + fprintf (stderr, "lseek failed (%s)\n", + strerror (errno)); + ret = -1; + goto unlock; + } + + ret = lseek (rdd_config.out_file.fd, offset, SEEK_SET); + if (ret != offset) { + fprintf (stderr, "lseek failed (%s)\n", + strerror (errno)); + ret = -1; + goto unlock; + } + + while (max_ops--) + { + bytes = read (rdd_config.in_file.fd, buf, bs); + if (!bytes) { + break; + } + + if (bytes == -1) { + fprintf (stderr, "read failed (%s)\n", + strerror (errno)); + ret = -1; + goto unlock; + } + + if (write (rdd_config.out_file.fd, buf, bytes) + != bytes) { + fprintf (stderr, "write failed (%s)\n", + strerror (errno)); + ret = -1; + goto unlock; + } + } + } + unlock: + pthread_mutex_unlock (&rdd_config.lock); + if (ret == -1) { + goto out; + } + ret = 0; + } +out: + free (buf); + pthread_barrier_wait (&rdd_config.barrier); + + return NULL; +} + + +static int +rdd_spawn_threads (void) +{ + int i = 0, ret = -1, fd = -1; + char buf[4096]; + + fd = open (rdd_config.in_file.path, O_RDONLY); + if (fd < 0) { + fprintf (stderr, "cannot open %s (%s)\n", + rdd_config.in_file.path, strerror (errno)); + ret = -1; + goto out; + } + ret = fstat (fd, &rdd_config.in_file.st); + if (ret != 0) { + close (fd); + fprintf (stderr, "cannot stat %s (%s)\n", + rdd_config.in_file.path, strerror (errno)); + ret = -1; + goto out; + } + rdd_config.in_file.fd = fd; + + fd = open (rdd_config.out_file.path, O_WRONLY | O_CREAT, + S_IRWXU | S_IROTH); + if (fd < 0) { + close (rdd_config.in_file.fd); + rdd_config.in_file.fd = -1; + fprintf (stderr, "cannot open %s (%s)\n", + rdd_config.out_file.path, strerror (errno)); + ret = -1; + goto out; + } + rdd_config.out_file.fd = fd; + + while ((ret = read (rdd_config.in_file.fd, buf, 4096)) > 0) { + if (write (rdd_config.out_file.fd, buf, ret) != ret) { + fprintf (stderr, "write failed (%s)\n", + strerror (errno)); + close (rdd_config.in_file.fd); + close (rdd_config.out_file.fd); + rdd_config.in_file.fd = rdd_config.out_file.fd = -1; + ret = -1; + goto out; + } + } + + rdd_config.threads = calloc (rdd_config.thread_count, + sizeof (pthread_t)); + if (rdd_config.threads == NULL) { + fprintf (stderr, "calloc() failed (%s)\n", strerror (errno)); + + ret = -1; + close (rdd_config.in_file.fd); + close (rdd_config.out_file.fd); + rdd_config.in_file.fd = rdd_config.out_file.fd = -1; + goto out; + } + + ret = pthread_barrier_init (&rdd_config.barrier, NULL, + rdd_config.thread_count + 1); + if (ret != 0) { + fprintf (stderr, "pthread_barrier_init() failed (%s)\n", + strerror (ret)); + + free (rdd_config.threads); + close (rdd_config.in_file.fd); + close (rdd_config.out_file.fd); + rdd_config.in_file.fd = rdd_config.out_file.fd = -1; + ret = -1; + goto out; + } + + ret = pthread_mutex_init (&rdd_config.lock, NULL); + if (ret != 0) { + fprintf (stderr, "pthread_mutex_init() failed (%s)\n", + strerror (ret)); + + free (rdd_config.threads); + pthread_barrier_destroy (&rdd_config.barrier); + close (rdd_config.in_file.fd); + close (rdd_config.out_file.fd); + rdd_config.in_file.fd = rdd_config.out_file.fd = -1; + ret = -1; + goto out; + } + + for (i = 0; i < rdd_config.thread_count; i++) + { + ret = pthread_create (&rdd_config.threads[i], NULL, + rdd_read_write, NULL); + if (ret != 0) { + fprintf (stderr, "pthread_create failed (%s)\n", + strerror (errno)); + exit (1); + } + } + +out: + return ret; +} + + +static void +rdd_wait_for_completion (void) +{ + pthread_barrier_wait (&rdd_config.barrier); +} + + +int +main (int argc, char *argv[]) +{ + int ret = -1; + + rdd_default_config (); + + ret = argp_parse (&argp, argc, argv, 0, 0, NULL); + if (ret != 0) { + ret = -1; + fprintf (stderr, "%s: argp_parse() failed\n", argv[0]); + goto err; + } + + if (!rdd_valid_config ()) { + ret = -1; + fprintf (stderr, "%s: configuration validation failed\n", + argv[0]); + goto err; + } + + ret = rdd_spawn_threads (); + if (ret != 0) { + fprintf (stderr, "%s: spawning threads failed\n", argv[0]); + goto err; + } + + rdd_wait_for_completion (); + +err: + return ret; +} diff --git a/extras/test/Makefile.am b/extras/test/Makefile.am deleted file mode 100644 index e6877054991..00000000000 --- a/extras/test/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -bin_PROGRAMS = rdd -rdd_SOURCES = rdd.c -AM_CFLAGS = -pthread diff --git a/extras/test/rdd.c b/extras/test/rdd.c deleted file mode 100644 index 2f2d6e6bb8e..00000000000 --- a/extras/test/rdd.c +++ /dev/null @@ -1,457 +0,0 @@ -/* - Copyright (c) 2008-2009 Z RESEARCH, Inc. - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - . -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TWO_POWER(power) (2UL << (power)) - -#define RDD_INTEGER_VALUE ((TWO_POWER ((sizeof (int) * 8))) - 1) - -#ifndef UNIX_PATH_MAX -#define UNIX_PATH_MAX 108 -#endif - -struct rdd_file { - char path[UNIX_PATH_MAX]; - struct stat st; - int fd; -}; - -struct rdd_config { - long iters; - long max_ops_per_seq; - size_t max_bs; - size_t min_bs; - int thread_count; - pthread_t *threads; - pthread_barrier_t barrier; - pthread_mutex_t lock; - struct rdd_file in_file; - struct rdd_file out_file; -}; -static struct rdd_config rdd_config; - -enum rdd_keys { - RDD_MIN_BS_KEY = 1, - RDD_MAX_BS_KEY, -}; - -static error_t -rdd_parse_opts (int key, char *arg, - struct argp_state *_state) -{ - switch (key) { - case 'o': - { - int len = 0; - len = strlen (arg); - if (len > UNIX_PATH_MAX) { - fprintf (stderr, "output file name too long (%s)\n", arg); - return -1; - } - - strncpy (rdd_config.out_file.path, arg, len); - } - break; - - case 'i': - { - int len = 0; - len = strlen (arg); - if (len > UNIX_PATH_MAX) { - fprintf (stderr, "input file name too long (%s)\n", arg); - return -1; - } - - strncpy (rdd_config.in_file.path, arg, len); - } - break; - - case RDD_MIN_BS_KEY: - { - char *tmp = NULL; - long bs = 0; - bs = strtol (arg, &tmp, 10); - if ((bs == LONG_MAX) || (bs == LONG_MIN) || (tmp && *tmp)) { - fprintf (stderr, "invalid argument for minimum block size (%s)\n", arg); - return -1; - } - - rdd_config.min_bs = bs; - } - break; - - case RDD_MAX_BS_KEY: - { - char *tmp = NULL; - long bs = 0; - bs = strtol (arg, &tmp, 10); - if ((bs == LONG_MAX) || (bs == LONG_MIN) || (tmp && *tmp)) { - fprintf (stderr, "invalid argument for maximum block size (%s)\n", arg); - return -1; - } - - rdd_config.max_bs = bs; - } - break; - - case 'r': - { - char *tmp = NULL; - long iters = 0; - iters = strtol (arg, &tmp, 10); - if ((iters == LONG_MAX) || (iters == LONG_MIN) || (tmp && *tmp)) { - fprintf (stderr, "invalid argument for iterations (%s)\n", arg); - return -1; - } - - rdd_config.iters = iters; - } - break; - - case 'm': - { - char *tmp = NULL; - long max_ops = 0; - max_ops = strtol (arg, &tmp, 10); - if ((max_ops == LONG_MAX) || (max_ops == LONG_MIN) || (tmp && *tmp)) { - fprintf (stderr, "invalid argument for max-ops (%s)\n", arg); - return -1; - } - - rdd_config.max_ops_per_seq = max_ops; - } - break; - - case 't': - { - char *tmp = NULL; - long threads = 0; - threads = strtol (arg, &tmp, 10); - if ((threads == LONG_MAX) || (threads == LONG_MIN) || (tmp && *tmp)) { - fprintf (stderr, "invalid argument for thread count (%s)\n", arg); - return -1; - } - - rdd_config.thread_count = threads; - } - break; - - case ARGP_KEY_NO_ARGS: - break; - case ARGP_KEY_ARG: - break; - case ARGP_KEY_END: - if (_state->argc == 1) { - argp_usage (_state); - } - - } - - return 0; -} - -static struct argp_option rdd_options[] = { - {"if", 'i', "INPUT_FILE", 0, "input-file"}, - {"of", 'o', "OUTPUT_FILE", 0, "output-file"}, - {"threads", 't', "COUNT", 0, "number of threads to spawn (defaults to 2)"}, - {"min-bs", RDD_MIN_BS_KEY, "MIN_BLOCK_SIZE", 0, - "Minimum block size in bytes (defaults to 1024)"}, - {"max-bs", RDD_MAX_BS_KEY, "MAX_BLOCK_SIZE", 0, - "Maximum block size in bytes (defaults to 4096)"}, - {"iters", 'r', "ITERS", 0, - "Number of read-write sequences (defaults to 1000000)"}, - {"max-ops", 'm', "MAXOPS", 0, - "maximum number of read-writes to be performed in a sequence (defaults to 1)"}, - {0, 0, 0, 0, 0} -}; - -static struct argp argp = { - rdd_options, - rdd_parse_opts, - "", - "random dd - tool to do a sequence of random block-sized continuous read writes starting at a random offset" -}; - - -static void -rdd_default_config (void) -{ - rdd_config.thread_count = 2; - rdd_config.iters = 1000000; - rdd_config.max_bs = 4096; - rdd_config.min_bs = 1024; - rdd_config.in_file.fd = rdd_config.out_file.fd = -1; - rdd_config.max_ops_per_seq = 1; - - return; -} - - -static char -rdd_valid_config (void) -{ - char ret = 1; - int fd = -1; - - fd = open (rdd_config.in_file.path, O_RDONLY); - if (fd == -1) { - ret = 0; - goto out; - } - close (fd); - - if (rdd_config.min_bs > rdd_config.max_bs) { - ret = 0; - goto out; - } - - if (strlen (rdd_config.out_file.path) == 0) { - sprintf (rdd_config.out_file.path, "%s.rddout", rdd_config.in_file.path); - } - -out: - return ret; -} - - -static void * -rdd_read_write (void *arg) -{ - int i = 0, ret = 0; - size_t bs = 0; - off_t offset = 0; - long rand = 0; - long max_ops = 0; - char *buf = NULL; - - buf = CALLOC (1, rdd_config.max_bs); - if (!buf) { - fprintf (stderr, "calloc failed (%s)\n", strerror (errno)); - ret = -1; - goto out; - } - - for (i = 0; i < rdd_config.iters; i++) - { - pthread_mutex_lock (&rdd_config.lock); - { - int bytes = 0; - rand = random (); - - if (rdd_config.min_bs == rdd_config.max_bs) { - bs = rdd_config.max_bs; - } else { - bs = rdd_config.min_bs + (rand % (rdd_config.max_bs - rdd_config.min_bs)); - } - - offset = rand % rdd_config.in_file.st.st_size; - max_ops = rand % rdd_config.max_ops_per_seq; - if (!max_ops) { - max_ops ++; - } - - ret = lseek (rdd_config.in_file.fd, offset, SEEK_SET); - if (ret != offset) { - fprintf (stderr, "lseek failed (%s)\n", strerror (errno)); - ret = -1; - goto unlock; - } - - ret = lseek (rdd_config.out_file.fd, offset, SEEK_SET); - if (ret != offset) { - fprintf (stderr, "lseek failed (%s)\n", strerror (errno)); - ret = -1; - goto unlock; - } - - while (max_ops--) - { - bytes = read (rdd_config.in_file.fd, buf, bs); - if (!bytes) { - break; - } - - if (bytes == -1) { - fprintf (stderr, "read failed (%s)\n", strerror (errno)); - ret = -1; - goto unlock; - } - - if (write (rdd_config.out_file.fd, buf, bytes) != bytes) { - fprintf (stderr, "write failed (%s)\n", strerror (errno)); - ret = -1; - goto unlock; - } - } - } - unlock: - pthread_mutex_unlock (&rdd_config.lock); - if (ret == -1) { - goto out; - } - ret = 0; - } -out: - free (buf); - pthread_barrier_wait (&rdd_config.barrier); - - return NULL; -} - - -static int -rdd_spawn_threads (void) -{ - int i = 0, ret = -1, fd = -1; - char buf[4096]; - - fd = open (rdd_config.in_file.path, O_RDONLY); - if (fd < 0) { - fprintf (stderr, "cannot open %s (%s)\n", rdd_config.in_file.path, strerror (errno)); - ret = -1; - goto out; - } - ret = fstat (fd, &rdd_config.in_file.st); - if (ret != 0) { - close (fd); - fprintf (stderr, "cannot stat %s (%s)\n", rdd_config.in_file.path, strerror (errno)); - ret = -1; - goto out; - } - rdd_config.in_file.fd = fd; - - fd = open (rdd_config.out_file.path, O_WRONLY | O_CREAT, S_IRWXU | S_IROTH); - if (fd < 0) { - close (rdd_config.in_file.fd); - rdd_config.in_file.fd = -1; - fprintf (stderr, "cannot open %s (%s)\n", rdd_config.out_file.path, strerror (errno)); - ret = -1; - goto out; - } - rdd_config.out_file.fd = fd; - - while ((ret = read (rdd_config.in_file.fd, buf, 4096)) > 0) { - if (write (rdd_config.out_file.fd, buf, ret) != ret) { - fprintf (stderr, "write failed (%s)\n", strerror (errno)); - close (rdd_config.in_file.fd); - close (rdd_config.out_file.fd); - rdd_config.in_file.fd = rdd_config.out_file.fd = -1; - ret = -1; - goto out; - } - } - - rdd_config.threads = CALLOC (rdd_config.thread_count, sizeof (pthread_t)); - if (rdd_config.threads == NULL) { - fprintf (stderr, "calloc() failed (%s)\n", strerror (errno)); - - ret = -1; - close (rdd_config.in_file.fd); - close (rdd_config.out_file.fd); - rdd_config.in_file.fd = rdd_config.out_file.fd = -1; - goto out; - } - - ret = pthread_barrier_init (&rdd_config.barrier, NULL, rdd_config.thread_count + 1); - if (ret != 0) { - fprintf (stderr, "pthread_barrier_init() failed (%s)\n", strerror (ret)); - - free (rdd_config.threads); - close (rdd_config.in_file.fd); - close (rdd_config.out_file.fd); - rdd_config.in_file.fd = rdd_config.out_file.fd = -1; - ret = -1; - goto out; - } - - ret = pthread_mutex_init (&rdd_config.lock, NULL); - if (ret != 0) { - fprintf (stderr, "pthread_mutex_init() failed (%s)\n", strerror (ret)); - - free (rdd_config.threads); - pthread_barrier_destroy (&rdd_config.barrier); - close (rdd_config.in_file.fd); - close (rdd_config.out_file.fd); - rdd_config.in_file.fd = rdd_config.out_file.fd = -1; - ret = -1; - goto out; - } - - for (i = 0; i < rdd_config.thread_count; i++) - { - ret = pthread_create (&rdd_config.threads[i], NULL, rdd_read_write, NULL); - if (ret != 0) { - fprintf (stderr, "pthread_create failed (%s)\n", strerror (errno)); - exit (1); - } - } - -out: - return ret; -} - - -static void -rdd_wait_for_completion (void) -{ - pthread_barrier_wait (&rdd_config.barrier); -} - - -int -main (int argc, char *argv[]) -{ - int ret = -1; - - rdd_default_config (); - - ret = argp_parse (&argp, argc, argv, 0, 0, NULL); - if (ret != 0) { - ret = -1; - fprintf (stderr, "%s: argp_parse() failed\n", argv[0]); - goto err; - } - - if (!rdd_valid_config ()) { - ret = -1; - fprintf (stderr, "%s: configuration validation failed\n", argv[0]); - goto err; - } - - ret = rdd_spawn_threads (); - if (ret != 0) { - fprintf (stderr, "%s: spawning threads failed\n", argv[0]); - goto err; - } - - rdd_wait_for_completion (); - -err: - return ret; -} -- cgit