DD::Image::Memory Class Reference

Classes

class  bytes
 
class  MemoryInfo
 

Public Types

typedef std::vector< MemoryInfoMemoryInfoArray
 
typedef std::map< const NodeI *, MemoryInfoArray > MemoryInfoMap
 

Static Public Member Functions

static int count_users ()
 
template<typename T >
static T * allocate (size_t num)
 
template<typename T >
static void deallocate (T *ptr)
 
static void generateMemoryInfo (MemoryInfoMap &outMemInfoMap, const void *restrict_to=nullptr)
 
static void dump_info (std::ostream &output, bool format_bytes, bool includeNodeInfo, const void *restrict_to)
 
static bool register_allocator (IAllocator *pAllocator)
 
static bool unregister_allocator (IAllocator *pAllocator)
 
static size_t get_num_registered_allocators ()
 
static IAllocatorget_allocator (size_t index)
 
static IAllocatorfind_allocator (const char *pAllocatorName)
 
template<typename T >
static T * create_allocator (const char *pAllocatorName)
 
static void dump_allocatorinfoXML (std::ostream &output, bool format_bytes)
 
static void dump_infoXML (std::ostream &output, bool format_bytes, bool includeNodeInfo, const void *restrict_to)
 
static void print_bytes (std::ostream &output, long long unsigned bytes, bool metric=true)
 
static int format_bytes (char *buffer, long long unsigned bytes, bool metric=true)
 
static void initialize ()
 
static size_t max_usage ()
 
static size_t current_usage ()
 
static size_t total_ram ()
 
static U64 total_ram_64 ()
 
static size_t total_vm ()
 
static int free_count ()
 
static int new_handler_count ()
 
static bool set_current_usage (size_t target, const char *message=nullptr)
 
static bool reduce_current_usage (const char *message=nullptr)
 
static void set_max_usage (size_t new_max)
 
static void set_hard_max_usage (size_t final_max)
 
static void set_free_count (int)
 
static void set_new_handler_count (int)
 
static void * allocate_remember_size (size_t size)
 
static void * allocate_void (size_t bytes)
 
static void deallocate_remember_size (void *ptr)
 
static void deallocate_void (void *ptr, size_t num=0)
 
static size_t get_allocated_size (void *ptr)
 
static bool clipToCacheLimit (int &width, int &height, const DD::Image::Format &format)
 

Friends

template<class MemoryHolderT >
class MemRegistrant
 

Detailed Description

Memory manager for cache-like objects that can be freed and recreated if necessary so that their memory can be used for other purposes. The output buffers on Iop and the 8-bit buffers used by the Nuke viewer, and other objects fall into this class.

Each such object should call register_user() in it's constructor and unregister_user() in it's destructor.

Any code that uses allocate() and deallocate() will trigger reduce_current_usage() if the total allocated by these calls goes over max_usage(). This will only work well if the majority of large objects allocated by Nuke and plugins calls these functions, so that current_usage() reflects the actual amount of memory being used. Code that uses new/delete (and malloc on Windows) will also trigger reduce_current_usage() when the std::new_handler() is called. But this only happens when you run out of memory which may be somewhat late for safe recovery.

allocate() will also be 16-byte aligned to allow use of vector operations.

Member Function Documentation

int Memory::count_users ( )
static

Returns the number of register_user() calls that have not had an unregister_user() call done to it. Used for debugging.

void Memory::dump_info ( std::ostream &  output,
bool  format_bytes,
bool  includeNodeInfo,
const void *  restrict_to 
)
static

Prints a report about all the users and the total memory usage to the stream. Also takes a format_bytes argument which, if true, returns the bytes in a human readable format.

If restrict_to is non-zero then only users whose info() command tests and matches the restrict_to() are printed, and no summary information is used. This is currently used to dump only the info about users that belong to a Node. Result may be a zero-length string if no users match.

If includeNodeInfo is true, Node pointers associated with memory objects (eg Ops/Knobs) will be dererenced for name information. This is unsafe during shutdown, where the associated Nodes may have been deleted.

bool Memory::register_allocator ( IAllocator pAllocator)
static

Registers an allocator with the Memory system, which allows us to track how much memory a given allocator is using.

An allocator instance can only be registered once, and print an error if added twice. Returns if allocator was successfully registered

References DD::Image::IAllocator::getName(), and DD::Image::getName().

bool Memory::unregister_allocator ( IAllocator pAllocator)
static

Unregisters an allocator from the Memory system Will print an error message if trying to remove an allocator that's already been removed. Returns if allocator was successfully unregistered

References DD::Image::end().

size_t Memory::get_num_registered_allocators ( )
static

Gets the number of allocators currently registered with the memory system

IAllocator * Memory::get_allocator ( size_t  index)
static

Gets the registered allocator at a given index

IAllocator * Memory::find_allocator ( const char *  pAllocatorName)
static

Finds the registered allocator by name and returns the pointer. returns NULL if it can't find one

