qa: update 660 to generate index.html, fixing pcp-testsuite runs
[pcp.git] / qa / src / multithread1.c
blobc1fc355dbfe1008549cf329f1d12c64e84ea130f
1 /*
2 * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
4 * exercise multi-threaded checks for PM_CONTEXT_LOCAL
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <pcp/pmapi.h>
10 #include <pcp/impl.h>
11 #include <pthread.h>
12 #if darwin_hack
13 #include <dlfcn.h>
14 #endif
16 #ifndef HAVE_PTHREAD_BARRIER_T
17 #include "pthread_barrier.h"
18 #endif
20 static pthread_barrier_t barrier;
22 static int ctx = -1;
23 static char *namelist[] = { "sampledso.colour" };
24 static pmID pmidlist[] = { 0 };
25 static pmDesc desc;
26 static char **instname;
27 static int *instance;
28 static pmResult *rp;
30 static void
31 func(void)
33 int sts;
34 char **children;
35 char *p;
37 if ((sts = pmUseContext(ctx)) < 0) {
38 printf("pmUseContext(%d): %s\n", ctx, pmErrStr(sts));
39 pthread_exit(NULL);
43 * expect this to fail for the second thread through when
44 * using PM_CONTEXT_LOCAL
46 if ((sts = pmDupContext()) < 0)
47 printf("pmDupContext: %s\n", pmErrStr(sts));
48 else
49 printf("pmDupContext: -> %d\n", sts);
51 if ((sts = pmUseContext(ctx)) < 0) {
52 printf("pmUseContext(%d): %s\n", ctx, pmErrStr(sts));
53 pthread_exit(NULL);
55 else
56 printf("pmUseContext(%d) -> %d\n", ctx, sts);
58 if ((sts = pmLookupName(1, namelist, pmidlist)) < 0)
59 printf("pmLookupName: %s\n", pmErrStr(sts));
60 else
61 printf("pmLookupName: -> %s\n", pmIDStr(pmidlist[0]));
63 pthread_barrier_wait(&barrier);
65 if (pmidlist[0] == 0)
66 pthread_exit("Loser failed to get pmid!");
68 if ((sts = pmGetPMNSLocation()) < 0)
69 printf("pmGetPMNSLocation: %s\n", pmErrStr(sts));
70 else
71 printf("pmGetPMNSLocation: -> %d\n", sts);
73 /* leaf node, expect no children */
74 if ((sts = pmGetChildrenStatus(namelist[0], &children, NULL)) < 0)
75 printf("pmGetChildrenStatus: %s\n", pmErrStr(sts));
76 else
77 printf("pmGetChildrenStatus: -> %d\n", sts);
79 if ((sts = pmLookupDesc(pmidlist[0], &desc)) < 0)
80 printf("pmLookupDesc: %s\n", pmErrStr(sts));
81 else
82 printf("pmLookupDesc: -> %s type=%s indom=%s\n", pmIDStr(desc.pmid), pmTypeStr(desc.type), pmInDomStr(desc.indom));
84 pthread_barrier_wait(&barrier);
86 if (desc.pmid == 0)
87 pthread_exit("Loser failed to get pmDesc!");
89 if ((sts = pmLookupText(pmidlist[0], PM_TEXT_ONELINE, &p)) < 0)
90 printf("pmLookupText: %s\n", pmErrStr(sts));
91 else
92 printf("pmLookupText: -> %s\n", p);
94 if ((sts = pmGetInDom(desc.indom, &instance, &instname)) < 0)
95 printf("pmGetInDom: %s: %s\n", pmInDomStr(desc.indom), pmErrStr(sts));
96 else
97 printf("pmGetInDom: -> %d\n", sts);
99 pthread_barrier_wait(&barrier);
101 if (instance == NULL)
102 pthread_exit("Loser failed to get indom!");
104 if ((sts = pmNameInDom(desc.indom, instance[0], &p)) < 0)
105 printf("pmNameInDom: %s\n", pmErrStr(sts));
106 else
107 printf("pmNameInDom: %d -> %s\n", instance[0], p);
109 if ((sts = pmLookupInDom(desc.indom, instname[0])) < 0)
110 printf("pmLookupInDom: %s\n", pmErrStr(sts));
111 else
112 printf("pmLookupInDom: %s -> %d\n", instname[0], sts);
114 if ((sts = pmFetch(1, pmidlist, &rp)) < 0)
115 printf("pmFetch: %s\n", pmErrStr(sts));
116 else
117 printf("pmFetch: -> OK\n");
119 pthread_barrier_wait(&barrier);
121 if (rp == NULL)
122 pthread_exit("Loser failed to get pmResult!");
124 if ((sts = pmStore(rp)) < 0)
125 printf("pmStore: %s\n", pmErrStr(sts));
126 else
127 printf("pmStore: -> OK\n");
129 pthread_exit(NULL);
132 static void *
133 func1(void *arg)
135 int sts;
137 if ((sts = pmNewContext(PM_CONTEXT_LOCAL, NULL)) < 0)
138 printf("pmNewContext: %s\n", pmErrStr(sts));
139 else {
140 ctx = sts;
141 printf("pmNewContext: -> %d\n", ctx);
144 pthread_barrier_wait(&barrier);
145 pthread_barrier_wait(&barrier);
147 func();
148 /*NOTREACHED*/
149 return NULL;
152 static void *
153 func2(void *arg)
155 int sts;
157 pthread_barrier_wait(&barrier);
160 * expect this to fail for the second thread through when
161 * using PM_CONTEXT_LOCAL
163 if ((sts = pmNewContext(PM_CONTEXT_LOCAL, NULL)) < 0)
164 printf("pmNewContext: %s\n", pmErrStr(sts));
165 else {
166 ctx = sts;
167 printf("pmNewContext: -> %d\n", ctx);
170 pthread_barrier_wait(&barrier);
172 func();
173 /*NOTREACHED*/
174 return NULL;
178 main()
180 pthread_t tid1;
181 pthread_t tid2;
182 int sts;
183 char *msg;
185 #if darwin_hack
187 * This is just too bizarre!
188 * On Mac OS X, if one falls into the "CoreFoundation" libraries
189 * in a thread, without first having run the initialization code
190 * from the mainline, you die with a SIGTRAP! Calling dlopen() with
191 * doomed to fail parameters suffices.
193 * See also the -framework CoreFoundation glue needed in
194 * GNUmakefile.
196 * I am not making this up, check out
197 * http://openradar.appspot.com/7209349
199 dlopen("/no/such/dso", RTLD_LAZY);
200 #endif
202 sts = pthread_barrier_init(&barrier, NULL, 2);
203 if (sts != 0) {
204 printf("pthread_barrier_init: sts=%d\n", sts);
205 exit(1);
208 sts = pthread_create(&tid1, NULL, func1, NULL);
209 if (sts != 0) {
210 printf("pthread_create: tid1: sts=%d\n", sts);
211 exit(1);
213 sts = pthread_create(&tid2, NULL, func2, NULL);
214 if (sts != 0) {
215 printf("pthread_create: tid2: sts=%d\n", sts);
216 exit(1);
219 pthread_join(tid1, (void *)&msg);
220 if (msg != NULL) printf("tid1: %s\n", msg);
221 pthread_join(tid2, (void *)&msg);
222 if (msg != NULL) printf("tid2: %s\n", msg);
224 if (rp != NULL)
225 pmFreeResult(rp);
227 exit(0);