1 #ifndef __PLE_DEFS_H__
2 #define __PLE_DEFS_H__
3 
4 /*============================================================================
5  * Definitions, global variables, and base functions
6  *============================================================================*/
7 
8 /*
9   This file is part of the "Parallel Location and Exchange" library,
10   intended to provide mesh or particle-based code coupling services.
11 
12   Copyright (C) 2005-2021  EDF S.A.
13 
14   This library is free software; you can redistribute it and/or
15   modify it under the terms of the GNU Lesser General Public
16   License as published by the Free Software Foundation; either
17   version 2.1 of the License, or (at your option) any later version.
18 
19   This library is distributed in the hope that it will be useful,
20   but WITHOUT ANY WARRANTY; without even the implied warranty of
21   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22   Lesser General Public License for more details.
23 
24   You should have received a copy of the GNU Lesser General Public
25   License along with this library; if not, write to the Free Software
26   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
27 */
28 
29 /*----------------------------------------------------------------------------*/
30 
31 #include "ple_config.h"
32 
33 /*----------------------------------------------------------------------------*/
34 
35 #include <stdarg.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #if 0
40 } /* Fake brace to force back Emacs auto-indentation back to column 0 */
41 #endif
42 #endif /* __cplusplus */
43 
44 /*=============================================================================
45  * Macro definitions
46  *============================================================================*/
47 
48 /* Absolute, minimum, and maximum values */
49 
50 #define PLE_ABS(a)     ((a) <  0  ? -(a) : (a))  /* Absolute value of a */
51 #define PLE_MIN(a,b)   ((a) > (b) ?  (b) : (a))  /* Minimum of a et b */
52 #define PLE_MAX(a,b)   ((a) < (b) ?  (b) : (a))  /* Maximum of a et b */
53 
54 /*
55  * Allocate memory for _ni items of type _type.
56  *
57  * This macro calls ple_mem_malloc(), automatically setting the
58  * allocated variable name and source file name and line arguments.
59  *
60  * parameters:
61  *   _ptr  --> pointer to allocated memory.
62  *   _ni   <-- number of items.
63  *   _type <-- element type.
64  */
65 
66 #define PLE_MALLOC(_ptr, _ni, _type) \
67 _ptr = (_type *) ple_mem_malloc(_ni, sizeof(_type), \
68                                 #_ptr, __FILE__, __LINE__)
69 
70 /*
71  * Reallocate memory for _ni items of type _type.
72  *
73  * This macro calls ple_mem_realloc(), automatically setting the
74  * allocated variable name and source file name and line arguments.
75  *
76  * parameters:
77  *   _ptr  <->  pointer to allocated memory.
78  *   _ni   <-- number of items.
79  *   _type <-- element type.
80  */
81 
82 #define PLE_REALLOC(_ptr, _ni, _type) \
83 _ptr = (_type *) ple_mem_realloc(_ptr, _ni, sizeof(_type), \
84                                  #_ptr, __FILE__, __LINE__)
85 
86 /*
87  * Free allocated memory.
88  *
89  * This macro calls ple_mem_free(), automatically setting the
90  * allocated variable name and source file name and line arguments.
91  *
92  * The freed pointer is set to NULL to avoid accidental reuse.
93  *
94  * parameters:
95  *   _ptr  <->  pointer to allocated memory.
96  */
97 
98 #ifdef __cplusplus /* avoid casting from void for C++ */
99 
100 #define PLE_FREE(_ptr) \
101 ple_mem_free(_ptr, #_ptr, __FILE__, __LINE__), _ptr = NULL
102 
103 #else
104 
105 #define PLE_FREE(_ptr) \
106 _ptr = ple_mem_free(_ptr, #_ptr, __FILE__, __LINE__)
107 
108 #endif /* __cplusplus */
109 
110 /*============================================================================
111  * Type definitions
112  *============================================================================*/
113 
114 /*----------------------------------------------------------------------------
115  * General C types such as size_t which should be known
116  *----------------------------------------------------------------------------*/
117 
118 /*
119  * Obtain definitions such as that of size_t through stddef.h (C99 standard)
120  * if available (preferred method), or through stdlib.h (which defines
121  * malloc() and family and so must define size_t some way) otherwise.
122  * This must be done in ple_defs.h in a way independent of the private
123  * configuration files, as size_t is used in many public FVM headers.
124  */
125 
126 #if defined(__STDC_VERSION__)
127 # if (__STDC_VERSION__ >= 199901L)
128 #   include <stddef.h>
129 # else
130 #   include <stdlib.h>
131 # endif
132 #else
133 # include <stdlib.h>
134 #endif
135 
136 /*----------------------------------------------------------------------------
137  * Basic types used by PLE.
138  * They may be modified here to better map to a given library, with the
139  * following constraints:
140  *  - ple_lnum_t must be signed
141  *----------------------------------------------------------------------------*/
142 
143 #if defined(PLE_HAVE_LONG_LNUM)
144   typedef long     ple_lnum_t;     /* Local integer index or number */
145 #else
146   typedef int      ple_lnum_t;     /* Local integer index or number */
147 #endif
148 
149 typedef double   ple_coord_t;    /* Real number (coordinate value) */
150 
151 /*----------------------------------------------------------------------------
152  * MPI datatypes.
153  *----------------------------------------------------------------------------*/
154 
155 #if defined(PLE_HAVE_MPI)
156 
157 #define PLE_MPI_TAG      (int)('P'+'L'+'E') /* MPI tag for PLE operations */
158 
159 #if defined(PLE_HAVE_LONG_LNUM)
160 #  define PLE_MPI_LNUM   MPI_LONG        /* MPI type for ple_lnum_t type */
161 #else
162 #  define PLE_MPI_LNUM   MPI_INT         /* MPI type for ple_lnum_t type */
163 #endif
164 
165 #define PLE_MPI_COORD    MPI_DOUBLE      /* MPI type for ple_coord_t type */
166 
167 #endif
168 
169 /*----------------------------------------------------------------------------
170  * Macro used to silence "unused argument" warnings.
171  *
172  * This is useful when a function must match a given function pointer
173  * type, but does not use all possible arguments.
174  *----------------------------------------------------------------------------*/
175 
176 #define PLE_UNUSED(x) (void)(x)
177 
178 /*----------------------------------------------------------------------------
179  * Macros for compilation with a C++ compiler
180  *----------------------------------------------------------------------------*/
181 
182 #undef PLE_BEGIN_C_DECLS
183 #undef   PLE_END_C_DECLS
184 
185 #if defined(__cplusplus)
186 #  define PLE_BEGIN_C_DECLS  extern "C" {
187 #  define   PLE_END_C_DECLS  }
188 #else
189 #  define PLE_BEGIN_C_DECLS
190 #  define   PLE_END_C_DECLS
191 #endif
192 
193 /*----------------------------------------------------------------------------
194  * Macros for scoping of examples
195  *----------------------------------------------------------------------------*/
196 
197 #undef PLE_BEGIN_EXAMPLE_SCOPE
198 #undef PLE_END_EXAMPLE_SCOPE
199 
200 #define PLE_BEGIN_EXAMPLE_SCOPE  {
201 #define   PLE_END_EXAMPLE_SCOPE  }
202 
203 /*----------------------------------------------------------------------------
204  * Function pointer types
205  *----------------------------------------------------------------------------*/
206 
207 typedef int
208 (ple_printf_t) (const char  *const format,
209                 va_list            arg_ptr);
210 
211 typedef void
212 (ple_error_handler_t) (const char  *file_name,
213                        const int    line_num,
214                        const int    sys_error_code,
215                        const char  *format,
216                        va_list      arg_ptr);
217 
218 typedef void *
219 (ple_mem_malloc_t)(size_t       ni,
220                    size_t       size,
221                    const char  *var_name,
222                    const char  *file_name,
223                    int          line_num);
224 
225 typedef void *
226 (ple_mem_realloc_t)(void        *ptr,
227                     size_t       ni,
228                     size_t       size,
229                     const char  *var_name,
230                     const char  *file_name,
231                     int          line_num);
232 
233 typedef void *
234 (ple_mem_free_t)(void        *ptr,
235                  const char  *var_name,
236                  const char  *file_name,
237                  int          line_num);
238 
239 /*============================================================================
240  * Public function prototypes
241  *============================================================================*/
242 
243 /*!
244  * \brief Replacement for printf() with modifiable behavior.
245  *
246  * This function calls vprintf() by default, or a function with similar
247  * arguments indicated by ple_printf_function_set().
248  *
249  * \param [in] format format string, as printf() and family.
250  * \param [in] ...    variable arguments based on format string.
251  *
252  * \return number of characters printed, not counting the trailing '\\0'
253  *         used to end output strings
254  */
255 
256 int
257 ple_printf(const char *const format,
258            ...);
259 
260 /* Returns function associated with the ple_printf() function.
261  *
262  * returns:
263  *   pointer to the vprintf() or replacement function.
264  */
265 
266 ple_printf_t *
267 ple_printf_function_get(void);
268 
269 /*
270  * Associates a vprintf() type function with the ple_printf() function.
271  *
272  * parameters:
273  *   f <-- pointer to a vprintf() type function.
274  */
275 
276 void
277 ple_printf_function_set(ple_printf_t  *f);
278 
279 /*
280  * Calls the error handler (set by ple_error_handler_set() or default).
281  *
282  * With the default error handler, an error message is output to stderr,
283  * and the current process exits with an EXIT_FAILURE code.
284  *
285  * parameters:
286  *   file_name      <-- name of source file from which error handler called.
287  *   line_num       <-- line of source file from which error handler called.
288  *   sys_error_code <-- error code if error in system or libc call,
289  *                      0 otherwise.
290  *   format         <-- format string, as printf() and family.
291  *   ...            <-- variable arguments based on format string.
292  */
293 
294 void
295 ple_error(const char  *file_name,
296           const int    line_num,
297           const int    sys_error_code,
298           const char  *format,
299           ...);
300 
301 /*
302  * Returns the error handler associated with the ple_error() function.
303  *
304  * returns:
305  *   pointer to the error handler function.
306  */
307 
308 ple_error_handler_t *
309 ple_error_handler_get(void);
310 
311 /*
312  * Associates an error handler with the ple_error() function.
313  *
314  * parameters:
315  *   handler <-- pointer to the error handler function.
316  */
317 
318 void
319 ple_error_handler_set(ple_error_handler_t  *handler);
320 
321 /*
322  * Allocate memory for ni items of size bytes.
323  *
324  * This function calls malloc(), but adds tracing capabilities, and
325  * automatically calls the ple_error() errorhandler if it fails to
326  * allocate the required memory.
327  *
328  * parameters:
329  *   ni        <-- number of items.
330  *   size      <-- element size.
331  *   var_name  <-- allocated variable name string.
332  *   file_name <-- name of calling source file.
333  *   line_num  <-- line number in calling source file.
334  *
335  * returns:
336  *   pointer to allocated memory.
337  */
338 
339 void *
340 ple_mem_malloc(size_t       ni,
341                size_t       size,
342                const char  *var_name,
343                const char  *file_name,
344                int          line_num);
345 
346 /*
347  * Reallocate memory for ni items of size bytes.
348  *
349  * This function calls realloc(), but adds tracing capabilities, and
350  * automatically calls the ple_error() errorhandler if it fails to
351  * allocate the required memory.
352  *
353  * parameters:
354  *   ptr       <-> pointer to previous memory location
355  *                 (if NULL, ple_alloc() called).
356  *   ni        <-- number of items.
357  *   size      <-- element size.
358  *   var_name  <-- allocated variable name string.
359  *   file_name <-- name of calling source file.
360  *   line_num   -> line number in calling source file
361  *
362  * returns:
363  *   pointer to allocated memory.
364  */
365 
366 void *
367 ple_mem_realloc(void        *ptr,
368                 size_t       ni,
369                 size_t       size,
370                 const char  *var_name,
371                 const char  *file_name,
372                 int          line_num);
373 
374 /*
375  * Free allocated memory.
376  *
377  * This function calls free(), but adds tracing capabilities, and
378  * automatically calls the ple_error() errorhandler if it fails to
379  * free the corresponding memory. In case of a NULL pointer argument,
380  * the function simply returns.
381  *
382  * parameters:
383  *   ptr       <-> pointer to previous memory location
384  *                 (if NULL, ple_alloc() called).
385  *   var_name  <-- allocated variable name string.
386  *   file_name <-- name of calling source file.
387  *   line_num  <-- line number in calling source file.
388  *
389  * returns:
390  *   NULL pointer.
391  */
392 
393 void *
394 ple_mem_free(void        *ptr,
395              const char  *var_name,
396              const char  *file_name,
397              int          line_num);
398 
399 /* Return the function pointers associated with PLE's memory management.
400  *
401  * All arguments are optional.
402  *
403  * parameters:
404  *   malloc_func  <-- pointer to ple_mem_malloc function pointer (or NULL).
405  *   realloc_func <-- pointer to ple_mem_realloc function pointer (or NULL).
406  *   free_func    <-- pointer to ple_mem_free function pointer (or NULL).
407  */
408 
409 void
410 ple_mem_functions_get(ple_mem_malloc_t   **malloc_func,
411                       ple_mem_realloc_t  **realloc_func,
412                       ple_mem_free_t     **free_func);
413 
414 /* Associate functions to modifiy PLE's memory management.
415  *
416  * All arguments are optional, so the previously set functions pointers will
417  * not be modified if an argument value is NULL.
418  *
419  * parameters:
420  *   malloc_func  <-- ple_mem_malloc function pointer (or NULL).
421  *   realloc_func <-- ple_mem_realloc function pointer (or NULL).
422  *   free_func    <-- ple_mem_free function pointer (or NULL).
423  */
424 
425 void
426 ple_mem_functions_set(ple_mem_malloc_t   *malloc_func,
427                       ple_mem_realloc_t  *realloc_func,
428                       ple_mem_free_t     *free_func);
429 
430 /*
431  * Return Wall clock time
432  *
433  * returns:
434  *   elapsed time from first call of a function of the ple_timer_...()
435  *   series, or -1 if unable to compute.
436  */
437 
438 double
439 ple_timer_wtime(void);
440 
441 /*
442  * Return CPU time.
443  *
444  * Note that in the rare case that only the minimal C library clock()
445  * method is available (see ple_timer_cpu_time_method()), at least one of
446  * the ple_timer_...() functions (possibly this one) must be called
447  * upon program start for this function to be used. In addition,
448  * in this case, time may "loop" back to 0 every multiple of
449  * 2^size_t / CLOCKS_PER_SEC seconds.
450  *
451  * returns:
452  *   current CPU time usage, or -1 if unable to compute.
453  */
454 
455 double
456 ple_timer_cpu_time(void);
457 
458 /*----------------------------------------------------------------------------*/
459 
460 #ifdef __cplusplus
461 }
462 #endif /* __cplusplus */
463 
464 #endif /* __PLE_DEFS_H__ */
465