Skip to content

Commit

Permalink
Add MemoryAllocator and CAllocator (#1636)
Browse files Browse the repository at this point in the history
  • Loading branch information
jslee02 authored Dec 23, 2021
1 parent 2507c72 commit 09935e5
Show file tree
Hide file tree
Showing 10 changed files with 583 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +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 MemoryAllocator and CAllocator: [#1636](https://github.com/dartsim/dart/pull/1636)

* Dynamics

Expand Down
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ option(DART_ENABLE_SIMD
option(DART_BUILD_GUI_OSG "Build osgDart library" ON)
option(DART_BUILD_EXTRAS "Build extra projects" OFF)
option(DART_CODECOV "Turn on codecov support" OFF)
option(DART_TREAT_WARNINGS_AS_ERRORS "Treat warnings as errors" OFF)
option(DART_FAST_DEBUG "Add -O1 option for DEBUG mode build" OFF)
# GCC and Clang add ANSI-formatted colors when they detect the output medium is a
# terminal. However, this doesn't work in some cases such as when the makefile is
Expand Down Expand Up @@ -170,6 +169,12 @@ else()
endif()
set_property(CACHE DART_ACTIVE_LOG_LEVEL PROPERTY STRINGS TRACE DEBUG INFO WARN ERROR FATAL OFF)

if(BUILD_TYPE_DEBUG)
option(DART_TREAT_WARNINGS_AS_ERRORS "Treat warnings as errors" OFF)
else()
option(DART_TREAT_WARNINGS_AS_ERRORS "Treat warnings as errors" ON)
endif()

#===============================================================================
# Find dependencies
#===============================================================================
Expand Down
145 changes: 145 additions & 0 deletions dart/common/CAllocator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* Copyright (c) 2011-2021, The DART development contributors
* All rights reserved.
*
* The list of contributors can be found at:
* https://github.com/dartsim/dart/blob/master/LICENSE
*
* This file is provided under the following "BSD-style" License:
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#include "dart/common/CAllocator.hpp"

#include "dart/common/Logging.hpp"

namespace dart::common {

//==============================================================================
CAllocator::CAllocator() noexcept
{
// Do nothing
}

//==============================================================================
CAllocator::~CAllocator()
{
#ifndef NDEBUG
std::lock_guard<std::mutex> lock(m_mutex);
if (!m_map_pointer_to_size.empty())
{
size_t total_size = 0;
for (auto it : m_map_pointer_to_size)
{
void* pointer = it.first;
size_t size = it.second;
total_size += size;
DART_FATAL("Found memory leak of {} bytes at {}!", size, pointer);
}
DART_FATAL("Found potential memory leak of total {} bytes!", total_size);
}
#endif
}

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

DART_TRACE("Allocated {} bytes.", size);
#ifndef NDEBUG
std::lock_guard<std::mutex> lock(m_mutex);
auto new_ptr = std::malloc(size);
if (new_ptr)
{
m_size += size;
m_peak = std::max(m_peak, m_size);
m_map_pointer_to_size[new_ptr] = size;
}
return new_ptr;
#else
return std::malloc(size);
#endif
}

//==============================================================================
void CAllocator::deallocate(void* pointer, size_t size)
{
(void)size;
#ifndef NDEBUG
std::lock_guard<std::mutex> lock(m_mutex);
auto it = m_map_pointer_to_size.find(pointer);
if (it != m_map_pointer_to_size.end())
{
auto allocated_size = it->second;
if (size != allocated_size)
{
DART_FATAL(
"Cannot deallocated memory {} because the deallocating size {} is "
"different from the allocated size {}.",
pointer,
size,
allocated_size);
return;
}
m_size -= size;
m_map_pointer_to_size.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
std::free(pointer);
}

//==============================================================================
void CAllocator::print(std::ostream& os, int indent) const
{
if (indent == 0)
{
os << "[CAllocator]\n";
}
const std::string spaces(indent, ' ');
if (indent != 0)
{
os << spaces << "type: " << getType() << "\n";
}
#ifndef NDEBUG
std::lock_guard<std::mutex> lock(m_mutex);
os << spaces << "size_in_bytes: " << m_size << "\n";
os << spaces << "peak: " << m_peak << "\n";
#endif
}

} // namespace dart::common
76 changes: 76 additions & 0 deletions dart/common/CAllocator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2011-2021, The DART development contributors
* All rights reserved.
*
* The list of contributors can be found at:
* https://github.com/dartsim/dart/blob/master/LICENSE
*
* This file is provided under the following "BSD-style" License:
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#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 {

class CAllocator : public MemoryAllocator
{
public:
/// Constructor
CAllocator() noexcept;

/// Destructor
~CAllocator() override;

DART_STRING_TYPE(CAllocator);

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

// Documentation inherited
void deallocate(void* pointer, size_t size) override;

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

#ifndef NDEBUG
private:
size_t m_size = 0;
size_t m_peak = 0;
std::unordered_map<void*, size_t> m_map_pointer_to_size;
mutable std::mutex m_mutex;
#endif
};

} // namespace dart::common

#endif // DART_COMMON_CALLOCATOR_HPP_
16 changes: 16 additions & 0 deletions dart/common/Castable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,22 @@
#ifndef DART_COMMON_CASTABLE_HPP_
#define DART_COMMON_CASTABLE_HPP_

#include <string>

#define DART_STRING_TYPE(type_name) \
/** Returns type string. */ \
[[nodiscard]] static const std::string& getStaticType() \
{ \
static const std::string type = #type_name; \
return type; \
} \
\
[[nodiscard]] const std::string& getType() const override \
{ \
return getStaticType(); \
} \
void _ANONYMOUS_FUNCTION_1()

namespace dart::common {

/// A CRTP base class that provides an interface for easily casting to the
Expand Down
65 changes: 65 additions & 0 deletions dart/common/MemoryAllocator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2011-2021, The DART development contributors
* All rights reserved.
*
* The list of contributors can be found at:
* https://github.com/dartsim/dart/blob/master/LICENSE
*
* This file is provided under the following "BSD-style" License:
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#include "dart/common/MemoryAllocator.hpp"

#include "dart/common/CAllocator.hpp"
#include "dart/common/Logging.hpp"

namespace dart::common {

//==============================================================================
MemoryAllocator& MemoryAllocator::GetDefault()
{
static CAllocator default_allocator;
return default_allocator;
}

//==============================================================================
void MemoryAllocator::print(std::ostream& os, int indent) const
{
if (indent == 0)
{
os << "[*::print is not implemented]\n";
}
const std::string spaces(indent, ' ');
os << spaces << "*::print is not implemented:\n";
}

//==============================================================================
std::ostream& operator<<(std::ostream& os, const MemoryAllocator& allocator)
{
allocator.print(os);
return os;
}

} // namespace dart::common
Loading

0 comments on commit 09935e5

Please sign in to comment.