1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
4  *                         University Research and Technology
5  *                         Corporation.  All rights reserved.
6  * Copyright (c) 2004-2007 The University of Tennessee and The University
7  *                         of Tennessee Research Foundation.  All rights
8  *                         reserved.
9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
10  *                         University of Stuttgart.  All rights reserved.
11  * Copyright (c) 2004-2005 The Regents of the University of California.
12  *                         All rights reserved.
13  * Copyright (c) 2006      University of Houston. All rights reserved.
14  * Copyright (c) 2007-2015 Cisco Systems, Inc.  All rights reserved.
15  * Copyright (c) 2015      Los Alamos National Security, LLC.  All rights
16  *                         reserved.
17  * $COPYRIGHT$
18  *
19  * Additional copyrights may follow
20  *
21  * $HEADER$
22  */
23 /** @file **/
24 
25 #ifndef OMPI_MPI_ERRCODE_H
26 #define OMPI_MPI_ERRCODE_H
27 
28 #include "ompi_config.h"
29 
30 #include "mpi.h"
31 #include "opal/class/opal_object.h"
32 #include "opal/class/opal_pointer_array.h"
33 
34 BEGIN_C_DECLS
35 
36 /**
37  * Back-end type for MPI error codes.
38  * Please note:
39  *   if code == MPI_UNDEFINED, than the according structure
40  *                             represents an error class.
41  *   For the predefined error codes and classes, code and
42  *   cls are both set to the according value.
43  */
44 struct ompi_mpi_errcode_t {
45     opal_object_t                      super;
46     int                                 code;
47     int                                  cls;
48     char     errstring[MPI_MAX_ERROR_STRING];
49 };
50 typedef struct ompi_mpi_errcode_t ompi_mpi_errcode_t;
51 
52 OMPI_DECLSPEC extern opal_pointer_array_t ompi_mpi_errcodes;
53 OMPI_DECLSPEC extern int ompi_mpi_errcode_lastused;
54 OMPI_DECLSPEC extern int ompi_mpi_errcode_lastpredefined;
55 
56 OMPI_DECLSPEC extern ompi_mpi_errcode_t ompi_err_unknown;
57 
58 /**
59  * Check for a valid error code
60  */
ompi_mpi_errcode_is_invalid(int errcode)61 static inline bool ompi_mpi_errcode_is_invalid(int errcode)
62 {
63     if ( errcode >= 0 && errcode <= ompi_mpi_errcode_lastused )
64         return 0;
65     else
66         return 1;
67 }
68 
69 /**
70  * Return the error class
71  */
ompi_mpi_errcode_get_class(int errcode)72 static inline int ompi_mpi_errcode_get_class (int errcode)
73 {
74     ompi_mpi_errcode_t *err = NULL;
75 
76     if (errcode >= 0) {
77         err = (ompi_mpi_errcode_t *)opal_pointer_array_get_item(&ompi_mpi_errcodes, errcode);
78         /* If we get a bogus errcode, return MPI_ERR_UNKNOWN */
79     }
80 
81     if (NULL != err) {
82 	if ( err->code != MPI_UNDEFINED ) {
83 	    return err->cls;
84 	}
85     }
86     return ompi_err_unknown.cls;
87 }
88 
ompi_mpi_errcode_is_predefined(int errcode)89 static inline int ompi_mpi_errcode_is_predefined ( int errcode )
90 {
91     if ( errcode >= 0 && errcode <= ompi_mpi_errcode_lastpredefined )
92 	return true;
93 
94     return false;
95 }
96 
ompi_mpi_errnum_is_class(int errnum)97 static inline int ompi_mpi_errnum_is_class ( int errnum )
98 {
99     ompi_mpi_errcode_t *err;
100 
101     if (errnum < 0) {
102         return false;
103     }
104 
105     if ( errnum <= ompi_mpi_errcode_lastpredefined ) {
106 	/* Predefined error values represent an error code and
107 	   an error class at the same time */
108 	return true;
109     }
110 
111     err = (ompi_mpi_errcode_t *)opal_pointer_array_get_item(&ompi_mpi_errcodes, errnum);
112     if (NULL != err) {
113 	if ( MPI_UNDEFINED == err->code) {
114 	    /* Distinction between error class and error code is that for the
115 	       first one the code section is set to MPI_UNDEFINED  */
116 	    return true;
117 	}
118     }
119 
120     return false;
121 }
122 
123 
124 /**
125  * Return the error string
126  */
ompi_mpi_errnum_get_string(int errnum)127 static inline char* ompi_mpi_errnum_get_string (int errnum)
128 {
129     ompi_mpi_errcode_t *err = NULL;
130 
131     if (errnum >= 0) {
132         err = (ompi_mpi_errcode_t *)opal_pointer_array_get_item(&ompi_mpi_errcodes, errnum);
133         /* If we get a bogus errcode, return a string indicating that this
134            truly should not happen */
135     }
136 
137     if (NULL != err) {
138         return err->errstring;
139     } else {
140         return "Unknown error (this should not happen!)";
141     }
142 }
143 
144 
145 /**
146  * Initialize the error codes
147  *
148  * @returns OMPI_SUCCESS Upon success
149  * @returns OMPI_ERROR Otherwise
150  *
151  * Invoked from ompi_mpi_init(); sets up all static MPI error codes,
152  */
153 int ompi_mpi_errcode_init(void);
154 
155 /**
156  * Finalize the error codes.
157  *
158  * @returns OMPI_SUCCESS Always
159  *
160  * Invokes from ompi_mpi_finalize(); tears down the error code array.
161  */
162 int ompi_mpi_errcode_finalize(void);
163 
164 /**
165  * Add an error code
166  *
167  * @param: error class to which this new error code belongs to
168  *
169  * @returns the new error code on SUCCESS (>0)
170  * @returns OMPI_ERROR otherwise
171  *
172  */
173 int ompi_mpi_errcode_add (int errclass);
174 
175 /**
176  * Add an error class
177  *
178  * @param: none
179  *
180  * @returns the new error class on SUCCESS (>0)
181  * @returns OMPI_ERROR otherwise
182  *
183  */
184 int ompi_mpi_errclass_add (void);
185 
186 /**
187  * Add an error string to an error code
188  *
189  * @param: error code for which the string is defined
190  * @param: error string to add
191  * @param: length of the string
192  *
193  * @returns OMPI_SUCCESS on success
194  * @returns OMPI_ERROR on error
195  */
196 int ompi_mpi_errnum_add_string (int errnum, const char* string, int len);
197 
198 END_C_DECLS
199 
200 #endif /* OMPI_MPI_ERRCODE_H */
201