1 /*
2  *
3  *  This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011
4  *
5  *
6  *  This version of MUMPS is provided to you free of charge. It is public
7  *  domain, based on public domain software developed during the Esprit IV
8  *  European project PARASOL (1996-1999). Since this first public domain
9  *  version in 1999, research and developments have been supported by the
10  *  following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT,
11  *  INRIA, and University of Bordeaux.
12  *
13  *  The MUMPS team at the moment of releasing this version includes
14  *  Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche,
15  *  Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora
16  *  Ucar and Clement Weisbecker.
17  *
18  *  We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil
19  *  Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat,
20  *  Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire
21  *  Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who
22  *  have been contributing to this project.
23  *
24  *  Up-to-date copies of the MUMPS package can be obtained
25  *  from the Web pages:
26  *  http://mumps.enseeiht.fr/  or  http://graal.ens-lyon.fr/MUMPS
27  *
28  *
29  *   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
30  *   EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
31  *
32  *
33  *  User documentation of any code that uses this software can
34  *  include this complete notice. You can acknowledge (using
35  *  references [1] and [2]) the contribution of this package
36  *  in any scientific publication dependent upon the use of the
37  *  package. You shall use reasonable endeavours to notify
38  *  the authors of the package of this publication.
39  *
40  *   [1] P. R. Amestoy, I. S. Duff, J. Koster and  J.-Y. L'Excellent,
41  *   A fully asynchronous multifrontal solver using distributed dynamic
42  *   scheduling, SIAM Journal of Matrix Analysis and Applications,
43  *   Vol 23, No 1, pp 15-41 (2001).
44  *
45  *   [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and
46  *   S. Pralet, Hybrid scheduling for the parallel solution of linear
47  *   systems. Parallel Computing Vol 32 (2), pp 136-156 (2006).
48  *
49  */
50 #include "mumps_io_err.h"
51 #include "mumps_io_basic.h"
52 #if defined( MUMPS_WIN32 )
53 # include <string.h>
54 #endif
55 /* Exported global variables */
56 char* mumps_err;
57 MUMPS_INT* dim_mumps_err;
58 int mumps_err_max_len;
59 int err_flag;
60 #if ! ( defined(MUMPS_WIN32) || defined(WITHOUT_PTHREAD) )
61 pthread_mutex_t err_mutex;
62 #endif /* ! ( MUMPS_WIN32 || WITHOUT_PTHREAD ) */
63 /* Functions */
64 /* Keeps a C pointer to store error description string that will be
65    displayed by the Fortran layers.
66    * dim contains the size of the Fortran character array to store the
67    description.
68 */
69 void MUMPS_CALL
MUMPS_LOW_LEVEL_INIT_ERR_STR(MUMPS_INT * dim,char * err_str,mumps_ftnlen l1)70 MUMPS_LOW_LEVEL_INIT_ERR_STR(MUMPS_INT *dim, char* err_str, mumps_ftnlen l1){
71   mumps_err = err_str;
72   dim_mumps_err = (MUMPS_INT *) dim;
73   mumps_err_max_len = (int) *dim;
74   err_flag = 0;
75   return;
76 }
77 #if ! defined(MUMPS_WIN32) && ! defined(WITHOUT_PTHREAD)
78 MUMPS_INLINE int
mumps_io_protect_err()79 mumps_io_protect_err()
80 {
81   if(mumps_io_flag_async==IO_ASYNC_TH){
82     pthread_mutex_lock(&err_mutex);
83   }
84   return 0;
85 }
86 MUMPS_INLINE int
mumps_io_unprotect_err()87 mumps_io_unprotect_err()
88 {
89   if(mumps_io_flag_async==IO_ASYNC_TH){
90     pthread_mutex_unlock(&err_mutex);
91   }
92   return 0;
93 }
94 int
mumps_io_init_err_lock()95 mumps_io_init_err_lock()
96 {
97   pthread_mutex_init(&err_mutex,NULL);
98   return 0;
99 }
100 int
mumps_io_destroy_err_lock()101 mumps_io_destroy_err_lock()
102 {
103   pthread_mutex_destroy(&err_mutex);
104   return 0;
105 }
106 int
mumps_check_error_th()107 mumps_check_error_th()
108 {
109   /* If err_flag != 0, then error_str is set */
110   return err_flag;
111 }
112 #endif /* MUMPS_WIN32 && WITHOUT_PTHREAD */
113 int
mumps_io_error(int mumps_errno,const char * desc)114 mumps_io_error(int mumps_errno, const char* desc)
115 {
116     int len;
117 #if ! defined( MUMPS_WIN32 ) && ! defined( WITHOUT_PTHREAD )
118   mumps_io_protect_err();
119 #endif
120   if(err_flag == 0){
121     strncpy(mumps_err, desc, mumps_err_max_len);
122     /* mumps_err is a FORTRAN string, we do not care about adding a final 0 */
123     len = (int) strlen(desc);
124     *dim_mumps_err = (len <= mumps_err_max_len ) ? len : mumps_err_max_len;
125     err_flag = mumps_errno;
126   }
127 #if ! defined( MUMPS_WIN32 ) && ! defined( WITHOUT_PTHREAD )
128   mumps_io_unprotect_err();
129 #endif
130   return mumps_errno;
131 }
132 int
mumps_io_sys_error(int mumps_errno,const char * desc)133 mumps_io_sys_error(int mumps_errno, const char* desc)
134 {
135   int len = 2; /* length of ": " */
136   const char* _desc;
137   char* _err;
138 #if defined( MUMPS_WIN32 )
139   int _err_len;
140 #endif
141 #if ! defined( MUMPS_WIN32 ) && ! defined( WITHOUT_PTHREAD )
142   mumps_io_protect_err();
143 #endif
144   if(err_flag==0){
145     if(desc == NULL) {
146       _desc = "";
147     } else {
148         len += (int) strlen(desc);
149       _desc = desc;
150     }
151 #if ! defined( MUMPS_WIN32 )
152     _err = strerror(errno);
153     len += (int) strlen(_err);
154     snprintf(mumps_err, mumps_err_max_len, "%s: %s", _desc, _err);
155     /* mumps_err is a FORTRAN string, we do not care about adding a final 0 */
156 #else
157     /* This a VERY UGLY workaround for snprintf: this function has been
158      * integrated quite lately into the ANSI stdio: some windows compilers are
159      * not up-to-date yet. */
160     if( len >= mumps_err_max_len - 1 ) { /* then do not print sys error msg at all */
161       len -= 2;
162       len = (len >= mumps_err_max_len ) ? mumps_err_max_len - 1 : len;
163       _err = strdup( _desc );
164       _err[len] = '\0';
165       sprintf(mumps_err, "%s", _err);
166     } else {
167       _err = strdup(strerror(errno));
168       _err_len = (int) strlen(_err);
169       /* We will use sprintf, so make space for the final '\0' ! */
170       if((len + _err_len) >= mumps_err_max_len) {
171         /* truncate _err, not to overtake mumps_err_max_len at the end. */
172         _err[mumps_err_max_len - len - 1] = '\0';
173         len = mumps_err_max_len - 1;
174       } else {
175         len += _err_len;
176       }
177       sprintf(mumps_err, "%s: %s", _desc, _err);
178     }
179     free(_err);
180 #endif
181     *dim_mumps_err = (len <= mumps_err_max_len ) ? len : mumps_err_max_len;
182     err_flag = mumps_errno;
183   }
184 #if ! defined( MUMPS_WIN32 ) && ! defined( WITHOUT_PTHREAD )
185   mumps_io_unprotect_err();
186 #endif
187   return mumps_errno;
188 }
189