[lxc-devel] [PATCH] add arguments with getopt to concurrent tester
Serge Hallyn
serge.hallyn at ubuntu.com
Mon Sep 16 21:40:48 UTC 2013
Quoting Dwight Engen (dwight.engen at 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.engen at oracle.com>
Acked-by: Serge E. Hallyn <serge.hallyn at 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
>
More information about the lxc-devel
mailing list