-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/errhan/dynerrutil.c
-: 0:Graph:dynerrutil.gcno
-: 0:Data:dynerrutil.gcda
-: 0:Runs:519
-: 0:Programs:142
-: 1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
-: 2:/*
-: 3: *
-: 4: * (C) 2001 by Argonne National Laboratory.
-: 5: * See COPYRIGHT in top-level directory.
-: 6: */
-: 7:
-: 8:#include "mpiimpl.h"
-: 9:#include "errcodes.h"
-: 10:
-: 11:#include <string.h>
-: 12:
-: 13:/*
-: 14: * This file contains the routines needed to implement the MPI routines that
-: 15: * can add error classes and codes during runtime. This file is organized
-: 16: * so that applications that do not use the MPI-2 routines to create new
-: 17: * error codes will not load any of this code.
-: 18: *
-: 19: * ROMIO has been customized to provide error messages with the same tools
-: 20: * as the rest of MPICH2 and will not rely on the dynamically assigned
-: 21: * error classes. This leaves all of the classes and codes for the user.
-: 22: *
-: 23: * Because we have customized ROMIO, we do not need to implement
-: 24: * instance-specific messages for the dynamic error codes.
-: 25: */
-: 26:
-: 27:/* Local data structures.
-: 28: A message may be associated with each class and code.
-: 29: Since we limit the number of user-defined classes and code (no more
-: 30: than 256 of each), we allocate an array of pointers to the messages here.
-: 31:
-: 32: We *could* allow 256 codes with each class. However, we don't expect
-: 33: any need for this many codes, so we simply allow 256 (actually
-: 34: ERROR_MAX_NCODE) codes, and distribute these among the error codes.
-: 35:
-: 36: A user-defined error code has the following format. The ERROR_xxx
-: 37: is the macro that may be used to extract the data (usually a MASK and
-: 38: a (right)shift)
-: 39:
-: 40: [0-6] Class (same as predefined error classes); ERROR_CLASS_MASK
-: 41: [7] Is dynamic; ERROR_DYN_MASK and ERROR_DYN_SHIFT
-: 42: [8-18] Code index (for messages); ERROR_GENERIC_MASK and ERROR_GENERIC_SHIFT
-: 43: [19-31] Zero (unused but defined as zero)
-: 44:*/
-: 45:
-: 46:static int not_initialized = 1; /* This allows us to use atomic decr */
-: 47:static const char *(user_class_msgs[ERROR_MAX_NCLASS]) = { 0 };
-: 48:static const char *(user_code_msgs[ERROR_MAX_NCODE]) = { 0 };
-: 49:static int first_free_class = 0;
-: 50:static int first_free_code = 1; /* code 0 is reserved */
-: 51:
-: 52:/* Forward reference */
-: 53:const char *MPIR_Err_get_dynerr_string( int code );
-: 54:
-: 55:/* This external allows this package to define the routine that converts
-: 56: dynamically assigned codes and classes to their corresponding strings.
-: 57: A cleaner implementation could replace this exposed global with a method
-: 58: defined in the error_string.c file that allowed this package to set
-: 59: the routine. */
-: 60:
-: 61:static int MPIR_Dynerrcodes_finalize( void * );
-: 62:
-: 63:/* Local routine to initialize the data structures for the dynamic
-: 64: error classes and codes.
-: 65:
-: 66: MPIR_Init_err_dyncodes is called if not_initialized is true.
-: 67: Because all of the routines in this file are called by the
-: 68: MPI_Add_error_xxx routines, and those routines use the SINGLE_CS
-: 69: when the implementation is multithreaded, these routines (until
-: 70: we implement finer-grain thread-synchronization) need not worry about
-: 71: multiple threads
-: 72: */
-: 73:static void MPIR_Init_err_dyncodes( void )
12: 74:{
-: 75: int i;
-: 76:
-: 77: /* FIXME: Does this need a thread-safe init? */
12: 78: not_initialized = 0;
-: 79:
1548: 80: for (i=0; i<ERROR_MAX_NCLASS; i++) {
1536: 81: user_class_msgs[i] = 0;
-: 82: }
98316: 83: for (i=0; i<ERROR_MAX_NCODE; i++) {
98304: 84: user_code_msgs[i] = 0;
-: 85: }
-: 86: /* Set the routine to provides access to the dynamically created
-: 87: error strings */
12: 88: MPIR_Process.errcode_to_string = MPIR_Err_get_dynerr_string;
-: 89:
-: 90: /* Add a finalize handler to free any allocated space */
12: 91: MPIR_Add_finalize( MPIR_Dynerrcodes_finalize, (void*)0, 9 );
12: 92:}
-: 93:
-: 94:/*
-: 95: MPIR_Err_set_msg - Change the message for an error code or class
-: 96:
-: 97: Input Parameter:
-: 98:+ code - Error code or class
-: 99:- msg - New message to use
-: 100:
-: 101: Notes:
-: 102: This routine is needed to implement 'MPI_Add_error_string'.
-: 103:*/
-: 104:int MPIR_Err_set_msg( int code, const char *msg_string )
187: 105:{
-: 106: int errcode, errclass;
-: 107: size_t msg_len;
-: 108: char *str;
-: 109: static const char FCNAME[] = "MPIR_Err_set_msg";
-: 110:
|
-: 111: /* --BEGIN ERROR HANDLING-- */
187: 112: if (not_initialized) {
-: 113: /* Just to keep the rest of the code more robust, we'll
-: 114: initialize the dynamic error codes *anyway*, but this is
-: 115: an error (see MPI_Add_error_string in the standard) */
#####: 116: MPIR_Init_err_dyncodes();
#####: 117: return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
-: 118: "MPIR_Err_set_msg", __LINE__,
-: 119: MPI_ERR_ARG, "**argerrcode",
-: 120: "**argerrcode %d", code );
-: 121: }
-: 122: /* --END ERROR HANDLING-- */
-: 123:
-: 124: /* Error strings are attached to a particular error code, not class.
-: 125: As a special case, if the code is 0, we use the class message */
|
187: 126: errclass = code & ERROR_CLASS_MASK;
187: 127: errcode = (code & ERROR_GENERIC_MASK) >> ERROR_GENERIC_SHIFT;
-: 128:
|
-: 129: /* --BEGIN ERROR HANDLING-- */
187: 130: if (code & ~(ERROR_CLASS_MASK | ERROR_DYN_MASK | ERROR_GENERIC_MASK)) {
-: 131: /* Check for invalid error code */
#####: 132: return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
-: 133: FCNAME, __LINE__,
-: 134: MPI_ERR_ARG, "**argerrcode",
-: 135: "**argerrcode %d", code );
-: 136: }
-: 137: /* --END ERROR HANDLING-- */
-: 138:
-: 139: /* --------------------------------------------------------------------- */
|
187: 140: msg_len = strlen( msg_string );
187: 141: str = (char *)MPIU_Malloc( msg_len + 1 );
|
-: 142: /* --BEGIN ERROR HANDLING-- */
187: 143: if (!str) {
#####: 144: return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
-: 145: FCNAME, __LINE__, MPI_ERR_OTHER,
-: 146: "**nomem", "**nomem %s %d",
-: 147: "error message string", msg_len );
-: 148: }
-: 149: /* --END ERROR HANDLING-- */
-: 150:
-: 151: /* --------------------------------------------------------------------- */
|
187: 152: MPIU_Strncpy( str, msg_string, msg_len + 1 );
187: 153: if (errcode) {
178: 154: if (errcode < first_free_code) {
178: 155: if (user_code_msgs[errcode]) {
|
#####: 156: MPIU_Free( (void*)(user_code_msgs[errcode]) );
-: 157: }
|
178: 158: user_code_msgs[errcode] = (const char *)str;
-: 159: }
-: 160: else {
-: 161: /* FIXME : Unallocated error code? */
|
#####: 162: MPIU_Free( str );
-: 163: }
-: 164: }
-: 165: else {
|
9: 166: if (errclass < first_free_class) {
9: 167: if (user_class_msgs[errclass]) {
|
#####: 168: MPIU_Free( (void*)(user_class_msgs[errclass]) );
-: 169: }
|
9: 170: user_class_msgs[errclass] = (const char *)str;
-: 171: }
-: 172: else {
-: 173: /* FIXME : Unallocated error code? */
|
#####: 174: MPIU_Free( str );
-: 175: }
-: 176: }
-: 177:
|
187: 178: return MPI_SUCCESS;
-: 179:}
-: 180:
-: 181:/*
-: 182: MPIR_Err_add_class - Creata a new error class
-: 183:
-: 184: Return value:
-: 185: An error class. Returns -1 if no more classes are available.
-: 186:
-: 187: Notes:
-: 188: This is used to implement 'MPI_Add_error_class'; it may also be used by a
-: 189: device to add device-specific error classes.
-: 190:
-: 191: Predefined classes are handled directly; this routine is not used to
-: 192: initialize the predefined MPI error classes. This is done to reduce the
-: 193: number of steps that must be executed when starting an MPI program.
-: 194:
-: 195: This routine should be run within a SINGLE_CS in the multithreaded case.
-: 196:*/
-: 197:int MPIR_Err_add_class(void)
45: 198:{
-: 199: int new_class;
-: 200:
45: 201: if (not_initialized)
12: 202: MPIR_Init_err_dyncodes();
-: 203:
-: 204: /* Get new class */
45: 205: MPIR_Fetch_and_increment( &first_free_class, &new_class );
-: 206:
|
-: 207: /* --BEGIN ERROR HANDLING-- */
45: 208: if (new_class >= ERROR_MAX_NCLASS) {
-: 209: /* Fail if out of classes */
#####: 210: return -1;
-: 211: }
-: 212: /* --END ERROR HANDLING-- */
-: 213:
-: 214: /* Note that the MPI interface always adds an error class without
-: 215: a string. */
|
45: 216: user_class_msgs[new_class] = 0;
-: 217:
45: 218: return (new_class | ERROR_DYN_MASK);
-: 219:}
-: 220:
-: 221:/*
-: 222: MPIR_Err_add_code - Create a new error code that is associated with an
-: 223: existing error class
-: 224:
-: 225: Input Parameters:
-: 226:. class - Error class to which the code belongs.
-: 227:
-: 228: Return value:
-: 229: An error code.
-: 230:
-: 231: Notes:
-: 232: This is used to implement 'MPI_Add_error_code'; it may also be used by a
-: 233: device to add device-specific error codes.
-: 234:
-: 235: */
-: 236:int MPIR_Err_add_code( int class )
178: 237:{
-: 238: int new_code;
-: 239:
-: 240: /* Note that we can add codes to existing classes, so we may
-: 241: need to initialize the dynamic error routines in this function */
178: 242: if (not_initialized)
|
#####: 243: MPIR_Init_err_dyncodes();
-: 244:
-: 245: /* Get the new code */
|
178: 246: MPIR_Fetch_and_increment( &first_free_code, &new_code );
|
-: 247: /* --BEGIN ERROR HANDLING-- */
178: 248: if (new_code >= ERROR_MAX_NCODE) {
-: 249: /* Fail if out of codes */
#####: 250: return -1;
-: 251: }
-: 252: /* --END ERROR HANDLING-- */
-: 253:
-: 254: /* Create the full error code */
|
178: 255: new_code = class | ERROR_DYN_MASK | (new_code << ERROR_GENERIC_SHIFT);
-: 256:
-: 257: /* FIXME: For robustness, we should make sure that the associated string
-: 258: is initialized to null */
178: 259: return new_code;
-: 260:}
-: 261:
-: 262:/*
-: 263: MPIR_Err_get_dynerr_string - Get the message string that corresponds to a
-: 264: dynamically created error class or code
-: 265:
-: 266: Input Parameter:
-: 267:+ code - An error class or code. If a code, it must have been created by
|
-: 268: 'MPIR_Err_create_code'.
-: 269:
-: 270: Return value:
-: 271: A pointer to a null-terminated text string with the corresponding error
-: 272: message. A null return indicates an error; usually the value of 'code' is
-: 273: neither a valid error class or code.
-: 274:
-: 275: Notes:
-: 276: This routine is used to implement 'MPI_ERROR_STRING'. It is only called
-: 277: for dynamic error codes.
-: 278: */
-: 279:const char *MPIR_Err_get_dynerr_string( int code )
|
199: 280:{
-: 281: int errcode, errclass;
199: 282: const char *errstr = 0;
-: 283:
-: 284: /* Error strings are attached to a particular error code, not class.
-: 285: As a special case, if the code is 0, we use the class message */
199: 286: errclass = code & ERROR_CLASS_MASK;
199: 287: errcode = (code & ERROR_GENERIC_MASK) >> ERROR_GENERIC_SHIFT;
-: 288:
199: 289: if (code & ~(ERROR_CLASS_MASK | ERROR_DYN_MASK | ERROR_GENERIC_MASK)) {
-: 290: /* Check for invalid error code */
|
#####: 291: return 0;
-: 292: }
-: 293:
|
199: 294: if (errcode) {
185: 295: if (errcode < first_free_code) {
185: 296: errstr = user_code_msgs[errcode];
-: 297: }
-: 298: }
-: 299: else {
14: 300: if (errclass < first_free_class) {
14: 301: errstr = user_class_msgs[errclass];
-: 302: }
-: 303: }
-: 304:
199: 305: return errstr;
-: 306:}
-: 307:
-: 308:
-: 309:static int MPIR_Dynerrcodes_finalize( void *p ATTRIBUTE((unused)) )
11: 310:{
-: 311: int i;
-: 312:
-: 313: MPIU_UNREFERENCED_ARG(p);
-: 314:
11: 315: if (not_initialized == 0) {
-: 316:
55: 317: for (i=0; i<first_free_class; i++) {
44: 318: if (user_class_msgs[i])
9: 319: MPIU_Free((char *) user_class_msgs[i]);
-: 320: }
-: 321:
199: 322: for (i=0; i<first_free_code; i++) {
188: 323: if (user_code_msgs[i])
177: 324: MPIU_Free((char *) user_code_msgs[i]);
-: 325: }
-: 326: }
11: 327: return 0;
-: 328:}
|