Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MemoryManager and MemoryAllocatorDebugger #1646

Merged
merged 1 commit into from
Jan 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

* Added Castable class: [#1634](https://github.com/dartsim/dart/pull/1634)
* Added spdlog support as underlying logging framework: [#1633](https://github.com/dartsim/dart/pull/1633)
* Added custom memory allocators: [#1636](https://github.com/dartsim/dart/pull/1636), [#1637](https://github.com/dartsim/dart/pull/1637), [#1639](https://github.com/dartsim/dart/pull/1639), [#1645](https://github.com/dartsim/dart/pull/1645)
* Added custom memory allocators: [#1636](https://github.com/dartsim/dart/pull/1636), [#1637](https://github.com/dartsim/dart/pull/1637), [#1639](https://github.com/dartsim/dart/pull/1639), [#1645](https://github.com/dartsim/dart/pull/1645), [#1646](https://github.com/dartsim/dart/pull/1646)
* Added Stopwatch class to replace Timer: [#1638](https://github.com/dartsim/dart/pull/1638)

* Dynamics
Expand Down
109 changes: 8 additions & 101 deletions dart/common/CAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,117 +47,29 @@ CAllocator::CAllocator() noexcept
//==============================================================================
CAllocator::~CAllocator()
{
#ifndef NDEBUG
std::lock_guard<std::mutex> lock(mMutex);
if (!mMapPointerToSize.empty())
{
size_t totalSize = 0;
for (auto it : mMapPointerToSize)
{
void* pointer = it.first;
size_t size = it.second;
totalSize += size;
dterr << "Found memory leak of " << size << " bytes at " << pointer
<< "\n";
// TODO(JS): Change to DART_FATAL once the issue of calling spdlog in
// destructor is resolved.
}
dterr << "Found potential memory leak of total " << totalSize
<< " bytes!\n";
// TODO(JS): Change to DART_FATAL once the issue of calling spdlog in
// destructor is resolved.
}
#endif
// Do nothing
}

//==============================================================================
void* CAllocator::allocate(size_t size) noexcept
void* CAllocator::allocate(size_t bytes) noexcept
{
if (size == 0)
if (bytes == 0)
{
return nullptr;
}

DART_TRACE("Allocated {} bytes.", size);
#ifndef NDEBUG
std::lock_guard<std::mutex> lock(mMutex);
auto newPtr = std::malloc(size);
if (newPtr)
{
mSize += size;
mPeak = std::max(mPeak, mSize);
mMapPointerToSize[newPtr] = size;
}
return newPtr;
#else
return std::malloc(size);
#endif
DART_TRACE("Allocated {} bytes.", bytes);
return std::malloc(bytes);
}

//==============================================================================
void CAllocator::deallocate(void* pointer, size_t size)
void CAllocator::deallocate(void* pointer, size_t bytes)
{
(void)size;
#ifndef NDEBUG // debug
std::lock_guard<std::mutex> lock(mMutex);
auto it = mMapPointerToSize.find(pointer);
if (it != mMapPointerToSize.end())
{
auto allocatedSize = it->second;
if (size != allocatedSize)
{
DART_FATAL(
"Attempting to deallocate memory at {} of {} bytes that is different "
"from the allocated size {}, which is a critical bug. Deallocating "
"{} bytes.",
pointer,
size,
allocatedSize,
allocatedSize);
size = allocatedSize;
}
mSize -= size;
mMapPointerToSize.erase(it);
DART_TRACE("Deallocated {} bytes.", size);
}
else
{
DART_FATAL(
"Cannot deallocate memory {} that is not allocated by this allocator!",
pointer);
return;
}
#else
DART_TRACE("Deallocated.");
#endif
DART_UNUSED(bytes);
std::free(pointer);
DART_TRACE("Deallocated.");
}

#ifndef NDEBUG
//==============================================================================
bool CAllocator::isAllocated(void* pointer, size_t size) const noexcept
{
std::lock_guard<std::mutex> lock(mMutex);

const auto it = mMapPointerToSize.find(pointer);
if (it == mMapPointerToSize.end())
return false;

const auto& allocatedSize = it->second;
if (size != allocatedSize)
return false;

return true;
}

//==============================================================================
bool CAllocator::isEmpty() const noexcept
{
std::lock_guard<std::mutex> lock(mMutex);
return mMapPointerToSize.empty();
}
#endif

//==============================================================================
void CAllocator::print(std::ostream& os, int indent) const
{
Expand All @@ -170,11 +82,6 @@ void CAllocator::print(std::ostream& os, int indent) const
{
os << spaces << "type: " << getType() << "\n";
}
#ifndef NDEBUG
std::lock_guard<std::mutex> lock(mMutex);
os << spaces << "size_in_bytes: " << mSize << "\n";
os << spaces << "peak: " << mPeak << "\n";
#endif
}

} // namespace dart::common
26 changes: 2 additions & 24 deletions dart/common/CAllocator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@
#ifndef DART_COMMON_CALLOCATOR_HPP_
#define DART_COMMON_CALLOCATOR_HPP_

#ifndef NDEBUG
#include <mutex>
#include <unordered_map>
#endif

#include "dart/common/MemoryAllocator.hpp"

namespace dart::common {
Expand All @@ -56,30 +51,13 @@ class CAllocator : public MemoryAllocator
DART_STRING_TYPE(CAllocator);

// Documentation inherited
[[nodiscard]] void* allocate(size_t size) noexcept override;

// Documentation inherited
void deallocate(void* pointer, size_t size) override;
[[nodiscard]] void* allocate(size_t bytes) noexcept override;

#ifndef NDEBUG
// Documentation inherited
[[nodiscard]] bool isAllocated(void* pointer, size_t size) const
noexcept override;

// Documentation inherited
[[nodiscard]] bool isEmpty() const noexcept override;
#endif
void deallocate(void* pointer, size_t bytes) override;

// Documentation inherited
void print(std::ostream& os = std::cout, int indent = 0) const override;

#ifndef NDEBUG
private:
size_t mSize = 0;
size_t mPeak = 0;
std::unordered_map<void*, size_t> mMapPointerToSize;
mutable std::mutex mMutex;
#endif
};

} // namespace dart::common
Expand Down
Loading