1 /*
2  * Copyright (c) 2004-2010 The Trustees of Indiana University and Indiana
3  *                         University Research and Technology
4  *                         Corporation.  All rights reserved.
5  * Copyright (c) 2004-2011 The University of Tennessee and The University
6  *                         of Tennessee Research Foundation.  All rights
7  *                         reserved.
8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9  *                         University of Stuttgart.  All rights reserved.
10  * Copyright (c) 2004-2005 The Regents of the University of California.
11  *                         All rights reserved.
12  * Copyright (c) 2006-2013 Los Alamos National Security, LLC.
13  *                         All rights reserved.
14  * Copyright (c) 2009-2012 Cisco Systems, Inc.  All rights reserved.
15  * Copyright (c) 2011      Oak Ridge National Labs.  All rights reserved.
16  * Copyright (c) 2013-2019 Intel, Inc.  All rights reserved.
17  * Copyright (c) 2015      Mellanox Technologies, Inc.  All rights reserved.
18  * $COPYRIGHT$
19  *
20  * Additional copyrights may follow
21  *
22  * $HEADER$
23  *
24  */
25 
26 #include <src/include/pmix_config.h>
27 #include <pmix.h>
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <time.h>
33 
34 #include "src/class/pmix_object.h"
35 #include "src/util/argv.h"
36 #include "src/util/output.h"
37 #include "src/util/printf.h"
38 
39 static pmix_proc_t myproc;
40 static bool completed;
41 
notification_fn(size_t evhdlr_registration_id,pmix_status_t status,const pmix_proc_t * source,pmix_info_t info[],size_t ninfo,pmix_info_t results[],size_t nresults,pmix_event_notification_cbfunc_fn_t cbfunc,void * cbdata)42 static void notification_fn(size_t evhdlr_registration_id,
43                             pmix_status_t status,
44                             const pmix_proc_t *source,
45                             pmix_info_t info[], size_t ninfo,
46                             pmix_info_t results[], size_t nresults,
47                             pmix_event_notification_cbfunc_fn_t cbfunc,
48                             void *cbdata)
49 {
50     pmix_output(0, "Client %s:%d NOTIFIED with status %d", myproc.nspace, myproc.rank, status);
51     if (NULL != cbfunc) {
52         cbfunc(PMIX_SUCCESS, NULL, 0, NULL, NULL, cbdata);
53     }
54     completed = true;
55 }
56 
op_callbk(pmix_status_t status,void * cbdata)57 static void op_callbk(pmix_status_t status,
58                       void *cbdata)
59 {
60     pmix_output(0, "CLIENT: OP CALLBACK CALLED WITH STATUS %d", status);
61 }
62 
errhandler_reg_callbk(pmix_status_t status,size_t errhandler_ref,void * cbdata)63 static void errhandler_reg_callbk (pmix_status_t status,
64                                    size_t errhandler_ref,
65                                    void *cbdata)
66 {
67     pmix_output(0, "Client: ERRHANDLER REGISTRATION CALLBACK CALLED WITH STATUS %d, ref=%lu",
68                 status, (unsigned long)errhandler_ref);
69 }
70 
main(int argc,char ** argv)71 int main(int argc, char **argv)
72 {
73     int rc;
74     pmix_value_t value;
75     pmix_value_t *val = &value;
76     pmix_proc_t proc;
77     uint32_t nprocs;
78 
79     /* init us */
80     if (PMIX_SUCCESS != (rc = PMIx_Init(&myproc, NULL, 0))) {
81         pmix_output(0, "Client ns %s rank %d: PMIx_Init failed: %d", myproc.nspace, myproc.rank, rc);
82         exit(0);
83     }
84     pmix_output(0, "Client ns %s rank %d: Running", myproc.nspace, myproc.rank);
85 
86     /* get our job size */
87     (void)strncpy(proc.nspace, myproc.nspace, PMIX_MAX_NSLEN);
88     proc.rank = PMIX_RANK_WILDCARD;
89     if (PMIX_SUCCESS != (rc = PMIx_Get(&proc, PMIX_JOB_SIZE, NULL, 0, &val))) {
90         pmix_output(0, "Client ns %s rank %d: PMIx_Get job size failed: %s",
91                     myproc.nspace, myproc.rank, PMIx_Error_string(rc));
92         goto done;
93     }
94     nprocs = val->data.uint32;
95     PMIX_VALUE_RELEASE(val);
96     pmix_output(0, "Client %s:%d job size %d", myproc.nspace, myproc.rank, nprocs);
97     completed = false;
98 
99     /* register our errhandler */
100     PMIx_Register_event_handler(NULL, 0, NULL, 0,
101                                 notification_fn, errhandler_reg_callbk, NULL);
102 
103     /* call fence to sync */
104     PMIX_PROC_CONSTRUCT(&proc);
105     (void)strncpy(proc.nspace, myproc.nspace, PMIX_MAX_NSLEN);
106     proc.rank = PMIX_RANK_WILDCARD;
107     if (PMIX_SUCCESS != (rc = PMIx_Fence(&proc, 1, NULL, 0))) {
108         pmix_output(0, "Client ns %s rank %d: PMIx_Fence failed: %d", myproc.nspace, myproc.rank, rc);
109         goto done;
110     }
111 
112     /* rank=0 calls abort */
113     if (0 == myproc.rank) {
114         PMIx_Abort(PMIX_ERR_OUT_OF_RESOURCE, "Eat rocks",
115                    &proc, 1);
116         pmix_output(0, "Client ns %s rank %d: Abort called", myproc.nspace, myproc.rank);
117     } else {
118     /* everyone simply waits */
119         while (!completed) {
120             struct timespec ts;
121             ts.tv_sec = 0;
122             ts.tv_nsec = 100000;
123             nanosleep(&ts, NULL);
124         }
125     }
126 
127  done:
128     /* finalize us */
129     pmix_output(0, "Client ns %s rank %d: Finalizing", myproc.nspace, myproc.rank);
130     PMIx_Deregister_event_handler(1, op_callbk, NULL);
131 
132     if (PMIX_SUCCESS != (rc = PMIx_Finalize(NULL, 0))) {
133         fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize failed: %d\n", myproc.nspace, myproc.rank, rc);
134     } else {
135         fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize successfully completed\n", myproc.nspace, myproc.rank);
136     }
137     fflush(stderr);
138     return(0);
139 }
140