1 /* 2 * Copyright (c) 2004-2010, Bruno Levy 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * * Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * * Neither the name of the ALICE Project-Team nor the names of its 14 * contributors may be used to endorse or promote products derived from this 15 * software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 * If you modify this software, you should include a notice giving the 30 * name of the person performing the modification, the date of modification, 31 * and the reason for such modification. 32 * 33 * Contact: Bruno Levy 34 * 35 * levy@loria.fr 36 * 37 * ALICE Project 38 * LORIA, INRIA Lorraine, 39 * Campus Scientifique, BP 239 40 * 54506 VANDOEUVRE LES NANCY CEDEX 41 * FRANCE 42 * 43 */ 44 45 #ifndef OPENNL_PRIVATE_H 46 #define OPENNL_PRIVATE_H 47 48 #include "nl.h" 49 #include <stdlib.h> 50 #include <string.h> 51 #include <stdio.h> 52 #include <math.h> 53 54 #ifndef NDEBUG 55 #define NL_DEBUG 56 #endif 57 58 /** 59 * \file geogram/NL/nl_private.h 60 * \brief Some macros and functions used internally by OpenNL. 61 */ 62 63 #if defined(__APPLE__) && defined(__MACH__) 64 /** 65 * \brief Defined if compiled on a Mac OS/X platform. 66 */ 67 #define NL_OS_APPLE 68 #endif 69 70 #if defined(__linux__) || defined(__DragonFly__) || defined(__ANDROID__) || defined(NL_OS_APPLE) 71 /** 72 * \brief Defined if compiled on a Unix-like platform. 73 */ 74 #define NL_OS_UNIX 75 #endif 76 77 78 #if defined(WIN32) || defined(_WIN64) 79 /** 80 * \brief Defined if compiled on a Windows platform. 81 */ 82 #define NL_OS_WINDOWS 83 #endif 84 85 /** 86 * \brief Suppresses unsused argument warnings 87 * \details Some callbacks do not necessary use all their 88 * arguments. 89 * \param[in] x the argument to be tagged as used 90 */ 91 #define nl_arg_used(x) (void)x 92 93 /** 94 * \name Assertion checks 95 * @{ 96 */ 97 98 #if defined(__clang__) || defined(__GNUC__) 99 #define NL_NORETURN __attribute__((noreturn)) 100 #else 101 #define NL_NORETURN 102 #endif 103 104 #if defined(_MSC_VER) 105 #define NL_NORETURN_DECL __declspec(noreturn) 106 #else 107 #define NL_NORETURN_DECL 108 #endif 109 110 /** 111 * \brief Displays an error message and aborts the program when 112 * an assertion failed. 113 * \details Called by nl_assert() whenever the assertion failed 114 * \param[in] cond the textual representation of the condition 115 * \param[in] file the source filename 116 * \param[in] line the line number 117 */ 118 NL_NORETURN_DECL void nl_assertion_failed( 119 const char* cond, const char* file, int line 120 ) NL_NORETURN; 121 122 /** 123 * \brief Displays an error message and aborts the program 124 * when a range assertion failed. 125 * \details Called by nl_range_assert() whenever the assertion failed 126 * \param[in] x the variable 127 * \param[in] min_val the minimum value 128 * \param[in] max_val the maximum value 129 * \param[in] file the source filename 130 * \param[in] line the line number 131 */ 132 NL_NORETURN_DECL void nl_range_assertion_failed( 133 double x, double min_val, double max_val, const char* file, int line 134 ) NL_NORETURN; 135 136 /** 137 * \brief Displays an error message and aborts the program 138 * when the execution flow reached a point it should not 139 * have reached. 140 * \details called by nl_assert_not_reached 141 * \param[in] file the source filename 142 * \param[in] line the line number 143 */ 144 NL_NORETURN_DECL void nl_should_not_have_reached( 145 const char* file, int line 146 ) NL_NORETURN; 147 148 /** 149 * \brief Tests an assertion and aborts the program if the test fails 150 * \param[in] x the condition to be tested 151 */ 152 #define nl_assert(x) { \ 153 if(!(x)) { \ 154 nl_assertion_failed(#x,__FILE__, __LINE__) ; \ 155 } \ 156 } 157 158 /** 159 * \brief Tests a range assertion and aborts the program if the test fails 160 * \param[in] x the variable to be tested 161 * \param[in] min_val the minimum admissible value for the variable 162 * \param[in] max_val the maximum admissible value for the variable 163 */ 164 #define nl_range_assert(x,min_val,max_val) { \ 165 if(((int)(x) < (int)(min_val)) || ((int)(x) > (int)(max_val))) { \ 166 nl_range_assertion_failed(x, min_val, max_val, \ 167 __FILE__, __LINE__ \ 168 ) ; \ 169 } \ 170 } 171 172 /** 173 * \brief Triggers an assertion failure when the execution flow 174 * reaches a specific location in the code. 175 */ 176 #define nl_assert_not_reached { \ 177 nl_should_not_have_reached(__FILE__, __LINE__) ; \ 178 } 179 180 #ifdef NL_DEBUG 181 #define nl_debug_assert(x) nl_assert(x) 182 #define nl_debug_range_assert(x,min_val,max_val) \ 183 nl_range_assert(x,min_val,max_val) 184 #else 185 #define nl_debug_assert(x) 186 #define nl_debug_range_assert(x,min_val,max_val) 187 #endif 188 189 #ifdef NL_PARANOID 190 #define nl_parano_assert(x) nl_assert(x) 191 #define nl_parano_range_assert(x,min_val,max_val) \ 192 nl_range_assert(x,min_val,max_val) 193 #else 194 #define nl_parano_assert(x) 195 #define nl_parano_range_assert(x,min_val,max_val) 196 #endif 197 198 /** 199 * @} 200 * \name Error reporting 201 * @{ 202 */ 203 204 /** 205 * \brief Displays an error message 206 * \param[in] function name of the function that triggered the error 207 * \param[in] message error message 208 */ 209 void nlError(const char* function, const char* message) ; 210 211 /** 212 * \brief Displays a warning message 213 * \param[in] function name of the function that triggered the error 214 * \param[in] message warning message 215 */ 216 void nlWarning(const char* function, const char* message) ; 217 218 /** 219 * @} 220 * \name OS 221 * @{ 222 */ 223 224 /** 225 * \brief Gets the current time in seconds 226 * \return the current time in seconds (starting from a given reference time) 227 */ 228 NLdouble nlCurrentTime(void); 229 230 231 /** 232 * \brief Gets the number of cores 233 * \return the number of cores obtained from OpenMP if supported, or 1 234 */ 235 NLuint nlGetNumCores(void); 236 237 /** 238 * \brief Gets the number of threads 239 * \return the number of threads used by OpenMP if supported, or 1 240 */ 241 NLuint nlGetNumThreads(void); 242 243 /** 244 * \brief Sets the number of threads 245 * \param[in] nb_threads number of threads to be used by OpenMP, 246 * ignored if OpenMP is not supported. 247 */ 248 void nlSetNumThreads(NLuint nb_threads); 249 250 /** 251 * \brief Type for manipulating DLL/shared object/dylib handles. 252 */ 253 typedef void* NLdll; 254 255 256 /** 257 * \brief Flag for nlOpenDLL(), resolve all symbols when opening the DLL. 258 * \see nlOpenDLL() 259 */ 260 #define NL_LINK_NOW 1 261 262 /** 263 * \brief Flag for nlOpenDLL(), resolve symbols only when they are called. 264 * \see nlOpenDLL() 265 */ 266 #define NL_LINK_LAZY 2 267 268 /** 269 * \brief Flag for nlOpenDLL(), add all loaded symbols to global namespace. 270 */ 271 #define NL_LINK_GLOBAL 4 272 273 /** 274 * \brief Flag for nlOpenDLL(), do not display messages. 275 */ 276 #define NL_LINK_QUIET 8 277 278 /** 279 * \brief Flag for nlOpenDLL(), use fallback geogram numerical library if 280 * library is not found in the system. 281 */ 282 #define NL_LINK_USE_FALLBACK 16 283 284 /** 285 * \brief Dynamically links a DLL/shared object/dylib to the current process. 286 * \param[in] filename the file name fo the DLL/shared object/dylib. 287 * \param[in] flags an or-combination of NL_LINK_NOW, NL_LINK_LAZY, NL_LINK_GLOBAL, 288 * NL_LINK_QUIET. 289 * \return a handle to the DLL/shared object/dylib or NULL if it could not 290 * be found. 291 */ 292 NLdll nlOpenDLL(const char* filename, NLenum flags); 293 294 /** 295 * \brief Closes a DLL/shared object/dylib. 296 * \param[in] handle a handle to a DLL/shared object/dylib that was previously 297 * obtained by nlOpenDLL() 298 */ 299 void nlCloseDLL(NLdll handle); 300 301 /** 302 * \brief Finds a function in a DLL/shared object/dylib. 303 * \param[in] handle a handle to a DLL/shared object/dylib that was previously 304 * obtained by nlOpenDLL() 305 * \param[in] funcname the name of the function 306 * \return a pointer to the function or NULL if no such function was found 307 */ 308 NLfunc nlFindFunction(NLdll handle, const char* funcname); 309 310 /******************************************************************************/ 311 /* classic macros */ 312 313 #ifndef MIN 314 #define MIN(x,y) (((x) < (y)) ? (x) : (y)) 315 #endif 316 317 #ifndef MAX 318 #define MAX(x,y) (((x) > (y)) ? (x) : (y)) 319 #endif 320 321 322 /** 323 * @} 324 * \name Memory management 325 * @{ 326 */ 327 328 /** 329 * \brief Allocates a new element 330 * \details Memory is zeroed after allocation 331 * \param[in] T type of the element to be allocated 332 */ 333 #define NL_NEW(T) (T*)(calloc(1, sizeof(T))) 334 335 /** 336 * \brief Allocates a new array of elements 337 * \details Memory is zeroed after allocation 338 * \param[in] T type of the elements 339 * \param[in] NB number of elements 340 */ 341 #define NL_NEW_ARRAY(T,NB) (T*)(calloc((size_t)(NB),sizeof(T))) 342 343 /** 344 * \brief Changes the size of an already allocated array of elements 345 * \details Memory is zeroed after allocation 346 * \param[in] T type of the elements 347 * \param[in,out] x a pointer to the array to be resized 348 * \param[in] NB number of elements 349 */ 350 #define NL_RENEW_ARRAY(T,x,NB) (T*)(realloc(x,(size_t)(NB)*sizeof(T))) 351 352 /** 353 * \brief Deallocates an element 354 * \param[in,out] x a pointer to the element to be deallocated 355 */ 356 #define NL_DELETE(x) free(x); x = NULL 357 358 /** 359 * \brief Deallocates an array 360 * \param[in,out] x a pointer to the first element of the array to 361 * be deallocated 362 */ 363 #define NL_DELETE_ARRAY(x) free(x); x = NULL 364 365 /** 366 * \brief Clears an element 367 * \param[in] T type of the element to be cleared 368 * \param[in,out] x a pointer to the element 369 */ 370 #define NL_CLEAR(T, x) memset(x, 0, sizeof(T)) 371 372 /** 373 * \brief Clears an array of elements 374 * \param[in] T type of the element to be cleared 375 * \param[in,out] x a pointer to the element 376 * \param[in] NB number of elements 377 */ 378 #define NL_CLEAR_ARRAY(T,x,NB) memset(x, 0, (size_t)(NB)*sizeof(T)) 379 380 /** 381 * @} 382 * \name Integer bounds 383 * @{ 384 */ 385 386 /** 387 * \brief Maximum unsigned 32 bits integer 388 */ 389 #define NL_UINT_MAX 0xffffffff 390 391 /** 392 * \brief Maximum unsigned 16 bits integer 393 */ 394 #define NL_USHORT_MAX 0xffff 395 396 /** 397 * @} 398 * \name Logging and messages 399 * @{ 400 */ 401 402 extern NLprintfFunc nl_printf; 403 404 extern NLfprintfFunc nl_fprintf; 405 406 /** 407 * @} 408 */ 409 410 #endif 411