diff options
Diffstat (limited to 'qa/src/multithread4.c')
-rw-r--r-- | qa/src/multithread4.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/qa/src/multithread4.c b/qa/src/multithread4.c new file mode 100644 index 0000000..110ba08 --- /dev/null +++ b/qa/src/multithread4.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2011 Ken McDonell. All Rights Reserved. + * + * exercise multi-threaded support for traverse and load/unload + * PMNS operations + */ + +#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 + +#define ITER 10 + +static int nmetric; + +void +dometric(const char *name) +{ + nmetric++; +} + +static void * +func1(void *arg) +{ + int sts; + int i; + char msgbuf[PM_MAXERRMSGLEN]; + + for (i = 0; i < ITER; i++) { + nmetric = 0; + sts = pmTraversePMNS("", dometric); + if (sts >= 0) + printf("traverse: found %d metrics, sts %d\n", nmetric, sts); + else { + /* + * expect 0 metrics and PM_ERR_NOPMNS if the pmTraversePMNS + * gets in between the pmUnloadPMNS and the pmLoadPMNS in the + * other thread + */ + if (nmetric > 0 || sts != PM_ERR_NOPMNS) + printf("traverse: found %d metrics, sts %s\n", nmetric, pmErrStr_r(sts, msgbuf, PM_MAXERRMSGLEN)); + else { + /* + * nmetric == 0 && sts == PM_ERR_NOPMNS, so try again ... + * won't loop forever because eventually func2() will + * finish + */ + i--; + } + } + } + + pthread_exit(NULL); +} + +static void * +func2(void *arg) +{ + int sts; + char *fn = "func2"; + int i; + char msgbuf[PM_MAXERRMSGLEN]; + + for (i = 0; i < ITER; i++) { + pmUnloadNameSpace(); + if ((sts = pmLoadNameSpace(PM_NS_DEFAULT)) < 0) { + printf("%s: pmLoadNameSpace[%d]: %s\n", fn, i, pmErrStr_r(sts, msgbuf, PM_MAXERRMSGLEN)); + exit(1); + } + } + + pthread_exit(NULL); +} + +int +main(int argc, char **argv) +{ + pthread_t tid1; + pthread_t tid2; + int sts; + char *msg; + unsigned int in[PDU_MAX+1]; + unsigned int out[PDU_MAX+1]; + int i; + char msgbuf[PM_MAXERRMSGLEN]; + + setvbuf(stdout, NULL, _IONBF, 0); + + if (argc != 1) { + printf("Usage: multithread4\n"); + exit(1); + } + + for (i = 0; i <= PDU_MAX; i++) { + in[i] = out[i] = 0; + } + __pmSetPDUCntBuf(in, out); + + if ((sts = pmLoadNameSpace(PM_NS_DEFAULT)) < 0) { + printf("%s: pmLoadNameSpace: %s\n", argv[0], pmErrStr_r(sts, msgbuf, PM_MAXERRMSGLEN)); + 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); + + printf("Total PDU counts\n"); + printf("in:"); + for (i = 0; i <= PDU_MAX; i++) + printf(" %d", in[i]); + putchar('\n'); + printf("out:"); + for (i = 0; i <= PDU_MAX; i++) + printf(" %d", out[i]); + putchar('\n'); + + exit(0); +} |