Quoting Dwight Engen (dwight.en...@oracle.com): > - 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>
Acked-by: Serge E. Hallyn <serge.hal...@ubuntu.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