diff options
author | David Teigland <teigland@redhat.com> | 2011-07-13 13:43:04 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2011-07-13 13:43:04 -0500 |
commit | 9b1d3e4ec0870b8ae4f7671ff135b29534179099 (patch) | |
tree | a24af29c4018bab6cedab6532b81bde574313896 /dlm | |
parent | eaba84e44dbac2eaefcbbcbd1c70cbfcd0c41b6a (diff) | |
download | dct-stuff-9b1d3e4ec0870b8ae4f7671ff135b29534179099.tar.gz dct-stuff-9b1d3e4ec0870b8ae4f7671ff135b29534179099.tar.xz dct-stuff-9b1d3e4ec0870b8ae4f7671ff135b29534179099.zip |
dlm_seq: add new test
measure time to:
acquire locks on resources 1-N
convert the locks (with -c)
unlock the locks (with -u)
Signed-off-by: David Teigland <teigland@redhat.com>
Diffstat (limited to 'dlm')
-rw-r--r-- | dlm/dlm_seq.c | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/dlm/dlm_seq.c b/dlm/dlm_seq.c new file mode 100644 index 0000000..02991ad --- /dev/null +++ b/dlm/dlm_seq.c @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2011 David Teigland + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License V2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would 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. + */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <stddef.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <time.h> +#include <signal.h> +#include <syslog.h> +#include <sys/time.h> +#include <asm/types.h> +#include <sys/socket.h> +#include <sys/poll.h> +#include <sys/un.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/errno.h> + +#include "libdlm.h" + +#define DEFAULT_NUM_R 1000 +#define DEFAULT_NUM_LPR 1 + +static dlm_lshandle_t *dh; +static int openclose = 0; +static int quiet = 0; +static int verbose = 0; +static int opt_convert = 0; +static int opt_unlock = 0; +static unsigned int num_r = DEFAULT_NUM_R; +static unsigned int num_lpr = DEFAULT_NUM_LPR; +static uint32_t *lkids; + +#define log_debug(fmt, args...) \ +do { \ + if (!quiet) \ + printf(fmt "\n", ##args); \ +} while (0) + +#define log_error(fmt, args...) \ +do { \ + printf("ERROR " fmt "\n", ##args); \ + exit(-1); \ +} while (0) + +static int rand_int(int a, int b) +{ + return a + (int) (((float)(b - a + 1)) * random() / (RAND_MAX+1.0)); +} + +static uint64_t dt_usec(struct timeval *start, struct timeval *stop) +{ + uint64_t dt; + + dt = stop->tv_sec - start->tv_sec; + dt *= 1000000; + dt += stop->tv_usec - start->tv_usec; + return dt; +} + +static void do_seq(int acquire, int convert, int unlock) +{ + struct dlm_lksb lksb; + char name[DLM_RESNAME_MAXLEN]; + struct timeval last, start, now; + uint32_t r_count = 0; + uint32_t lkid; + int i, j, rv; + + gettimeofday(&last, NULL); + start = last; + + for (i = 0; i < num_r; i++) { + snprintf(name, sizeof(name), "seq%08d", i); + + for (j = 0; j < num_lpr; j++) { + memset(&lksb, 0, sizeof(lksb)); + + if (acquire) { + rv = dlm_ls_lock_wait(dh, LKM_PRMODE, &lksb, 0, + name, strlen(name), + 0, NULL, NULL, NULL); + } + if (convert) { + lksb.sb_lkid = lkids[(i * num_lpr) + j]; + + rv = dlm_ls_lock_wait(dh, LKM_NLMODE, &lksb, + LKF_CONVERT, + name, strlen(name), + 0, NULL, NULL, NULL); + } + if (unlock) { + lkid = lkids[(i * num_lpr) + j]; + + rv = dlm_ls_unlock_wait(dh, lkid, 0, &lksb); + } + + if (rv) { + log_error("dlm op %d %d %d %d,%d error %d", + acquire, convert, unlock, i, j, rv); + return; + } + + if (acquire && lkids) + lkids[(i * num_lpr) + j] = lksb.sb_lkid; + } + r_count++; + + if (quiet) + continue; + + if (verbose || !(r_count % 1000)) { + gettimeofday(&now, NULL); + + printf("%08u: %08llu %08llu us%s%s\n", + r_count, + (unsigned long long)dt_usec(&last, &now), + (unsigned long long)dt_usec(&start, &now), + convert ? " convert" : "", + unlock ? " unlock" : ""); + + last = now; + } + } + + if (verbose || !(r_count % 1000)) + return; + + gettimeofday(&now, NULL); + + printf("%08u: %08llu %08llu us%s\n", + r_count, + (unsigned long long)dt_usec(&last, &now), + (unsigned long long)dt_usec(&start, &now), + convert ? " convert" : "", + unlock ? " unlock" : ""); +} + +static void print_usage(void) +{ + printf("dlm_seq [options]\n"); + printf("Options:\n"); + printf("\n"); + printf(" -r The number of resources, default %d\n", DEFAULT_NUM_R); + printf(" -l The number of locks per resource, default %d\n", DEFAULT_NUM_LPR); + printf(" -c Convert all locks after acquiring them all\n"); + printf(" -u Unlock all locks before exiting\n"); + printf(" -o Open/close existing lockspace\n"); + printf(" -v Verbose output\n"); + printf(" -q Quiet output\n"); +} + +static void decode_arguments(int argc, char **argv) +{ + int cont = 1; + int optchar; + + while (cont) { + optchar = getopt(argc, argv, "r:l:cuvqoh"); + + switch (optchar) { + + case 'r': + num_r = atoi(optarg); + break; + + case 'l': + num_lpr = atoi(optarg); + break; + + case 'c': + opt_convert = 1; + break; + + case 'u': + opt_unlock = 1; + break; + + case 'o': + openclose = 1; + break; + + case 'v': + verbose = 1; + break; + + case 'q': + quiet = 1; + break; + + case 'h': + print_usage(); + exit(EXIT_SUCCESS); + break; + + case 'V': + printf("%s (built %s %s)\n", argv[0], __DATE__, __TIME__); + exit(EXIT_SUCCESS); + break; + + case ':': + case '?': + fprintf(stderr, "Please use '-h' for usage.\n"); + exit(EXIT_FAILURE); + break; + + case EOF: + cont = 0; + break; + + default: + fprintf(stderr, "unknown option: %c\n", optchar); + exit(EXIT_FAILURE); + break; + }; + } +} + +int main(int argc, char *argv[]) +{ + int i, rv, quit = 0; + + decode_arguments(argc, argv); + + printf("%d resources, %d locks per resource\n", num_r, num_lpr); + + if (openclose) { + log_debug("dlm_open_lockspace..."); + + dh = dlm_open_lockspace("dlm_seq"); + if (!dh) { + log_error("dlm_open_lockspace error %lu %d", + (unsigned long)dh, errno); + return -ENOTCONN; + } + } else { + log_debug("dlm_new_lockspace..."); + + dh = dlm_new_lockspace("dlm_seq", 0600, 0); + if (!dh) { + log_error("dlm_new_lockspace error %lu %d", + (unsigned long)dh, errno); + return -ENOTCONN; + } + } + + rv = dlm_ls_pthread_init(dh); + if (rv < 0) { + log_error("dlm_ls_pthread_init error %d %d", rv, errno); + goto done; + } + + if (opt_convert || opt_unlock) { + lkids = malloc(sizeof(uint32_t) * (num_r * num_lpr)); + if (!lkids) { + log_error("no mem"); + goto done; + } + } + + do_seq(1, 0, 0); + + if (opt_convert) + do_seq(0, 1, 0); + + if (opt_unlock) + do_seq(0, 0, 1); + + if (lkids) + free(lkids); + done: + if (openclose) { + log_debug("dlm_close_lockspace"); + + rv = dlm_close_lockspace(dh); + if (rv < 0) + log_error("dlm_close_lockspace error %d %d", + rv, errno); + } else { + log_debug("dlm_release_lockspace"); + + rv = dlm_release_lockspace("dlm_seq", dh, 1); + if (rv < 0) + log_error("dlm_release_lockspace error %d %d", + rv, errno); + } + + return 0; +} + |