summaryrefslogtreecommitdiffstats
path: root/dlm
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2011-07-13 13:43:04 -0500
committerDavid Teigland <teigland@redhat.com>2011-07-13 13:43:04 -0500
commit9b1d3e4ec0870b8ae4f7671ff135b29534179099 (patch)
treea24af29c4018bab6cedab6532b81bde574313896 /dlm
parenteaba84e44dbac2eaefcbbcbd1c70cbfcd0c41b6a (diff)
downloaddct-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.c306
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;
+}
+