2018-12-14 12:06:02 -05:00
|
|
|
#ifndef OPENMC_OPENMP_INTERFACE_H
|
|
|
|
|
#define OPENMC_OPENMP_INTERFACE_H
|
|
|
|
|
|
|
|
|
|
#ifdef _OPENMP
|
|
|
|
|
#include <omp.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
namespace openmc {
|
|
|
|
|
|
2023-12-18 21:31:29 -06:00
|
|
|
//==============================================================================
|
|
|
|
|
//! Accessor functions related to number of threads and thread number
|
|
|
|
|
//==============================================================================
|
|
|
|
|
inline int num_threads()
|
|
|
|
|
{
|
|
|
|
|
#ifdef _OPENMP
|
|
|
|
|
return omp_get_max_threads();
|
|
|
|
|
#else
|
|
|
|
|
return 1;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline int thread_num()
|
|
|
|
|
{
|
|
|
|
|
#ifdef _OPENMP
|
|
|
|
|
return omp_get_thread_num();
|
|
|
|
|
#else
|
|
|
|
|
return 0;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-14 12:06:02 -05:00
|
|
|
//==============================================================================
|
2018-12-15 15:34:00 -05:00
|
|
|
//! An object used to prevent concurrent access to a piece of data.
|
|
|
|
|
//
|
|
|
|
|
//! This type meets the C++ "Lockable" requirements.
|
|
|
|
|
//==============================================================================
|
2018-12-14 12:06:02 -05:00
|
|
|
|
2018-12-29 12:54:29 -05:00
|
|
|
class OpenMPMutex {
|
2018-12-14 12:06:02 -05:00
|
|
|
public:
|
2025-02-11 11:23:26 -06:00
|
|
|
void init()
|
2018-12-15 15:34:00 -05:00
|
|
|
{
|
2020-04-21 21:08:02 +00:00
|
|
|
#ifdef _OPENMP
|
2018-12-15 15:34:00 -05:00
|
|
|
omp_init_lock(&mutex_);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2018-12-14 12:06:02 -05:00
|
|
|
|
2025-02-11 11:23:26 -06:00
|
|
|
OpenMPMutex() { init(); }
|
|
|
|
|
|
2018-12-29 12:54:29 -05:00
|
|
|
~OpenMPMutex()
|
2018-12-15 15:34:00 -05:00
|
|
|
{
|
2020-04-21 21:08:02 +00:00
|
|
|
#ifdef _OPENMP
|
2018-12-15 15:34:00 -05:00
|
|
|
omp_destroy_lock(&mutex_);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2018-12-14 12:06:02 -05:00
|
|
|
|
2023-12-04 12:08:47 -06:00
|
|
|
// omp_lock_t objects cannot be deep copied, they can only be shallow
|
|
|
|
|
// copied. Thus, while shallow copying of an omp_lock_t object is
|
|
|
|
|
// completely valid (provided no race conditions exist), true copying
|
|
|
|
|
// of an OpenMPMutex object is not valid due to the action of the
|
|
|
|
|
// destructor. However, since locks are fungible, we can simply replace
|
|
|
|
|
// copying operations with default construction. This allows storage of
|
|
|
|
|
// OpenMPMutex objects within containers that may need to move/copy them
|
|
|
|
|
// (e.g., std::vector). It is left to the caller to understand that
|
|
|
|
|
// copying of OpenMPMutex does not produce two handles to the same mutex,
|
|
|
|
|
// rather, it produces two different mutexes.
|
|
|
|
|
|
|
|
|
|
// Copy constructor
|
2025-02-11 11:23:26 -06:00
|
|
|
OpenMPMutex(const OpenMPMutex& other) { init(); }
|
2023-12-04 12:08:47 -06:00
|
|
|
|
|
|
|
|
// Copy assignment operator
|
2025-02-11 11:23:26 -06:00
|
|
|
OpenMPMutex& operator=(const OpenMPMutex& other) { return *this; }
|
2018-12-15 15:34:00 -05:00
|
|
|
|
|
|
|
|
//! Lock the mutex.
|
|
|
|
|
//
|
|
|
|
|
//! This function blocks execution until the lock succeeds.
|
2018-12-14 12:06:02 -05:00
|
|
|
void lock()
|
2018-12-15 15:34:00 -05:00
|
|
|
{
|
2020-04-21 21:08:02 +00:00
|
|
|
#ifdef _OPENMP
|
2018-12-15 15:34:00 -05:00
|
|
|
omp_set_lock(&mutex_);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2018-12-14 12:06:02 -05:00
|
|
|
|
2018-12-15 15:34:00 -05:00
|
|
|
//! Try to lock the mutex and indicate success.
|
|
|
|
|
//
|
|
|
|
|
//! This function does not block. It returns immediately and gives false if
|
|
|
|
|
//! the lock is unavailable.
|
|
|
|
|
bool try_lock() noexcept
|
|
|
|
|
{
|
2020-04-21 21:08:02 +00:00
|
|
|
#ifdef _OPENMP
|
2018-12-15 15:34:00 -05:00
|
|
|
return omp_test_lock(&mutex_);
|
|
|
|
|
#else
|
|
|
|
|
return true;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2018-12-14 12:06:02 -05:00
|
|
|
|
2018-12-15 15:34:00 -05:00
|
|
|
//! Unlock the mutex.
|
|
|
|
|
void unlock() noexcept
|
|
|
|
|
{
|
2020-04-21 21:08:02 +00:00
|
|
|
#ifdef _OPENMP
|
2018-12-15 15:34:00 -05:00
|
|
|
omp_unset_lock(&mutex_);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2018-12-14 12:06:02 -05:00
|
|
|
|
|
|
|
|
private:
|
2020-04-21 21:08:02 +00:00
|
|
|
#ifdef _OPENMP
|
2018-12-15 15:34:00 -05:00
|
|
|
omp_lock_t mutex_;
|
|
|
|
|
#endif
|
2018-12-14 12:06:02 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace openmc
|
|
|
|
|
#endif // OPENMC_OPENMP_INTERFACE_H
|