Skip to content
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: 2 additions & 0 deletions src/include/OpenImageIO/imagecache.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ class OIIO_API ImageCache {
/// all files referenced by calls to the ImageCache. (The
/// array is of `ustring` or `char*`.)
///
/// - `int64 stat:cache_footprint` :
/// Total bytes used by image cache.
/// - `int64 stat:cache_memory_used` :
/// Total bytes used by tile cache.
///
Expand Down
20 changes: 20 additions & 0 deletions src/include/OpenImageIO/imageio.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <OpenImageIO/strutil.h>
#include <OpenImageIO/thread.h>
#include <OpenImageIO/typedesc.h>
#include <OpenImageIO/memory.h>

OIIO_NAMESPACE_BEGIN

Expand Down Expand Up @@ -1884,6 +1885,9 @@ class OIIO_API ImageInput {
std::unique_ptr<Impl, decltype(&impl_deleter)> m_impl;

void append_error(string_view message) const; // add to error message

/// declare a friend heapsize definition
template <typename T> friend size_t pvt::heapsize(const T&);
};


Expand Down Expand Up @@ -2788,10 +2792,26 @@ class OIIO_API ImageOutput {
std::unique_ptr<Impl, decltype(&impl_deleter)> m_impl;

void append_error(string_view message) const; // add to m_errmessage

/// declare a friend heapsize definition
template <typename T> friend size_t pvt::heapsize(const T&);
};



/// Memory tracking. Specializes the base memory tracking functions from memory.h.

// heapsize specialization for `ImageSpec`
template <> OIIO_API size_t pvt::heapsize<ImageSpec>(const ImageSpec&);

// heapsize specialization for `ImageInput`
template <> OIIO_API size_t pvt::heapsize<ImageInput>(const ImageInput&);

// heapsize specialization for `ImageOutput`
template <> OIIO_API size_t pvt::heapsize<ImageOutput>(const ImageOutput&);



// Utility functions

/// `OIIO::shutdown` prepares OpenImageIO for shutdown. Before exiting an
Expand Down
117 changes: 117 additions & 0 deletions src/include/OpenImageIO/memory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright Contributors to the OpenImageIO project.
// SPDX-License-Identifier: Apache-2.0
// https://github.com/AcademySoftwareFoundation/OpenImageIO


/////////////////////////////////////////////////////////////////////////
/// @file memory.h
///
/// @brief Utilities for memory tracking.
/////////////////////////////////////////////////////////////////////////


#pragma once

#define OPENIMAGEIO_MEMORY_H

#include <cstring>
#include <memory>
#include <vector>

OIIO_NAMESPACE_BEGIN

namespace pvt {

/// Return the total heap memory allocated by `object`.
/// The template specialization can be used to give improved results for non trivial types
/// that perform heap allocation, and to include members allocations recursively.
template<typename T>
inline size_t
heapsize(const T& t)
{
return 0;
}

/// Return the total memory footprint of `object`. If possible, including any heap
/// allocations done by any constituent parts. The default implementation just reduces
/// to sizeof(object), given that heapsize(object) would return 0.
/// The template specialization can be used to give improved results for non trivial types
/// that perform heap allocation.
template<typename T>
inline size_t
footprint(const T& t)
{
return sizeof(T) + heapsize(t);
}

template<typename T>
inline size_t
footprint(const T* t)
{
return sizeof(T) + (t ? footprint(*t) : 0);
}

/// Specializations for common STL types


// heapsize specialization for std::string
template<>
inline size_t
heapsize<std::string>(const std::string& s)
{
// accounts for small string optimization that does not
// use any heap allocations
const char* const sbegin = (const char*)&s;
const char* const send = sbegin + sizeof(std::string);
const char* const sdata = s.data();
const bool is_small = sdata >= sbegin && sdata < send;
return is_small ? 0 : s.capacity();
}

// heapsize specialization for std::vector
template<typename T>
inline size_t
heapsize(const std::vector<T>& vec)
{
size_t size = 0;
for (const T& elem : vec)
size += footprint(elem);
return size;
}

// heapsize specialization for std::shared_ptr
template<typename T>
inline size_t
heapsize(const std::shared_ptr<T>& ref)
{
return ref ? footprint(*ref.get()) : 0;
}

// footprint specialization for std::shared_ptr
template<typename T>
inline size_t
footprint(const std::shared_ptr<T>& ref)
{
return sizeof(std::shared_ptr<T>) + heapsize(ref);
}

// heapsize specialization for std::unique_ptr
template<typename T>
inline size_t
heapsize(const std::unique_ptr<T>& ref)
{
return ref ? footprint(*ref.get()) : 0;
}

// footprint specialization for std::unique_ptr
template<typename T>
inline size_t
footprint(const std::unique_ptr<T>& ref)
{
return sizeof(std::unique_ptr<T>) + heapsize(ref);
}

} // namespace pvt


OIIO_NAMESPACE_END
9 changes: 8 additions & 1 deletion src/include/OpenImageIO/paramlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include <OpenImageIO/attrdelegate.h>
#include <OpenImageIO/export.h>
#include <OpenImageIO/memory.h>
#include <OpenImageIO/strongparam.h>
#include <OpenImageIO/typedesc.h>
#include <OpenImageIO/ustring.h>
Expand Down Expand Up @@ -276,9 +277,15 @@ class OIIO_UTIL_API ParamValue {
Copy _copy = Copy(true),
FromUstring _from_ustring = FromUstring(false)) noexcept;
void clear_value() noexcept;
};