References DD::Image::end(), and DD::Image::IAllocator::getName().

template<typename T >
static T* DD::Image::Memory::create_allocator ( const char *  pAllocatorName)
inlinestatic

Helper function that creates and registers an allocator of type T, or if it already exists returns the allocator pointer.

void Memory::dump_allocatorinfoXML ( std::ostream &  output,
bool  format_bytes 
)
static

Prints and XML report about all registered allocators, including the current memory usage and the highwater mark.

Also takes a format_bytes argument which, if true, returns the bytes in a human readable format.

References DD::Image::IAllocator::getAllocatorHighWaterMark(), DD::Image::IAllocator::getAllocatorUsage(), DD::Image::IAllocator::getName(), DD::Image::IAllocator::getRequestedHighWaterMark(), DD::Image::IAllocator::getRequestedUsage(), and DD::Image::IAllocator::getType().

void Memory::dump_infoXML ( std::ostream &  output,
bool  format_bytes,
bool  includeNodeInfo,
const void *  restrict_to 
)
static

Prints an XML report about all the users and the total memory usage to the stream. Also takes a format_bytes argument which, if true, returns the bytes in a human readable format.

If restrict_to is non-zero then only users whose info() command tests and matches the restrict_to() are printed, and no summary information is used. This is currently used to dump only the info about users that belong to a Node. Result may be a zero-length string if no users match.

If includeNodeInfo is true, Node pointers associated with memory objects (eg Ops/Knobs) will be dererenced for name information. This is unsafe during shutdown, where the associated Nodes may have been deleted.

void Memory::print_bytes ( std::ostream &  output,
long long unsigned  bytes,
bool  metric = true 
)
static

Prints a number of bytes in a user-friendly form, for instance 123.4MiB, 1024KiB, or 513B. If metric is true then use powers of 10 rather than powers of 2, and remove the 'i' from the suffixes.

int Memory::format_bytes ( char *  buffer,
long long unsigned  bytes,
bool  metric = true 
)
static

Puts the same result as print_bytes() into the passed buffer, which must be at least 11 bytes long. Returns the number of bytes written, not counting the nul terminator.

void Memory::initialize ( )
static

Sets total_ram() by asking the system for this information, and sets max_usage() to 50% of that. This is automatically done by many Memory calls, but you should do this if you wish to change the max_usage to some value other than this default.

Also calls std::set_new_handler(). If you don't want this, call this and then call std::set_new_handler() to set the value back. By default running out of memory in new (and in malloc in Windows) will cause it to clean up memory so it will work, and will throw a bad_alloc exception if it does not work.

size_t Memory::current_usage ( )
static

Return number of bytes allocated by allocate_void(). This function is not inline in case we need to add a lock around the reference

bool Memory::set_current_usage ( size_t  target,
const char *  message = nullptr 
)
static

Reduce current_usage() to target or smaller. Returns true if it deleted anything (check current_usage() to see if you really hit the target)

bool Memory::reduce_current_usage ( const char *  message = nullptr)
static

Reduce the amount of memory being used. Returns true if anything is freed. The message, if not zero, should id the caller is used to print debugging info.

static void* DD::Image::Memory::allocate_remember_size ( size_t  size)
inlinestatic

TODO: REMOVE THIS FUNCTION!

void * Memory::allocate_void ( size_t  bytes)
static

Allocate bytes bytes of memory and return as a void*

static void DD::Image::Memory::deallocate_remember_size ( void *  ptr)
inlinestatic

TODO: REMOVE THIS FUNCTION!

void Memory::deallocate_void ( void *  ptr,
size_t  num = 0 
)
static

Free memory created with allocate_void() TODO: REMOVE num ARG!

size_t Memory::get_allocated_size ( void *  ptr)
static

Returns the size actually allocated for a given pointer NOTE: the size returned may be bigger than requested, implementation dependent. This effectively calls the following: Windows: HeapSize() OSX: malloc_size() Linux: malloc_usable_size()

Referenced by DD::Image::AllocationTracker::allocate().

bool DD::Image::Memory::clipToCacheLimit ( int &  width,
int &  height,
const DD::Image::Format format 
)
static

Reduce width & height to a box so that can be allocated.

Currently an absolute maximum of 1Mb on each dimension, and an absolute maximum of 64k^2 (4Gb) on the area. This has been chosen so that several dozen 1-D arrays of pointers or floats can be allocated without running out of memory.

In addition each dimension is limited to 16k or the size of the format, whichever is larger. This smaller limit has been chosen so that the entire image can probably be allocated at once. But if the user chooses a very large format this limit is ignored and it may try to allocate far more memory than will fit. Many operations in Nuke will still work with these very large operations (especially in 64-bit versions).

Returns true if it changes the width or height.

References DD::Image::Format::height(), and DD::Image::Format::width().

Referenced by DD::Image::Iop::request().



©2021 The Foundry Visionmongers, Ltd. All Rights Reserved.
www.thefoundry.co.uk