Loading...
Searching...
No Matches
sigFpe.H
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2018-2025 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27Class
28 Foam::sigFpe
29
30Description
31 Set up trapping for floating point exceptions (signal FPE).
32
33 Defined by controlDict InfoSwitch entries:
34 - \par trapFpe
35 Enable floating point exception trapping.
36
37 - \par setNaN
38 Initialization all malloced memory to NaN.
39 Combined with \c trapFpe, this causes usage of uninitialized scalars
40 to trigger an abort.
41
42 Environment variables:
43 - \par FOAM_SIGFPE (true|false)
44 overrides \c trapFpe
45 - \par FOAM_SETNAN (true|false)
46 overrides \c setNaN
47
48 Note that trapping can be set/removed through the static member functions
49 or through the scope of the object (constructor sets trapping; destructor
50 restores original). The class behaves as a singleton.
51
52SourceFiles
53 sigFpe.cxx
54
55\*---------------------------------------------------------------------------*/
56
57#ifndef Foam_sigFpe_H
58#define Foam_sigFpe_H
59
60#include <algorithm>
61#include <limits>
62#include <cstddef> // For std::size_t
63#include "scalarFwd.H"
64
65// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
66
67namespace Foam
68{
69
70// Forward Declarations
71template<class T> class UList;
73/*---------------------------------------------------------------------------*\
74 Class sigFpe Declaration
75\*---------------------------------------------------------------------------*/
76
77class sigFpe
78{
79 // Private Data
80
81 //- Flag that floating point trapping should be used.
82 // Can override with FOAM_SIGFPE env variable
83 static bool switchFpe_;
84
85 //- Flag that NaN initialisation should be used.
86 // Can override with FOAM_SETNAN env variable
87 static bool switchNan_;
88
89 //- Floating point trapping currently active?
90 static bool sigActive_;
91
92 //- Is NaN memory initialisation currently active?
93 static bool nanActive_;
94
95
96 // Private Member Functions
97
98 //- Handler for caught signals - ends job and prints stack
99 static void sigHandler(int);
100
101 //- Fill (float | double) buffer with signalling NaN
102 template<class FloatType>
103 inline static void fill_with_NaN(FloatType* buf, size_t count)
104 {
105 if (buf && count)
106 {
107 const auto val =
108 std::numeric_limits<FloatType>::signaling_NaN();
109
110 // [float|double] so do not need std::uninitialized_fill_n()
111 // Can dispatch with
112 // - std::execution::par_unseq
113 // - std::execution::unseq
114 std::fill_n(buf, count, val);
115 }
116 }
117
118
119public:
120
121 // Constructors
122
123 //- Constructor calls set() to activate the FPE signal handler if it
124 //- was was not previously activate and requested() returns true.
125 sigFpe();
126
127
128 //- Destructor calls unset() to deactivate the FPE signal handler
129 //- as required.
130 ~sigFpe();
131
132
133 // Static Member Functions
134
135 //- Check if SIGFPE signals handler is to be enabled.
136 // This is controlled by the trapFpe entry or the FOAM_SIGFPE
137 // environment variable
138 static bool requested();
139
140 //- True if SIGFPE handling is currently active.
141 static bool active() noexcept { return sigActive_; }
142
143 //- True if NaN memory initialisation is currently active.
144 static bool nanActive() noexcept { return nanActive_; }
145
146 //- Set NaN memory initialisation on/off.
147 // \return the previous value
148 static bool nanActive(bool on) noexcept
149 {
150 bool old(nanActive_);
151 nanActive_ = on;
152 return old;
153 }
155 //- Activate SIGFPE handler when FOAM_SIGFPE is enabled.
156 //- Activate fill memory with signaling_NaN when FOAM_SETNAN is enabled
157 static void set(bool verbose=false);
158
159 //- Deactivate SIGFPE handler and NaN memory initialisation
160 static void unset(bool verbose=false);
161
162 //- Fill data block with signaling_NaN values if nanActive().
163 //- Does a reinterpret to \c Foam::scalar
164 static void fillNan_if(void* buf, size_t count)
165 {
166 if (nanActive_)
167 {
168 fill_with_NaN
169 (
170 reinterpret_cast<Foam::scalar*>(buf),
171 (count/sizeof(Foam::scalar))
172 );
173 }
174 }
175
176 //- Fill data block with signaling_NaN values.
177 //- Does a reinterpret to \c Foam::scalar
178 static void fillNan(char* buf, size_t count)
179 {
180 fill_with_NaN
181 (
182 reinterpret_cast<Foam::scalar*>(buf),
183 (count/sizeof(Foam::scalar))
184 );
185 }
186
187 //- Fill data block with (float) signaling_NaN values
188 static void fillNan(UList<float>& list);
189
190 //- Fill data block with (double) signaling_NaN values
191 static void fillNan(UList<double>& list);
192
194 // Helpers
195
196 //- Helper to locally ignore SIGFPE handling.
197 // Restores the original state of the SIGFPE handler on destruction.
198 class ignore
199 {
200 //- The signal handler state when entering
201 bool wasActive_;
202
203 public:
204
205 //- No copy construct
206 ignore(const ignore&) = delete;
207
208 //- No move construct
209 ignore(ignore&&) = delete;
210
211 //- No copy assignment
212 void operator=(const ignore&) = delete;
213
214 //- No move assignment
215 void operator=(ignore&&) = delete;
216
217 //- Constructor deactivates any previously active SIGFPE handler
218 ignore()
219 :
220 wasActive_(Foam::sigFpe::active())
222 if (wasActive_)
223 {
225 }
227
228 //- Destructor restores the original state of SIGFPE handler
229 ~ignore() { reset(); }
230
231 //- Restore the original state of SIGFPE handler
232 void reset()
233 {
234 if (wasActive_)
235 {
236 wasActive_ = false;
238 }
239 }
240
241 //- Same as reset()
242 void restore() { reset(); }
243 };
244};
245
246
247// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
249} // End namespace Foam
250
251// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
252
253#endif
254
255// ************************************************************************* //
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
Helper to locally ignore SIGFPE handling.
Definition sigFpe.H:237
ignore()
Constructor deactivates any previously active SIGFPE handler.
Definition sigFpe.H:268
ignore(const ignore &)=delete
No copy construct.
~ignore()
Destructor restores the original state of SIGFPE handler.
Definition sigFpe.H:281
ignore(ignore &&)=delete
No move construct.
void operator=(const ignore &)=delete
No copy assignment.
void operator=(ignore &&)=delete
No move assignment.
void reset()
Restore the original state of SIGFPE handler.
Definition sigFpe.H:286
void restore()
Same as reset().
Definition sigFpe.H:298
static void unset(bool verbose=false)
Deactivate SIGFPE handler and NaN memory initialisation.
static void set(bool verbose=false)
Activate SIGFPE handler when FOAM_SIGFPE is enabled. Activate fill memory with signaling_NaN when FOA...
~sigFpe()
Destructor calls unset() to deactivate the FPE signal handler as required.
static void fillNan(UList< double > &list)
Fill data block with (double) signaling_NaN values.
static bool requested()
Check if SIGFPE signals handler is to be enabled.
static void fillNan(UList< float > &list)
Fill data block with (float) signaling_NaN values.
static bool nanActive(bool on) noexcept
Set NaN memory initialisation on/off.
Definition sigFpe.H:171
static bool nanActive() noexcept
True if NaN memory initialisation is currently active.
Definition sigFpe.H:164
static bool active() noexcept
True if SIGFPE handling is currently active.
Definition sigFpe.H:159
static void fillNan(char *buf, size_t count)
Fill data block with signaling_NaN values. Does a reinterpret to Foam::scalar.
Definition sigFpe.H:209
static void fillNan_if(void *buf, size_t count)
Fill data block with signaling_NaN values if nanActive(). Does a reinterpret to Foam::scalar.
Definition sigFpe.H:193
sigFpe()
Constructor calls set() to activate the FPE signal handler if it was was not previously activate and ...
Namespace for OpenFOAM.
const direction noexcept
Definition scalarImpl.H:265
Typedefs for float/double/scalar without requiring scalar.H.