sigFpe.C
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-2015 OpenFOAM Foundation
9 Copyright (C) 2011 Symscape
10 Copyright (C) 2016-2021 OpenCFD Ltd.
11-------------------------------------------------------------------------------
12License
13 This file is part of OpenFOAM.
14
15 OpenFOAM is free software: you can redistribute it and/or modify it
16 under the terms of the GNU General Public License as published by
17 the Free Software Foundation, either version 3 of the License, or
18 (at your option) any later version.
19
20 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
21 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
27
28\*---------------------------------------------------------------------------*/
29
30#include "sigFpe.H"
31#include "error.H"
32#include "JobInfo.H"
33#include "OSspecific.H"
34#include "IOstreams.H"
35#include "List.H"
36#include "Switch.H"
37
38#include <float.h> // For *fp functions
39#include <limits>
40
41// File-local functions
42#include "signalMacros.C"
43
44
45// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
46
47bool Foam::sigFpe::switchFpe_(Foam::debug::optimisationSwitch("trapFpe", 0));
48bool Foam::sigFpe::switchNan_(Foam::debug::optimisationSwitch("setNaN", 0));
49
50bool Foam::sigFpe::sigActive_ = false;
51bool Foam::sigFpe::nanActive_ = false;
52
53// Saved old FPE signal trapping setting (file-local variable)
54static unsigned int oldFpe_ = 0u;
55
56
57static void clearFpe()
58{
59 #ifndef Foam_no_sigFpe
60 _clearfp();
61 _controlfp(oldFpe_, 0xFFFFFFFF);
62 #endif
63}
64
65
66// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
67
68// Can turn on/off via env variable containing a bool (true|false|on|off ...)
69// or by the specified flag
70static bool isTrue(const char* envName, bool deflt)
71{
73
74 if (sw.good())
75 {
76 return static_cast<bool>(sw);
77 }
78
79 // Env was not set or did not contain a valid bool value
80 return deflt;
81}
82
83
84// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
85
86void Foam::sigFpe::sigHandler(int)
87{
88 resetHandler("SIGFPE", SIGFPE);
89
90 JobInfo::shutdown(); // From running -> finished
92 clearFpe();
93 ::raise(SIGFPE); // Throw signal (to old handler)
94}
95
96
97// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
98
100{
101 set(false);
102}
103
104
106:
107 wasActive_(sigFpe::active())
108{
109 if (wasActive_)
110 {
112 }
113}
114
115
116// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
117
119{
120 unset(false);
121}
122
123
125{
126 restore();
127}
128
129
130// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
131
133{
134 if (wasActive_)
135 {
136 sigFpe::set();
137 }
138 wasActive_ = false;
139}
140
141
143{
144 return isTrue("FOAM_SIGFPE", switchFpe_);
145}
146
147
148void Foam::sigFpe::set(bool verbose)
149{
150 if (!sigActive_ && requested())
151 {
152 #ifdef Foam_no_sigFpe
153
154 if (verbose)
155 {
156 Info<< "trapFpe: Floating point exception trapping ";
157 Info<< "- disabled on this platform" << endl;
158 }
159
160 #else
161
162 oldFpe_ = _controlfp(0, 0);
163
164 const unsigned int newFpe =
165 (
166 oldFpe_ & ~(_EM_ZERODIVIDE | _EM_INVALID | _EM_OVERFLOW)
167 );
168
169 _controlfp(newFpe, _MCW_EM);
170
171 setHandler("SIGFPE", SIGFPE, sigHandler);
172
173 sigActive_ = true;
174
175 if (verbose)
176 {
177 Info<< "trapFpe: Floating point exception trapping ";
178
179 if (sigActive_)
180 {
181 Info<< "enabled (FOAM_SIGFPE)." << endl;
182 }
183 else
184 {
185 Info<< "- not supported on this platform" << endl;
186 }
187 }
188 #endif
189 }
190
191
192 nanActive_ = false;
193 if (isTrue("FOAM_SETNAN", switchNan_))
194 {
195 if (verbose)
196 {
197 Info<< "setNaN : Initialise allocated memory to NaN "
198 << "- not supported on this platform" << endl;
199 }
200 }
201}
202
203
204void Foam::sigFpe::unset(bool verbose)
205{
206 if (sigActive_)
207 {
208 if (verbose)
209 {
210 Info<< "sigFpe : Disabling floating point exception trapping"
211 << endl;
212 }
213
214 sigActive_ = false;
215
216 clearFpe();
217
218 resetHandler("SIGFPE", SIGFPE);
219 }
220
221 nanActive_ = false;
222}
223
224
226{
227 list = std::numeric_limits<scalar>::signaling_NaN();
228}
229
230
231// ************************************************************************* //
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
static bool isTrue(const char *envName, bool deflt)
Definition: sigFpe.C:70
static void clearFpe()
Definition: sigFpe.C:57
static unsigned int oldFpe_
Definition: sigFpe.C:54
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
File-local code for setting/resetting signal handlers.
static void shutdown()
Simple shutdown (finalize) of JobInfo.
Definition: JobInfo.C:98
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:78
bool good() const noexcept
True if the Switch represents a valid enumeration.
Definition: Switch.C:300
static Switch find(const std::string &str)
Definition: Switch.C:151
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:94
static void printStack(Ostream &os)
Helper function to print a stack.
ignore()
Constructor deactivates any previously active SIGFPE handler.
Definition: sigFpe.C:105
~ignore()
Destructor restores the original state of SIGFPE handler.
Definition: sigFpe.C:124
void restore()
Restore the original state of SIGFPE handler.
Definition: sigFpe.C:132
Set up trapping for floating point exceptions (signal FPE).
Definition: sigFpe.H:74
static void fillNan(UList< scalar > &list)
Fill data block with NaN values.
Definition: sigFpe.C:225
static void unset(bool verbose=false)
Deactivate SIGFPE signal handler and NaN memory initialisation.
Definition: sigFpe.C:204
static bool requested()
Check if SIGFPE signals handler is to be enabled.
Definition: sigFpe.C:142
static const triad unset
Definition: triad.H:97
bool set() const
Are all the vector set.
Definition: triadI.H:76
int optimisationSwitch(const char *name, const int deflt=0)
Lookup optimisation switch or add default value.
Definition: debug.C:237
string getEnv(const std::string &envName)
Get environment value for given envName.
Definition: MSwindows.C:371
prefixOSstream Perr
OSstream wrapped stderr (std::cerr) with parallel prefix.
static void setHandler(const char *what, int sigNum, void(*handler)(int))
Definition: signalMacros.C:61
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
static void resetHandler(const char *what, int sigNum)
Definition: signalMacros.C:46