All of lore.kernel.org
 help / color / mirror / Atom feed
* [Cluster-devel] cluster/dlm/tests/usertest Makefile threads.c
@ 2007-02-01 11:11 pcaulfield
  0 siblings, 0 replies; only message in thread
From: pcaulfield @ 2007-02-01 11:11 UTC (permalink / raw)
  To: cluster-devel.redhat.com

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	pcaulfield at sourceware.org	2007-02-01 11:11:51

Modified files:
	dlm/tests/usertest: Makefile 
Added files:
	dlm/tests/usertest: threads.c 

Log message:
	Add threads example

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tests/usertest/threads.c.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tests/usertest/Makefile.diff?cvsroot=cluster&r1=1.9&r2=1.10

/cvs/cluster/cluster/dlm/tests/usertest/threads.c,v  -->  standard output
revision 1.1
--- cluster/dlm/tests/usertest/threads.c
+++ -	2007-02-01 11:11:51.819404000 +0000
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * Threaded DLM example
+ */
+
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/poll.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <limits.h>
+#include <unistd.h>
+#include <errno.h>
+#include <getopt.h>
+
+#include "libdlm.h"
+
+struct lock_wait {
+	pthread_cond_t cond;
+	pthread_mutex_t mutex;
+	struct dlm_lksb lksb;
+};
+
+struct thread_args
+{
+	dlm_lshandle_t *lockspace;
+	char *resource;
+	int flags;
+	int delay;
+	int mode;
+	int verbose;
+	int num;
+};
+
+static int modetonum(char *modestr)
+{
+    int mode = LKM_EXMODE;
+
+    if (strncasecmp(modestr, "NL", 2) == 0) mode = LKM_NLMODE;
+    if (strncasecmp(modestr, "CR", 2) == 0) mode = LKM_CRMODE;
+    if (strncasecmp(modestr, "CW", 2) == 0) mode = LKM_CWMODE;
+    if (strncasecmp(modestr, "PR", 2) == 0) mode = LKM_PRMODE;
+    if (strncasecmp(modestr, "PW", 2) == 0) mode = LKM_PWMODE;
+    if (strncasecmp(modestr, "EX", 2) == 0) mode = LKM_EXMODE;
+
+    return mode;
+}
+
+static char *numtomode(int mode)
+{
+    switch (mode)
+    {
+    case LKM_NLMODE: return "NL";
+    case LKM_CRMODE: return "CR";
+    case LKM_CWMODE: return "CW";
+    case LKM_PRMODE: return "PR";
+    case LKM_PWMODE: return "PW";
+    case LKM_EXMODE: return "EX";
+    default: return "??";
+    }
+}
+
+static void usage(char *prog, FILE *file)
+{
+    fprintf(file, "Usage:\n");
+    fprintf(file, "%s [mcnpquhV] <lockname>\n", prog);
+    fprintf(file, "\n");
+    fprintf(file, "   -V           show version of %s\n", prog);
+    fprintf(file, "   -h           show this help information\n");
+    fprintf(file, "   -m <mode>    lock mode (default EX)\n");
+    fprintf(file, "   -n           don't block\n");
+    fprintf(file, "   -t <threads> number of threads\n");
+    fprintf(file, "   -d <secs>    delay while holding lock\n");
+    fprintf(file, "   -l <name>    lockspace name\n");
+    fprintf(file, "   -v           verbose (up to 3)\n");
+    fprintf(file, "\n");
+
+}
+
+/* Simply wakes the thread that initiated the lock */
+static void sync_ast_routine(void *arg)
+{
+	struct lock_wait *lwait = arg;
+
+	pthread_mutex_lock(&lwait->mutex);
+	pthread_cond_signal(&lwait->cond);
+	pthread_mutex_unlock(&lwait->mutex);
+}
+
+/* Get/Convert a lock and wait for it to complete (or fail) */
+static int sync_lock(dlm_lshandle_t lockspace,
+		     const char *resource,
+		     int mode,
+		     int flags,
+		     int *lockid)
+{
+	int status;
+	struct lock_wait lwait;
+
+	if (!lockid) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	/* Conversions need the lockid in the LKSB */
+	if (flags & LKF_CONVERT)
+		lwait.lksb.sb_lkid = *lockid;
+
+	pthread_cond_init(&lwait.cond, NULL);
+	pthread_mutex_init(&lwait.mutex, NULL);
+	pthread_mutex_lock(&lwait.mutex);
+
+	status = dlm_ls_lock(lockspace,
+			     mode,
+			     &lwait.lksb,
+			     flags,
+			     resource,
+			     strlen(resource),
+			     0, sync_ast_routine, &lwait, NULL, NULL);
+	if (status)
+		return status;
+
+	/* Wait for it to complete */
+	pthread_cond_wait(&lwait.cond, &lwait.mutex);
+	pthread_mutex_unlock(&lwait.mutex);
+
+	*lockid = lwait.lksb.sb_lkid;
+
+	errno = lwait.lksb.sb_status;
+
+	if (lwait.lksb.sb_status)
+		return -1;
+	else
+		return 0;
+}
+
+/* Unlock - and wait for it to complete */
+static int sync_unlock(dlm_lshandle_t lockspace, int lockid)
+{
+	int status;
+	struct lock_wait lwait;
+
+	pthread_cond_init(&lwait.cond, NULL);
+	pthread_mutex_init(&lwait.mutex, NULL);
+	pthread_mutex_lock(&lwait.mutex);
+
+	status = dlm_ls_unlock(lockspace, lockid, 0, &lwait.lksb, &lwait);
+
+	if (status)
+		return status;
+
+	/* Wait for it to complete */
+	pthread_cond_wait(&lwait.cond, &lwait.mutex);
+	pthread_mutex_unlock(&lwait.mutex);
+
+	errno = lwait.lksb.sb_status;
+	if (lwait.lksb.sb_status != EUNLOCK)
+		return -1;
+	else
+		return 0;
+
+}
+
+static void *thread_fn(void *arg)
+{
+	struct thread_args *ta = arg;
+	int lockid;
+	int status;
+
+	if (ta->verbose > 1)
+		fprintf(stderr, "Locking in thread %d\n", pthread_self);
+
+	status = sync_lock(ta->lockspace, ta->resource,
+			   ta->mode, ta->flags, &lockid);
+
+	if (status)
+	{
+		if (ta->verbose)
+			fprintf(stderr, "Lock in thread %x failed: %s\n", pthread_self, strerror(errno));
+		return NULL;
+	}
+
+	sleep(ta->delay);
+
+	if (ta->verbose > 1)
+		fprintf(stderr, "Unlocking in thread %x\n", pthread_self());
+
+	status = sync_unlock(ta->lockspace,lockid);
+	if (status)
+	{
+		if (ta->verbose)
+			fprintf(stderr, "Unlock in thread %x failed: %s\n", pthread_self(), strerror(errno));
+	}
+
+	return NULL;
+}
+
+
+int main(int argc, char *argv[])
+{
+    char *resource = "LOCK-NAME";
+    char *lockspace_name = "threadtest";
+    dlm_lshandle_t *lockspace;
+    int  flags = 0;
+    int  num_threads = 5;
+    int  delay = 1;
+    int  mode;
+    int  verbose;
+    int  i;
+    signed char opt;
+    pthread_t *threads;
+    struct thread_args ta;
+
+    /* Deal with command-line arguments */
+    opterr = 0;
+    optind = 0;
+    while ((opt=getopt(argc,argv,"h?nt:d:l:m:vV")) != EOF)
+    {
+	switch(opt)
+	{
+	case 'h':
+	    usage(argv[0], stdout);
+	    exit(0);
+
+	case '?':
+	    usage(argv[0], stderr);
+	    exit(0);
+
+	case 'n':
+	    flags |= LKF_NOQUEUE;
+	    break;
+
+	case 't':
+            num_threads = atoi(optarg);
+	    break;
+
+	case 'm':
+            mode = modetonum(optarg);
+	    break;
+
+	case 'l':
+	    lockspace_name = strdup(optarg);
+	    break;
+
+	case 'd':
+            delay = atoi(optarg);
+	    break;
+
+	case 'v':
+	    verbose++;
+	    break;
+
+	case 'V':
+	    printf("\nthread example version 0.1\n\n");
+	    exit(1);
+	    break;
+	}
+    }
+
+    if (argv[optind])
+	resource = argv[optind];
+
+    if (verbose)
+	    fprintf(stderr, "Creating lockspace '%s'...", lockspace_name);
+
+    /* You need to be root to create the lockspace ... but not to use it */
+    lockspace = dlm_create_lockspace(lockspace_name, 0666);
+    if (!lockspace) {
+	    perror("Unable to create lockspace");
+	    return 1;
+    }
+    if (verbose)
+	    fprintf(stderr, "done\n");
+
+    dlm_ls_pthread_init(lockspace);
+
+    threads = malloc(sizeof(pthread_t) * num_threads);
+    if (!threads)
+    {
+	    perror("can't malloc threads array");
+	    return 2;
+    }
+
+    if (verbose)
+	    fprintf(stderr, "Starting threads\n");
+
+    ta.lockspace = lockspace;
+    ta.mode = mode;
+    ta.flags = flags;
+    ta.delay = delay;
+    ta.verbose = verbose;
+    ta.resource = resource;
+
+    for (i=0; i<num_threads; i++)
+    {
+	    if (verbose > 2)
+		    fprintf(stderr, "Starting thread %d\n", i);
+
+	    pthread_create(&threads[i], NULL, thread_fn, &ta);
+    }
+
+    if (verbose)
+	    fprintf(stderr, "All threads started\n");
+
+    for (i=0; i<num_threads; i++)
+    {
+	    void *status;
+	    if (verbose > 2)
+		    fprintf(stderr, "Waiting for thread %d\n", i);
+	    pthread_join(threads[i], &status);
+    }
+
+    return 0;
+}
+
--- cluster/dlm/tests/usertest/Makefile	2007/01/31 22:47:00	1.9
+++ cluster/dlm/tests/usertest/Makefile	2007/02/01 11:11:51	1.10
@@ -12,7 +12,7 @@
 top_srcdir = ../../..
 UNINSTALL=${top_srcdir}/scripts/uninstall.pl
 
-BINARIES=dlmtest asttest lstest pingtest lvb dlmtest2 flood alternate-lvb joinleave
+BINARIES=dlmtest asttest lstest pingtest lvb dlmtest2 flood alternate-lvb joinleave threads
 
 all: $(BINARIES)
 
@@ -53,5 +53,8 @@
 lvb: lvb.c	
 	$(CC) $(CFLAGS) -o $@ $< -ldlm -lpthread
 
+threads: threads.c	
+	$(CC) $(CFLAGS) -o $@ $< -ldlm -lpthread
+
 clean:
 	rm -f *.o $(BINARIES) *~ core



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-02-01 11:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-01 11:11 [Cluster-devel] cluster/dlm/tests/usertest Makefile threads.c pcaulfield

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.