Skip to content

Commit

Permalink
Make allocate API threadsafe when needed
Browse files Browse the repository at this point in the history
  • Loading branch information
mcfadden8 committed Jul 20, 2023
1 parent 1e5ef60 commit 3229bc5
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/umpire/Allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "umpire/Allocator.hpp"

#include "umpire/ResourceManager.hpp"
#include "umpire/strategy/ThreadSafeAllocator.hpp"
#include "umpire/util/Macros.hpp"

namespace umpire {
Expand All @@ -17,6 +18,15 @@ Allocator::Allocator(strategy::AllocationStrategy* allocator) noexcept
m_allocator{allocator},
m_tracking{allocator->isTracked()}
{
// Hack: If the strategy for this allocator requires thread safety,
// we create a mutex to be used during allocation operations
//
if (dynamic_cast<umpire::strategy::ThreadSafeAllocator*>(allocator) != nullptr) {
m_mutex = new std::mutex; // Management of pointer TBD
}
else {
m_mutex = nullptr;
}
}

void Allocator::release()
Expand Down
7 changes: 7 additions & 0 deletions src/umpire/Allocator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <cstddef>
#include <memory>
#include <mutex>
#include <ostream>
#include <string>

Expand Down Expand Up @@ -199,6 +200,12 @@ class Allocator : private strategy::mixins::Inspector, strategy::mixins::Allocat
umpire::strategy::AllocationStrategy* m_allocator;

bool m_tracking{true};

/*!
* \brief Mutex to be used for AllocationStrategys that
* require thread safety
*/
std::mutex* m_mutex;
};

inline std::string to_string(const Allocator& a)
Expand Down
18 changes: 18 additions & 0 deletions src/umpire/Allocator.inl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ inline void* Allocator::allocate(std::size_t bytes)

UMPIRE_LOG(Debug, "(" << bytes << ")");

if (m_mutex != nullptr)
m_mutex->lock();

if (0 == bytes) {
ret = allocateNull();
} else {
Expand All @@ -32,6 +35,8 @@ inline void* Allocator::allocate(std::size_t bytes)
} catch (umpire::out_of_memory_error& e) {
e.set_allocator_id(this->getId());
e.set_requested_size(bytes);
if (m_mutex != nullptr)
m_mutex->unlock();
throw;
}
}
Expand All @@ -40,6 +45,9 @@ inline void* Allocator::allocate(std::size_t bytes)
registerAllocation(ret, bytes, m_allocator);
}

if (m_mutex != nullptr)
m_mutex->unlock();

umpire::event::record<umpire::event::allocate>(
[&](auto& event) { event.size(bytes).ref((void*)m_allocator).ptr(ret); });

Expand All @@ -54,6 +62,9 @@ inline void* Allocator::allocate(const std::string& name, std::size_t bytes)

UMPIRE_LOG(Debug, "(" << bytes << ")");

if (m_mutex != nullptr)
m_mutex->lock();

if (0 == bytes) {
ret = allocateNull();
} else {
Expand All @@ -64,6 +75,9 @@ inline void* Allocator::allocate(const std::string& name, std::size_t bytes)
registerAllocation(ret, bytes, m_allocator, name);
}

if (m_mutex != nullptr)
m_mutex->unlock();

umpire::event::record<umpire::event::named_allocate>(
[&](auto& event) { event.name(name).size(bytes).ref((void*)m_allocator).ptr(ret); });
return ret;
Expand All @@ -79,6 +93,8 @@ inline void Allocator::deallocate(void* ptr)
UMPIRE_LOG(Info, "Deallocating a null pointer (This behavior is intentionally allowed and ignored)");
return;
} else {
if (m_mutex != nullptr)
m_mutex->lock();
if (m_tracking) {
auto record = deregisterAllocation(ptr, m_allocator);
if (!deallocateNull(ptr)) {
Expand All @@ -89,6 +105,8 @@ inline void Allocator::deallocate(void* ptr)
m_allocator->deallocate(ptr);
}
}
if (m_mutex != nullptr)
m_mutex->unlock();
}
}

Expand Down

0 comments on commit 3229bc5

Please sign in to comment.