diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index 935d1577a5f5935341132dce5bb5c21b169370d5..ad047d0ea29d6f6bff9001ca880d1419f2595d20 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -83,6 +83,17 @@ add_dependencies( include(CheckIncludeFile) check_include_file(fenv.h PASTIS_HAS_FENV_H) +# Checks for host system name +if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") + set(SYSTEM_IS_LINUX 1) +elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + set(SYSTEM_IS_DARWIN 1) +elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + set(SYSTEM_IS_WINDOWS 1) +else() + message(WARNMSG "Your system is ${CMAKE_HOST_SYSTEM_NAME} which may not be managed!") +endif() + # Generates pastis_config.hpp configure_file("${CMAKE_CURRENT_SOURCE_DIR}/pastis_config.hpp.in" "${CMAKE_CURRENT_BINARY_DIR}/pastis_config.hpp" diff --git a/src/utils/FPEManager.cpp b/src/utils/FPEManager.cpp index 455eb6d83eda5df6f76977bb086435391790ad2e..176787a01cf2f127a0c2ccc0dc46e2281fb705cf 100644 --- a/src/utils/FPEManager.cpp +++ b/src/utils/FPEManager.cpp @@ -7,6 +7,51 @@ #define MANAGED_FPE (FE_DIVBYZERO|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW) +#ifdef SYSTEM_IS_DARWIN +// MacOS-X requires definition of feenableexcept and fedisableexcept + +// Public domain polyfill for feenableexcept on OS X +// http://www-personal.umich.edu/~williams/archive/computation/fe-handling-example.c +inline int feenableexcept(unsigned int excepts) +{ + static fenv_t fenv; + unsigned int new_excepts = excepts & FE_ALL_EXCEPT; + // previous masks + unsigned int old_excepts; + + if (fegetenv(&fenv)) { + return -1; + } + old_excepts = fenv.__control & FE_ALL_EXCEPT; + + // unmask + fenv.__control &= ~new_excepts; + fenv.__mxcsr &= ~(new_excepts << 7); + + return fesetenv(&fenv) ? -1 : old_excepts; +} + +inline int fedisableexcept(unsigned int excepts) +{ + static fenv_t fenv; + unsigned int new_excepts = excepts & FE_ALL_EXCEPT; + // all previous masks + unsigned int old_excepts; + + if (fegetenv(&fenv)) { + return -1; + } + old_excepts = fenv.__control & FE_ALL_EXCEPT; + + // mask + fenv.__control |= new_excepts; + fenv.__mxcsr |= new_excepts << 7; + + return fesetenv(&fenv) ? -1 : old_excepts; +} + +#endif // SYSTEM_IS_DARWIN + void FPEManager::enable() { std::cout << "FE management: " diff --git a/src/utils/SignalManager.cpp b/src/utils/SignalManager.cpp index 271720d0df0d3c60738dc8300ca3675100c6b943..9f9da08f48c35c7e0a8344b831b8f4eca5cb7628 100644 --- a/src/utils/SignalManager.cpp +++ b/src/utils/SignalManager.cpp @@ -4,6 +4,9 @@ #include <ConsoleManager.hpp> #include <csignal> +#include <unistd.h> + +#include <pastis_config.hpp> #include <rang.hpp> std::string SignalManager::s_pause_on_error = "auto"; @@ -43,10 +46,7 @@ void SignalManager::pauseForDebug(const int& signal) std::cout << "======================================\n"; std::cout << std::flush; - ::sigset_t sig; - ::sigaddset(&sig,SIGSTOP); - ::sigsuspend(&sig); - + pause(); std::exit(signal); } diff --git a/src/utils/pastis_config.hpp.in b/src/utils/pastis_config.hpp.in index b415195c02368c6860ffd67e62227db51add9521..aa8d0505a453931c6dd777a64b10f242ca358eb7 100644 --- a/src/utils/pastis_config.hpp.in +++ b/src/utils/pastis_config.hpp.in @@ -2,5 +2,8 @@ #define PASTIS_CONFIG_HPP #cmakedefine PASTIS_HAS_FENV_H +#cmakedefine SYSTEM_IS_LINUX +#cmakedefine SYSTEM_IS_DARWIN +#cmakedefine SYSTEM_IS_WINDOWS #endif // PASTIS_CONFIG_HPP