- add ability to run for multiple iterations - can also run non-threaded for comparison to threaded case
Signed-off-by: Dwight Engen <dwight.en...@oracle.com> --- Hi Guys, Serge I hope you don't mind I changed this to use getopt since there are a couple of things I'm using it for at the moment (ie. fixing up the fd leaks in the new cgroup code, patch for that will follow in a bit). Having it be able to do a couple iterations is handy for use with valgrind also. src/tests/concurrent.c | 148 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 116 insertions(+), 32 deletions(-) diff --git a/src/tests/concurrent.c b/src/tests/concurrent.c index 7cf86c4..85b423b 100644 --- a/src/tests/concurrent.c +++ b/src/tests/concurrent.c @@ -15,14 +15,46 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + +#include <limits.h> #include <stdio.h> #include <pthread.h> +#include <unistd.h> +#define _GNU_SOURCE +#include <getopt.h> #include "../lxc/lxccontainer.h" -#define NTHREADS 5 +static int nthreads = 5; +static int iterations = 1; +static int quiet = 0; +static int delay = 0; +static const char *template = "busybox"; + +static struct option options[] = { + { "threads", required_argument, NULL, 'j' }, + { "iterations", required_argument, NULL, 'i' }, + { "template", required_argument, NULL, 't' }, + { "delay", required_argument, NULL, 'd' }, + { "quiet", no_argument, NULL, 'q' }, + { "help", no_argument, NULL, '?' }, + { 0, 0, 0, 0 }, +}; -char *template = "busybox"; +static void usage(void) { + fprintf(stderr, "Usage: lxc-test-concurrent [OPTION]...\n\n" + "Common options :\n" + " -j, --threads=N Threads to run concurrently\n" + " (default: 5, use 1 for no threading)\n" + " -i, --iterations=N Number times to run the test (default: 1)\n" + " -t, --template=t Template to use (default: busybox)\n" + " -d, --delay=N Delay in seconds between start and stop\n" + " -q, --quiet Don't produce any output\n" + " -?, --help Give this help list\n" + "\n" + "Mandatory or optional arguments to long options are also mandatory or optional\n" + "for any corresponding short options.\n\n"); +} struct thread_args { int thread_id; @@ -30,16 +62,21 @@ struct thread_args { char *mode; }; -void * concurrent(void *arguments) { - char name[4]; +static void do_function(void *arguments) +{ + char name[NAME_MAX+1]; struct thread_args *args = arguments; struct lxc_container *c; - sprintf(name, "%d", args->thread_id); + sprintf(name, "lxc-test-concurrent-%d", args->thread_id); + args->return_code = 1; c = lxc_container_new(name, NULL); + if (!c) { + fprintf(stderr, "Unable to instantiate container (%s)\n", name); + return; + } - args->return_code = 1; if (strcmp(args->mode, "create") == 0) { if (!c->is_defined(c)) { if (!c->create(c, template, NULL, NULL, 1, NULL)) { @@ -58,6 +95,7 @@ void * concurrent(void *arguments) { fprintf(stderr, "Waiting the container (%s) to start failed...\n", name); goto out; } + sleep(delay); } } else if(strcmp(args->mode, "stop") == 0) { if (c->is_defined(c) && c->is_running(c)) { @@ -81,49 +119,95 @@ void * concurrent(void *arguments) { args->return_code = 0; out: lxc_container_put(c); - pthread_exit(NULL); } +static void *concurrent(void *arguments) +{ + do_function(arguments); + pthread_exit(NULL); +} int main(int argc, char *argv[]) { - int i, j; + int i, j, iter, opt; pthread_attr_t attr; - pthread_t threads[NTHREADS]; - struct thread_args args[NTHREADS]; + pthread_t *threads; + struct thread_args *args; char *modes[] = {"create", "start", "stop", "destroy", NULL}; - if (argc > 1) - template = argv[1]; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - for (i = 0; modes[i];i++) { - printf("Executing (%s) for %d containers...\n", modes[i], NTHREADS); - for (j = 0; j < NTHREADS; j++) { - args[j].thread_id = j; - args[j].mode = modes[i]; - - if (pthread_create(&threads[j], &attr, concurrent, (void *) &args[j]) != 0) { - perror("pthread_create() error"); - exit(EXIT_FAILURE); - } + while ((opt = getopt_long(argc, argv, "j:i:t:d:q", options, NULL)) != -1) { + switch(opt) { + case 'j': + nthreads = atoi(optarg); + break; + case 'i': + iterations = atoi(optarg); + break; + case 't': + template = optarg; + break; + case 'd': + delay = atoi(optarg); + break; + case 'q': + quiet = 1; + break; + default: /* '?' */ + usage(); + exit(EXIT_FAILURE); } + } + + threads = malloc(sizeof(*threads) * nthreads); + args = malloc(sizeof(*args) * nthreads); + if (threads == NULL || args == NULL) { + fprintf(stderr, "Unable malloc enough memory for %d threads\n", nthreads); + exit(EXIT_FAILURE); + } - for (j = 0; j < NTHREADS; j++) { - if ( pthread_join(threads[j], NULL) != 0) { - perror("pthread_join() error"); - exit(EXIT_FAILURE); + for (iter = 1; iter <= iterations; iter++) { + int fd; + fd = open("/", O_RDONLY); + if (!quiet) + printf("\nIteration %d/%d maxfd:%d\n", iter, iterations, fd); + close(fd); + + for (i = 0; modes[i];i++) { + if (!quiet) + printf("Executing (%s) for %d containers...\n", modes[i], nthreads); + for (j = 0; j < nthreads; j++) { + args[j].thread_id = j; + args[j].mode = modes[i]; + + if (nthreads > 1) { + if (pthread_create(&threads[j], &attr, concurrent, (void *) &args[j]) != 0) { + perror("pthread_create() error"); + exit(EXIT_FAILURE); + } + } else { + do_function(&args[j]); + } } - if (args[j].return_code) { - perror("thread returned an error"); - exit(EXIT_FAILURE); + + for (j = 0; j < nthreads; j++) { + if (nthreads > 1) { + if (pthread_join(threads[j], NULL) != 0) { + perror("pthread_join() error"); + exit(EXIT_FAILURE); + } + } + if (args[j].return_code) { + fprintf(stderr, "thread returned error %d", args[j].return_code); + exit(EXIT_FAILURE); + } } } - printf("\n"); } + free(args); + free(threads); pthread_attr_destroy(&attr); exit(EXIT_SUCCESS); } -- 1.8.1.4 ------------------------------------------------------------------------------ LIMITED TIME SALE - Full Year of Microsoft Training For Just $49.99! 1,500+ hours of tutorials including VisualStudio 2012, Windows 8, SharePoint 2013, SQL 2012, MVC 4, more. BEST VALUE: New Multi-Library Power Pack includes Mobile, Cloud, Java, and UX Design. Lowest price ever! Ends 9/20/13. http://pubads.g.doubleclick.net/gampad/clk?id=58041151&iu=/4140/ostg.clktrk _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel