Skip to content
Snippets Groups Projects
Commit b66369fb authored by Mark OLESEN's avatar Mark OLESEN
Browse files

ENH: add sigFpe::fillNan(char* buf, size_t count)

- simplifies use with other allocators (eg, memory pools).
  Can also be used with other containers.

  vectorField fld = ...;
  sigFpe::fillNan(fld.data_bytes(), fld.size_bytes());

COMP: inline sigFpe::ignore helper class

- now unused (may be removed in the future), but can avoid compiling
  code for it

COMP: missing sigStopAtWriteNow() definition for MSwindows
parent b236e149
No related branches found
No related tags found
No related merge requests found
......@@ -7,7 +7,7 @@
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2011 Symscape
Copyright (C) 2016-2021 OpenCFD Ltd.
Copyright (C) 2016-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -36,6 +36,7 @@ License
#include "Switch.H"
#include <float.h> // For *fp functions
#include <algorithm>
#include <limits>
// File-local functions
......@@ -98,18 +99,7 @@ void Foam::sigFpe::sigHandler(int)
Foam::sigFpe::sigFpe()
{
set(false);
}
Foam::sigFpe::ignore::ignore()
:
wasActive_(sigFpe::active())
{
if (wasActive_)
{
sigFpe::unset();
}
set(false); // false = non-verbose
}
......@@ -117,28 +107,12 @@ Foam::sigFpe::ignore::ignore()
Foam::sigFpe::~sigFpe()
{
unset(false);
}
Foam::sigFpe::ignore::~ignore()
{
restore();
unset(false); // false = non-verbose
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::sigFpe::ignore::restore()
{
if (wasActive_)
{
sigFpe::set();
}
wasActive_ = false;
}
bool Foam::sigFpe::requested()
{
return isTrue("FOAM_SIGFPE", switchFpe_);
......@@ -153,8 +127,8 @@ void Foam::sigFpe::set(bool verbose)
if (verbose)
{
Info<< "trapFpe: Floating point exception trapping ";
Info<< "- disabled on this platform" << endl;
Info<< "trapFpe: Floating point exception trapping "
<< "- disabled on this platform" << endl;
}
#else
......@@ -194,7 +168,7 @@ void Foam::sigFpe::set(bool verbose)
{
if (verbose)
{
Info<< "setNaN : Initialise allocated memory to NaN "
Info<< "setNaN : Fill allocated memory with NaN "
<< "- not supported on this platform" << endl;
}
}
......@@ -222,9 +196,37 @@ void Foam::sigFpe::unset(bool verbose)
}
void Foam::sigFpe::fillNan(char* buf, size_t count)
{
if (!buf || !count) return;
// Fill with signaling_NaN
const scalar val = std::numeric_limits<scalar>::signaling_NaN();
// Can dispatch with
// - std::execution::parallel_unsequenced_policy
// - std::execution::unsequenced_policy
std::fill_n
(
reinterpret_cast<scalar*>(buf), (count/sizeof(scalar)), val
);
}
void Foam::sigFpe::fillNan(UList<scalar>& list)
{
list = std::numeric_limits<scalar>::signaling_NaN();
if (list.empty()) return;
// Fill with signaling_NaN
const scalar val = std::numeric_limits<scalar>::signaling_NaN();
// Can dispatch with
// - std::execution::parallel_unsequenced_policy
// - std::execution::unsequenced_policy
std::fill_n
(
list.data(), list.size(), val
);
}
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2019 OpenCFD Ltd.
Copyright (C) 2018-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -57,7 +57,7 @@ SourceFiles
#ifndef Foam_sigFpe_H
#define Foam_sigFpe_H
#include <cstddef> // for std::size_t
#include <cstddef> // For std::size_t
#include "scalarFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -87,7 +87,7 @@ class sigFpe
//- Floating point trapping currently active?
static bool sigActive_;
//- Flag to indicate mallocNan is currently active
//- Is NaN memory initialisation currently active?
static bool nanActive_;
......@@ -124,18 +124,21 @@ public:
//- True if NaN memory initialisation is currently active.
static bool nanActive() noexcept { return nanActive_; }
//- Activate SIGFPE signal handler when FOAM_SIGFPE is %set
// Fill memory with NaN when FOAM_SETNAN is %set
//- Activate SIGFPE handler when FOAM_SIGFPE is enabled.
//- Activate fill memory with signaling_NaN when FOAM_SETNAN is enabled
static void set(bool verbose=false);
//- Deactivate SIGFPE signal handler and NaN memory initialisation
//- Deactivate SIGFPE handler and NaN memory initialisation
static void unset(bool verbose=false);
//- Fill data block with NaN values
//- Fill data block with signaling_NaN values
static void fillNan(char* buf, size_t count);
//- Fill data block with signaling_NaN values
static void fillNan(UList<scalar>& list);
// Helper classes
// Helpers
//- Helper to locally ignore SIGFPE handling.
// Restores the original state of the SIGFPE handler on destruction.
......@@ -144,29 +147,46 @@ public:
//- The signal handler state when entering
bool wasActive_;
public:
//- No copy construct
ignore(const ignore&) = delete;
//- No copy assignment
void operator=(const ignore&) = delete;
//- No move construct
ignore(ignore&&) = delete;
//- No copy assignment
void operator=(const ignore&) = delete;
//- No move assignment
void operator=(ignore&&) = delete;
public:
//- Constructor deactivates any previously active SIGFPE handler
ignore();
ignore()
:
wasActive_(Foam::sigFpe::active())
{
if (wasActive_)
{
Foam::sigFpe::unset();
}
}
//- Destructor restores the original state of SIGFPE handler
~ignore();
~ignore() { reset(); }
//- Restore the original state of SIGFPE handler
void restore();
void reset()
{
if (wasActive_)
{
wasActive_ = false;
Foam::sigFpe::set();
}
}
//- Same as reset()
void restore() { reset(); }
};
};
......
......@@ -77,7 +77,7 @@ public:
// Constructors
//- Default construct
sigStopAtWriteNow();
sigStopAtWriteNow() noexcept = default;
//- Construct with Time reference
explicit sigStopAtWriteNow(const Time& runTime, bool verbose=false);
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2016-2021 OpenCFD Ltd.
Copyright (C) 2016-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -33,12 +33,12 @@ License
#include "IOstreams.H"
#include "UList.H"
#include "Switch.H"
#include <algorithm>
#include <limits>
// File-local functions
#include "signalMacros.C"
#include <limits>
#if defined(__linux__) && defined(__GNUC__)
#ifndef __USE_GNU
#define __USE_GNU // To use feenableexcept()
......@@ -85,32 +85,32 @@ extern "C"
{
extern void* __libc_malloc(size_t size);
// Override the GLIBC malloc to support mallocNan
// Override the GLIBC malloc to support filling with NaN
void* malloc(size_t size)
{
// Call the low-level GLIBC malloc function
void* ptr = __libc_malloc(size);
if (Foam::sigFpe::nanActive())
{
return Foam::sigFpe::mallocNan(size);
// Fill with signaling_NaN
const auto val = std::numeric_limits<Foam::scalar>::signaling_NaN();
// Can dispatch with
// - std::execution::parallel_unsequenced_policy
// - std::execution::unsequenced_policy
std::fill_n
(
reinterpret_cast<Foam::scalar*>(ptr),
(size/sizeof(Foam::scalar)),
val
);
}
else
{
return __libc_malloc(size);
}
}
}
void* Foam::sigFpe::mallocNan(size_t size)
{
// Call the low-level GLIBC malloc function
void* result = __libc_malloc(size);
// Initialize to signalling NaN
UList<scalar> list(reinterpret_cast<scalar*>(result), size/sizeof(scalar));
sigFpe::fillNan(list);
return ptr;
}
} // End extern C
return result;
}
#endif // __linux__
......@@ -134,18 +134,7 @@ void Foam::sigFpe::sigHandler(int)
Foam::sigFpe::sigFpe()
{
set(false);
}
Foam::sigFpe::ignore::ignore()
:
wasActive_(sigFpe::active())
{
if (wasActive_)
{
sigFpe::unset();
}
set(false); // false = non-verbose
}
......@@ -153,28 +142,12 @@ Foam::sigFpe::ignore::ignore()
Foam::sigFpe::~sigFpe()
{
unset(false);
}
Foam::sigFpe::ignore::~ignore()
{
restore();
unset(false); // false = non-verbose
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::sigFpe::ignore::restore()
{
if (wasActive_)
{
sigFpe::set();
}
wasActive_ = false;
}
bool Foam::sigFpe::requested()
{
return isTrue("FOAM_SIGFPE", switchFpe_);
......@@ -224,7 +197,7 @@ void Foam::sigFpe::set(bool verbose)
if (verbose)
{
Info<< "setNaN : Initialise allocated memory to NaN ";
Info<< "setNaN : Fill allocated memory with NaN ";
if (nanActive_)
{
......@@ -275,9 +248,37 @@ void Foam::sigFpe::unset(bool verbose)
}
void Foam::sigFpe::fillNan(char* buf, size_t count)
{
if (!buf || !count) return;
// Fill with signaling_NaN
const auto val = std::numeric_limits<scalar>::signaling_NaN();
// Can dispatch with
// - std::execution::parallel_unsequenced_policy
// - std::execution::unsequenced_policy
std::fill_n
(
reinterpret_cast<scalar*>(buf), (count/sizeof(scalar)), val
);
}
void Foam::sigFpe::fillNan(UList<scalar>& list)
{
list = std::numeric_limits<scalar>::signaling_NaN();
if (list.empty()) return;
// Fill with signaling_NaN
const auto val = std::numeric_limits<scalar>::signaling_NaN();
// Can dispatch with
// - std::execution::parallel_unsequenced_policy
// - std::execution::unsequenced_policy
std::fill_n
(
list.data(), list.size(), val
);
}
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2019 OpenCFD Ltd.
Copyright (C) 2018-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -57,7 +57,7 @@ SourceFiles
#ifndef Foam_sigFpe_H
#define Foam_sigFpe_H
#include <cstddef> // for std::size_t
#include <cstddef> // For std::size_t
#include "scalarFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -87,7 +87,7 @@ class sigFpe
//- Floating point trapping currently active?
static bool sigActive_;
//- Flag to indicate mallocNan is currently active
//- Is NaN memory initialisation currently active?
static bool nanActive_;
......@@ -124,23 +124,21 @@ public:
//- True if NaN memory initialisation is currently active.
static bool nanActive() noexcept { return nanActive_; }
//- Activate SIGFPE signal handler when FOAM_SIGFPE is %set
// Fill memory with NaN when FOAM_SETNAN is %set
//- Activate SIGFPE handler when FOAM_SIGFPE is enabled.
//- Activate fill memory with signaling_NaN when FOAM_SETNAN is enabled
static void set(bool verbose=false);
//- Deactivate SIGFPE signal handler and NaN memory initialisation
//- Deactivate SIGFPE handler and NaN memory initialisation
static void unset(bool verbose=false);
#ifdef __linux__
//- Malloc function which initializes to NaN
static void* mallocNan(size_t size);
#endif
//- Fill data block with signaling_NaN values
static void fillNan(char* buf, size_t count);
//- Fill data block with NaN values
//- Fill data block with signaling_NaN values
static void fillNan(UList<scalar>& list);
// Helper classes
// Helpers
//- Helper to locally ignore SIGFPE handling.
// Restores the original state of the SIGFPE handler on destruction.
......@@ -149,29 +147,46 @@ public:
//- The signal handler state when entering
bool wasActive_;
public:
//- No copy construct
ignore(const ignore&) = delete;
//- No copy assignment
void operator=(const ignore&) = delete;
//- No move construct
ignore(ignore&&) = delete;
//- No copy assignment
void operator=(const ignore&) = delete;
//- No move assignment
void operator=(ignore&&) = delete;
public:
//- Constructor deactivates any previously active SIGFPE handler
ignore();
ignore()
:
wasActive_(Foam::sigFpe::active())
{
if (wasActive_)
{
Foam::sigFpe::unset();
}
}
//- Destructor restores the original state of SIGFPE handler
~ignore();
~ignore() { reset(); }
//- Restore the original state of SIGFPE handler
void restore();
void reset()
{
if (wasActive_)
{
wasActive_ = false;
Foam::sigFpe::set();
}
}
//- Same as reset()
void restore() { reset(); }
};
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment