IAP GITLAB

Skip to content
Snippets Groups Projects
Commit 9559d501 authored by Lukas Nellen's avatar Lukas Nellen :footprints:
Browse files

Linux / OSX portable floating point exception enable/disable

parent d6c1191c
No related branches found
No related tags found
1 merge request!60OSX brew fixes
Pipeline #206 passed
......@@ -31,10 +31,11 @@
#include <corsika/random/RNGManager.h>
#include <corsika/utl/CorsikaFenv.h>
#include <boost/type_index.hpp>
using boost::typeindex::type_id_with_cvr;
#include <fenv.h>
#include <iostream>
#include <limits>
#include <typeinfo>
......
......@@ -2,13 +2,14 @@
set (
UTILITIES_SOURCES
COMBoost.cc
)
CorsikaFenv.cc)
set (
UTILITIES_HEADERS
COMBoost.h
Bit.h
Singleton.h
CorsikaFenv.h
)
set (
......@@ -58,5 +59,13 @@ target_link_libraries (
CORSIKAutilities
CORSIKAthirdparty # for catch2
)
CORSIKA_ADD_TEST(testCOMBoost)
add_executable (testCorsikaFenv testCorsikaFenv.cc)
target_link_libraries (
testCorsikaFenv
CORSIKAutilities
CORSIKAthirdparty # for catch2
)
CORSIKA_ADD_TEST(testCOMBoost)
add_test(testCorsikaFenv testCorsikaFenv)
/**
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* See file AUTHORS for a list of contributors.
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*
* Provide portable or fallback versions of feenableexcept() and fedisableexcept()
* Exist by default in glibc since version 2.2, but not in the standard
* fenv.h / cfenv headers for C 99 or C++ 11
*
* \author Lukas Nellen
* \date 14 Jan 2019
*
*/
#include <corsika/utl/CorsikaFenv.h>
#include <cfenv>
#if defined(__GLIBC__)
// do nothing functions exist
#elif defined(__APPLE__) && defined(__MACH__)
// Implementation of OS X on intel X64_86
// code from https://stackoverflow.com/questions/37819235/how-do-you-enable-floating-point-exceptions-for-clang-in-os-x
// based on http://www-personal.umich.edu/~williams/archive/computation/fe-handling-example.c
extern "C" {
int
feenableexcept(int excepts) {
static fenv_t fenv;
int new_excepts = excepts & FE_ALL_EXCEPT;
// previous masks
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;
}
int
fedisableexcept(int excepts) {
static fenv_t fenv;
int new_excepts = excepts & FE_ALL_EXCEPT;
// all previous masks
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;
}
}
#else
// unknown environment, dummy implementations
extern "C" {
#warning No enabling/disabling of floating point exceptions
int feenableexcept(int excepts)
{
return -1;
}
int fedisableexcept(int excepts)
{
return -1;
}
}
#endif
/**
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* See file AUTHORS for a list of contributors.
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*
* Provide portable or fallback versions of feenableexcept() and fedisableexcept()
* Exist by default in glibc since version 2.2, but not in the standard
* fenv.h / cfenv headers for C 99 or C++ 11
*
* \author Lukas Nellen
* \date 14 Jan 2019
*
*/
#ifndef CORSIKA_CORSIKAFENV_H
#define CORSIKA_CORSIKAFENV_H
#include <cfenv>
#if !defined(__GLIBC__)
extern "C" {
int
feenableexcept(int excepts);
int
fedisableexcept(int excepts);
}
#endif
#endif //CORSIKA_CORSIKAFENV_H
/**
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* See file AUTHORS for a list of contributors.
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*/
#include <corsika/utl/CorsikaFenv.h>
#include <cmath>
#include <iostream>
#include <csignal>
extern "C" {
static void
handle_fpe(int /*signo*/ ) {
exit(0);
}
}
int
main() {
feenableexcept(FE_ALL_EXCEPT);
signal(SIGFPE, handle_fpe);
std::cout << std::log(0.) << std::endl;
exit(1);
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment