summaryrefslogtreecommitdiff
path: root/qa/src/multithread1.c
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2014-10-26 12:33:50 +0400
committerIgor Pashev <pashev.igor@gmail.com>2014-10-26 12:33:50 +0400
commit47e6e7c84f008a53061e661f31ae96629bc694ef (patch)
tree648a07f3b5b9d67ce19b0fd72e8caa1175c98f1a /qa/src/multithread1.c
downloadpcp-debian/3.9.10.tar.gz
Debian 3.9.10debian/3.9.10debian
Diffstat (limited to 'qa/src/multithread1.c')
-rw-r--r--qa/src/multithread1.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/qa/src/multithread1.c b/qa/src/multithread1.c
new file mode 100644
index 0000000..c1fc355
--- /dev/null
+++ b/qa/src/multithread1.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * exercise multi-threaded checks for PM_CONTEXT_LOCAL
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pthread.h>
+#if darwin_hack
+#include <dlfcn.h>
+#endif
+
+#ifndef HAVE_PTHREAD_BARRIER_T
+#include "pthread_barrier.h"
+#endif
+
+static pthread_barrier_t barrier;
+
+static int ctx = -1;
+static char *namelist[] = { "sampledso.colour" };
+static pmID pmidlist[] = { 0 };
+static pmDesc desc;
+static char **instname;
+static int *instance;
+static pmResult *rp;
+
+static void
+func(void)
+{
+ int sts;
+ char **children;
+ char *p;
+
+ if ((sts = pmUseContext(ctx)) < 0) {
+ printf("pmUseContext(%d): %s\n", ctx, pmErrStr(sts));
+ pthread_exit(NULL);
+ }
+
+ /*
+ * expect this to fail for the second thread through when
+ * using PM_CONTEXT_LOCAL
+ */
+ if ((sts = pmDupContext()) < 0)
+ printf("pmDupContext: %s\n", pmErrStr(sts));
+ else
+ printf("pmDupContext: -> %d\n", sts);
+
+ if ((sts = pmUseContext(ctx)) < 0) {
+ printf("pmUseContext(%d): %s\n", ctx, pmErrStr(sts));
+ pthread_exit(NULL);
+ }
+ else
+ printf("pmUseContext(%d) -> %d\n", ctx, sts);
+
+ if ((sts = pmLookupName(1, namelist, pmidlist)) < 0)
+ printf("pmLookupName: %s\n", pmErrStr(sts));
+ else
+ printf("pmLookupName: -> %s\n", pmIDStr(pmidlist[0]));
+
+ pthread_barrier_wait(&barrier);
+
+ if (pmidlist[0] == 0)
+ pthread_exit("Loser failed to get pmid!");
+
+ if ((sts = pmGetPMNSLocation()) < 0)
+ printf("pmGetPMNSLocation: %s\n", pmErrStr(sts));
+ else
+ printf("pmGetPMNSLocation: -> %d\n", sts);
+
+ /* leaf node, expect no children */
+ if ((sts = pmGetChildrenStatus(namelist[0], &children, NULL)) < 0)
+ printf("pmGetChildrenStatus: %s\n", pmErrStr(sts));
+ else
+ printf("pmGetChildrenStatus: -> %d\n", sts);
+
+ if ((sts = pmLookupDesc(pmidlist[0], &desc)) < 0)
+ printf("pmLookupDesc: %s\n", pmErrStr(sts));
+ else
+ printf("pmLookupDesc: -> %s type=%s indom=%s\n", pmIDStr(desc.pmid), pmTypeStr(desc.type), pmInDomStr(desc.indom));
+
+ pthread_barrier_wait(&barrier);
+
+ if (desc.pmid == 0)
+ pthread_exit("Loser failed to get pmDesc!");
+
+ if ((sts = pmLookupText(pmidlist[0], PM_TEXT_ONELINE, &p)) < 0)
+ printf("pmLookupText: %s\n", pmErrStr(sts));
+ else
+ printf("pmLookupText: -> %s\n", p);
+
+ if ((sts = pmGetInDom(desc.indom, &instance, &instname)) < 0)
+ printf("pmGetInDom: %s: %s\n", pmInDomStr(desc.indom), pmErrStr(sts));
+ else
+ printf("pmGetInDom: -> %d\n", sts);
+
+ pthread_barrier_wait(&barrier);
+
+ if (instance == NULL)
+ pthread_exit("Loser failed to get indom!");
+
+ if ((sts = pmNameInDom(desc.indom, instance[0], &p)) < 0)
+ printf("pmNameInDom: %s\n", pmErrStr(sts));
+ else
+ printf("pmNameInDom: %d -> %s\n", instance[0], p);
+
+ if ((sts = pmLookupInDom(desc.indom, instname[0])) < 0)
+ printf("pmLookupInDom: %s\n", pmErrStr(sts));
+ else
+ printf("pmLookupInDom: %s -> %d\n", instname[0], sts);
+
+ if ((sts = pmFetch(1, pmidlist, &rp)) < 0)
+ printf("pmFetch: %s\n", pmErrStr(sts));
+ else
+ printf("pmFetch: -> OK\n");
+
+ pthread_barrier_wait(&barrier);
+
+ if (rp == NULL)
+ pthread_exit("Loser failed to get pmResult!");
+
+ if ((sts = pmStore(rp)) < 0)
+ printf("pmStore: %s\n", pmErrStr(sts));
+ else
+ printf("pmStore: -> OK\n");
+
+ pthread_exit(NULL);
+}
+
+static void *
+func1(void *arg)
+{
+ int sts;
+
+ if ((sts = pmNewContext(PM_CONTEXT_LOCAL, NULL)) < 0)
+ printf("pmNewContext: %s\n", pmErrStr(sts));
+ else {
+ ctx = sts;
+ printf("pmNewContext: -> %d\n", ctx);
+ }
+
+ pthread_barrier_wait(&barrier);
+ pthread_barrier_wait(&barrier);
+
+ func();
+ /*NOTREACHED*/
+ return NULL;
+}
+
+static void *
+func2(void *arg)
+{
+ int sts;
+
+ pthread_barrier_wait(&barrier);
+
+ /*
+ * expect this to fail for the second thread through when
+ * using PM_CONTEXT_LOCAL
+ */
+ if ((sts = pmNewContext(PM_CONTEXT_LOCAL, NULL)) < 0)
+ printf("pmNewContext: %s\n", pmErrStr(sts));
+ else {
+ ctx = sts;
+ printf("pmNewContext: -> %d\n", ctx);
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ func();
+ /*NOTREACHED*/
+ return NULL;
+}
+
+int
+main()
+{
+ pthread_t tid1;
+ pthread_t tid2;
+ int sts;
+ char *msg;
+
+#if darwin_hack
+ /*
+ * This is just too bizarre!
+ * On Mac OS X, if one falls into the "CoreFoundation" libraries
+ * in a thread, without first having run the initialization code
+ * from the mainline, you die with a SIGTRAP! Calling dlopen() with
+ * doomed to fail parameters suffices.
+ *
+ * See also the -framework CoreFoundation glue needed in
+ * GNUmakefile.
+ *
+ * I am not making this up, check out
+ * http://openradar.appspot.com/7209349
+ */
+ dlopen("/no/such/dso", RTLD_LAZY);
+#endif
+
+ sts = pthread_barrier_init(&barrier, NULL, 2);
+ if (sts != 0) {
+ printf("pthread_barrier_init: sts=%d\n", sts);
+ exit(1);
+ }
+
+ sts = pthread_create(&tid1, NULL, func1, NULL);
+ if (sts != 0) {
+ printf("pthread_create: tid1: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid2, NULL, func2, NULL);
+ if (sts != 0) {
+ printf("pthread_create: tid2: sts=%d\n", sts);
+ exit(1);
+ }
+
+ pthread_join(tid1, (void *)&msg);
+ if (msg != NULL) printf("tid1: %s\n", msg);
+ pthread_join(tid2, (void *)&msg);
+ if (msg != NULL) printf("tid2: %s\n", msg);
+
+ if (rp != NULL)
+ pmFreeResult(rp);
+
+ exit(0);
+}