/// declare a friend heapsize definition
template<typename T> friend size_t pvt::heapsize(const T&);
};

/// heapsize specialization for `ParamValue`
template<>
OIIO_API size_t
pvt::heapsize<ParamValue>(const ParamValue&);

/// Factory for a ParamValue that holds a single value of any type supported
/// by a corresponding ParamValue constructor (such as int, float, string).
Expand Down
22 changes: 22 additions & 0 deletions src/include/OpenImageIO/refcnt.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include <OpenImageIO/atomic.h>
#include <OpenImageIO/dassert.h>
#include <OpenImageIO/memory.h>


OIIO_NAMESPACE_BEGIN
Expand Down Expand Up @@ -232,4 +233,25 @@ intrusive_ptr_release(T* x)
#define OIIO_REFCNT_HAS_RELEASE 1 /* intrusive_ptr::release() */


/// Memory tracking. Specializes the base memory tracking functions from memory.h.

// heapsize specialization for `intrusive_ptr`
namespace pvt {
template<typename T>
inline size_t
heapsize(const intrusive_ptr<T>& ref)
{
return ref ? footprint(*ref.get()) : 0;
}

// footprint specialization for `intrusive_ptr`
template<typename T>
inline size_t
footprint(const intrusive_ptr<T>& ref)
{
return sizeof(intrusive_ptr<T>) + heapsize(ref);
}
} // namespace pvt


OIIO_NAMESPACE_END
13 changes: 13 additions & 0 deletions src/libOpenImageIO/formatspec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1251,4 +1251,17 @@ ImageSpec::set_colorspace(string_view colorspace)
}



template<>
size_t
pvt::heapsize<ImageSpec>(const ImageSpec& is)
{
size_t size = pvt::heapsize(is.channelformats);
size += pvt::heapsize(is.channelnames);
size += pvt::heapsize(is.extra_attribs);
return size;
}



OIIO_NAMESPACE_END
13 changes: 13 additions & 0 deletions src/libOpenImageIO/imageinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1337,4 +1337,17 @@ ImageInput::check_open(const ImageSpec& spec, ROI range, uint64_t /*flags*/)
return true; // all is ok
}



template<>
size_t
pvt::heapsize<ImageInput>(const ImageInput& input)
{
//! TODO: change ImageInput API to add a virtual heapsize() function
//! to allow per image input override, and call that function here.
return pvt::heapsize(input.m_spec);
}



OIIO_NAMESPACE_END
11 changes: 11 additions & 0 deletions src/libOpenImageIO/imageoutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1021,4 +1021,15 @@ ImageOutput::check_open(OpenMode mode, const ImageSpec& userspec, ROI range,



template<>
size_t
pvt::heapsize<ImageOutput>(const ImageOutput& output)
{
//! TODO: change ImageOutput API to add a virtual heapsize() function
//! to allow per image output override, and call that function here.
return pvt::heapsize(output.m_spec);
}



OIIO_NAMESPACE_END
4 changes: 4 additions & 0 deletions src/libOpenImageIO/imagespec_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@ test_imagespec_from_xml()
std::cout << "test_imagespec_from_xml\n";
ImageSpec spec;
spec.from_xml(imagespec_xml_string);
print(" spec heapsize = {}\n", pvt::heapsize(spec));
print(" spec footprint = {}\n", pvt::footprint(spec));

OIIO_CHECK_EQUAL(spec.nchannels, 4);
OIIO_CHECK_EQUAL(spec.width, 1920);
Expand All @@ -331,6 +333,8 @@ test_imagespec_from_xml()
int
main(int /*argc*/, char* /*argv*/[])
{
print("sizeof(ImageSpec) = {}\n", sizeof(ImageSpec));

test_imagespec_pixels();
test_imagespec_metadata_val();
test_imagespec_attribute_from_string();
Expand Down
5 changes: 5 additions & 0 deletions src/libtexture/imagecache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include <OpenImageIO/typedesc.h>
#include <OpenImageIO/ustring.h>

#include "imagecache_memory_print.h"
#include "imagecache_memory_pvt.h"
#include "imagecache_pvt.h"
#include "imageio_pvt.h"

Expand Down Expand Up @@ -2004,6 +2006,8 @@ ImageCacheImpl::getstats(int level) const
" Failure reads followed by unexplained success:"
" {} files, {} tiles\n",
stats.file_retry_success, stats.tile_retry_success);

printImageCacheMemory(out, *this);
}

if (level >= 2 && files.size()) {
Expand Down Expand Up @@ -2464,6 +2468,7 @@ ImageCacheImpl::getattribute(string_view name, TypeDesc type, void* val) const

if (Strutil::starts_with(name, "stat:")) {
// Stats we can just grab
ATTR_DECODE("stat:cache_footprint", long long, footprint(*this));
ATTR_DECODE("stat:cache_memory_used", long long, m_mem_used);
ATTR_DECODE("stat:tiles_created", int, m_stat_tiles_created);
ATTR_DECODE("stat:tiles_current", int, m_stat_tiles_current);
Expand Down
Loading