Loading...
Searching...
No Matches
fpe_handler.h
Go to the documentation of this file.
1/*
2** This file is part of eOn.
3**
4** SPDX-License-Identifier: BSD-3-Clause
5**
6** Copyright (c) 2010--present, eOn Development Team
7** All rights reserved.
8**
9** Repo:
10** https://github.com/TheochemUI/eOn
11*/
12#pragma once
13
14#include <cstdint>
15#include <fenv.h>
16#include <mutex>
17
18namespace eonc {
19
20// Windows x64 EXCEPTION_CONTINUE_EXECUTION reloads this MXCSR from
21// CONTEXT.MxCsr. Bits 7-12 are the exception masks; bits 0-5 are sticky
22// flags. _controlfp_s updates the live register only.
23constexpr std::uint32_t kWindowsMxcsrExceptionMasks = 0x1F80u;
24constexpr std::uint32_t maskWindowsMxcsrForContinue(std::uint32_t mxcsr) {
25 return (mxcsr & ~std::uint32_t{0x3Fu}) | kWindowsMxcsrExceptionMasks;
26}
27
28// Floating Point Trapping. It is platform specific!
29// This causes the program to crash on division by zero,
30// invalid operations, and overflows.
31void enableFPE(void);
32void disableFPE(void);
33
35public:
36 // Fix for gh-184, see
37 // https://github.com/numpy/numpy/issues/20504#issuecomment-985542508
38 void eat_fpe();
39 void restore_fpe();
40
41private:
42 fenv_t orig_feenv;
43 std::mutex mutex_;
44};
45
46// eat_fpe for one scope. The destructor restores traps on every exit,
47// including when the guarded call throws.
48class FPEGuard {
49public:
50 FPEGuard() { handler_.eat_fpe(); }
51 ~FPEGuard() { handler_.restore_fpe(); }
52 FPEGuard(const FPEGuard &) = delete;
53 FPEGuard &operator=(const FPEGuard &) = delete;
54
55private:
57};
58
59} // namespace eonc
FPEGuard(const FPEGuard &)=delete
FPEHandler handler_
Definition fpe_handler.h:56
FPEGuard & operator=(const FPEGuard &)=delete
std::mutex mutex_
Definition fpe_handler.h:43
RAII resource manager for the ARTn C library with global synchronization.
constexpr std::uint32_t kWindowsMxcsrExceptionMasks
Definition fpe_handler.h:23
constexpr std::uint32_t maskWindowsMxcsrForContinue(std::uint32_t mxcsr)
Definition fpe_handler.h:24
void enableFPE()
void disableFPE()