diff options
Diffstat (limited to 'qa/src/multithread3.c')
-rw-r--r-- | qa/src/multithread3.c | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/qa/src/multithread3.c b/qa/src/multithread3.c new file mode 100644 index 0000000..c31ee57 --- /dev/null +++ b/qa/src/multithread3.c @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2011 Ken McDonell. All Rights Reserved. + * + * exercise multi-threaded support for local PMNS functions + */ + +#include <stdio.h> +#include <stdlib.h> +#include <pcp/pmapi.h> +#include <pcp/impl.h> +#include <pthread.h> + +#ifndef HAVE_PTHREAD_BARRIER_T +#include "pthread_barrier.h" +#endif + +static pthread_barrier_t barrier; + +static char *pmnsfile; +static char pmns[] = "#undef EXTRA\n\ +root {\n\ + a\n\ + b 1:0:0\n\ + c 2:0:0\n\ +#ifdef EXTRA\n\ + d\n\ + e 4:0:0\n\ +#endif\n\ +}\n\ +a {\n\ + one 0:0:0\n\ + two 0:1:0\n\ + three\n\ +}\n\ +a.three {\n\ + foo 0:2:0\n\ + bar 0:2:1\n\ +}\n\ +#ifdef EXTRA\n\ +d {\n\ + mumble 3:0:0\n\ + f\n\ +}\n\ +d.f {\n\ + fumble 3:0:1\n\ +}\n\ +#endif\n\ +"; + + +static void * +func1(void *arg) +{ + int sts; + char *fn = "func1"; + char **offspring; + int *status; + int i; + int j; + char *namelist[] = { "b", "a.three.foo", "d.f.fumble" }; + pmID pmidlist[3]; + + pthread_barrier_wait(&barrier); + + __pmDumpNameSpace(stdout, 1); + + sts = pmGetChildrenStatus("", &offspring, &status); + if (sts >= 0) { + printf("%s: pmGetChildrenStatus -> %d\n", fn, sts); + for (i = 0; i < sts; i++) { + printf("[%d] %s %s\n", i, offspring[i], status[i] == PMNS_LEAF_STATUS ? "leaf" : "non-leaf"); + } + free(offspring); + free(status); + } + else + printf("%s: pmGetChildrenStatus -> %s\n", fn, pmErrStr(sts)); + + for (i = 0; i < 5; i++) { + pthread_barrier_wait(&barrier); + sts = pmLookupName(sizeof(namelist)/sizeof(namelist[0]), namelist, pmidlist); + if (sts < 0) + printf("%s: pmGetChildrenStatus[%d] -> %s\n", fn, i, pmErrStr(sts)); + else { + for (j = 0; j < sizeof(namelist)/sizeof(namelist[0]); j++) { + printf("%s: [%d] %s -> %s", fn, i, namelist[j], pmIDStr(pmidlist[j])); + if (pmidlist[j] == PM_ID_NULL) + printf("\n"); + else { + char *name; + sts = pmNameID(pmidlist[j], &name); + if (sts < 0) + printf(": pmNameID -> %s\n", pmErrStr(sts)); + else { + printf(" -> %s\n", name); + free(name); + } + } + } + } + pthread_barrier_wait(&barrier); + } + + pthread_exit(NULL); +} + +static void * +func2(void *arg) +{ + int sts; + char *fn = "func2"; + char *p; + FILE *f; + + pthread_barrier_wait(&barrier); + + /* iter 0 */ + pthread_barrier_wait(&barrier); + pthread_barrier_wait(&barrier); + + /* iter 1 */ + pmUnloadNameSpace(); + pthread_barrier_wait(&barrier); + pthread_barrier_wait(&barrier); + + /* iter 2 */ + if ((sts = pmLoadNameSpace(pmnsfile)) < 0) { + printf("%s: pmLoadNameSpace: [reload] %s\n", fn, pmErrStr(sts)); + exit(1); + } + pthread_barrier_wait(&barrier); + pthread_barrier_wait(&barrier); + + /* iter 3 */ + pmUnloadNameSpace(); + for (p = pmns; *p; p++) { + if (*p == 'u') { + *p++ = 'd'; + *p++ = 'e'; + *p++ = 'f'; + *p++ = 'i'; + *p++ = 'n'; + *p++ = 'e'; + break; + } + } + if ((f = fopen(pmnsfile, "w")) == NULL) { + printf("fopen: %s: failed: %s\n", pmnsfile, pmErrStr(-oserror())); + exit(1); + } + if (fwrite(pmns, strlen(pmns), 1, f) != 1) { + printf("fwrite: %s: failed: %s\n", pmnsfile, pmErrStr(-oserror())); + exit(1); + } + fclose(f); + if ((sts = pmLoadNameSpace(pmnsfile)) < 0) { + printf("%s: pmLoadNameSpace: [extra reload] %s\n", fn, pmErrStr(sts)); + exit(1); + } + pthread_barrier_wait(&barrier); + pthread_barrier_wait(&barrier); + + /* iter 4 */ + pthread_barrier_wait(&barrier); + pthread_barrier_wait(&barrier); + + pthread_exit(NULL); +} + +int +main(int argc, char **argv) +{ + pthread_t tid1; + pthread_t tid2; + int sts; + char *msg; + FILE *f; + + if (argc != 2) { + printf("Usage: multithread3 tmpfile\n"); + exit(1); + } + pmnsfile = argv[1]; + if ((f = fopen(pmnsfile, "w")) == NULL) { + printf("fopen: %s: failed: %s\n", pmnsfile, pmErrStr(-oserror())); + exit(1); + } + if (fwrite(pmns, strlen(pmns), 1, f) != 1) { + printf("fwrite: %s: failed: %s\n", pmnsfile, pmErrStr(-oserror())); + exit(1); + } + fclose(f); + + sts = pthread_barrier_init(&barrier, NULL, 2); + if (sts != 0) { + printf("pthread_barrier_init: sts=%d\n", sts); + exit(1); + } + + if ((sts = pmLoadNameSpace(pmnsfile)) < 0) { + printf("pmLoadNameSpace: %s\n", pmErrStr(sts)); + exit(1); + } + + sts = pthread_create(&tid1, NULL, func1, NULL); + if (sts != 0) { + printf("thread_create: tid1: sts=%d\n", sts); + exit(1); + } + sts = pthread_create(&tid2, NULL, func2, NULL); + if (sts != 0) { + printf("thread_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); + + exit(0); +} |