MySQL 8.0.29
Source Code Documentation
ut Namespace Reference

This file contains a set of libraries providing overloads for regular dynamic allocation routines which allow for opt-in memory instrumentation through performance schema memory engine (PFS). More...

Namespaces

namespace  detail
 

Classes

class  aligned_array_pointer
 Lightweight convenience wrapper which manages a dynamically allocated array of over-aligned types. More...
 
class  aligned_pointer
 Lightweight convenience wrapper which manages dynamically allocated over-aligned type. More...
 
struct  allocation_low_level_info
 Can be used to extract pointer and size of the allocation provided by the OS. More...
 
class  allocator
 Allocator that allows std::* containers to manage their memory through ut::malloc* and ut::free library functions. More...
 
class  bool_scope_guard_t
 A RAII-style class, which sets a given boolean to true in constructor, and to false in destructor, effectively making sure that it is true for the duration of the object lifetime/scope. More...
 
struct  Cacheline_padded
 A utility wrapper class, which adds padding at the end of the wrapped structure, so that the next object after it is guaranteed to be in the next cache line. More...
 
struct  Count
 Light-weight and type-safe wrapper which serves a purpose of being able to select proper ut::new_arr* overload. More...
 
struct  fallback_to_normal_page_t
 
class  Guarded
 
struct  Location
 
class  Non_copyable
 A utility class which, if inherited from, prevents the descendant class from being copied, moved, or assigned. More...
 
struct  PSI_memory_key_t
 Light-weight and type-safe wrapper around the PSI_memory_key that eliminates the possibility of introducing silent bugs through the course of implicit conversions and makes them show up as compile-time errors. More...
 
class  Stateful_latching_rules
 This is a generic mechanism for verifying correctness of latching rules for state transitions and quering for state of a system. More...
 

Typedefs

template<typename T >
using unique_ptr = std::conditional_t< !std::is_array< T >::value, std::unique_ptr< T, detail::Deleter< T > >, std::conditional_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, detail::Array_deleter< std::remove_extent_t< T > > >, void > >
 The following is a common type that is returned by all the ut::make_unique (non-aligned) specializations listed above. More...
 
using ostringstream = std::basic_ostringstream< char, std::char_traits< char >, ut::allocator< char > >
 Specialization of basic_ostringstream which uses ut::allocator. More...
 
template<typename T >
using vector = std::vector< T, ut::allocator< T > >
 Specialization of vector which uses allocator. More...
 
template<typename Key >
using unordered_set = std::unordered_set< Key, std::hash< Key >, std::equal_to< Key >, ut::allocator< Key > >
 

Functions

template<typename T >
bool is_aligned_as (void const *const ptr)
 Checks if the pointer has address aligned properly for a given type. More...
 
PSI_memory_key_t make_psi_memory_key (PSI_memory_key key)
 Convenience helper function to create type-safe representation of PSI_memory_key. More...
 
void * malloc_withkey (PSI_memory_key_t key, std::size_t size) noexcept
 Dynamically allocates storage of given size. More...
 
void * malloc (std::size_t size) noexcept
 Dynamically allocates storage of given size. More...
 
void * zalloc_withkey (PSI_memory_key_t key, std::size_t size) noexcept
 Dynamically allocates zero-initialized storage of given size. More...
 
void * zalloc (std::size_t size) noexcept
 Dynamically allocates zero-initialized storage of given size. More...
 
void * realloc_withkey (PSI_memory_key_t key, void *ptr, std::size_t size) noexcept
 Upsizes or downsizes already dynamically allocated storage to the new size. More...
 
void * realloc (void *ptr, std::size_t size) noexcept
 Upsizes or downsizes already dynamically allocated storage to the new size. More...
 
void free (void *ptr) noexcept
 Releases storage which has been dynamically allocated through any of the ut::malloc*(), ut::realloc* or ut::zalloc*() variants. More...
 
template<typename T , typename... Args>
T * new_withkey (PSI_memory_key_t key, Args &&... args)
 Dynamically allocates storage for an object of type T. More...
 
template<typename T , typename... Args>
T * new_ (Args &&... args)
 Dynamically allocates storage for an object of type T. More...
 
template<typename T >
void delete_ (T *ptr) noexcept
 Releases storage which has been dynamically allocated through any of the ut::new*() variants. More...
 
template<typename T , typename... Args>
T * new_arr_withkey (PSI_memory_key_t key, Args &&... args)
 Dynamically allocates storage for an array of T's. More...
 
template<typename T , typename... Args>
T * new_arr (Args &&... args)
 Dynamically allocates storage for an array of T's. More...
 
template<typename T >
T * new_arr_withkey (PSI_memory_key_t key, Count count)
 Dynamically allocates storage for an array of T's. More...
 
template<typename T >
T * new_arr (Count count)
 Dynamically allocates storage for an array of T's. More...
 
template<typename T >
void delete_arr (T *ptr) noexcept
 Releases storage which has been dynamically allocated through any of the ut::new_arr*() variants. More...
 
size_t pfs_overhead () noexcept
 Returns number of bytes that ut::malloc_*, ut::zalloc_*, ut::realloc_* and ut::new_* variants will be using to store the necessary metadata for PFS. More...
 
void * malloc_page_withkey (PSI_memory_key_t key, std::size_t size) noexcept
 Dynamically allocates system page-aligned storage of given size. More...
 
void * malloc_page (std::size_t size) noexcept
 Dynamically allocates system page-aligned storage of given size. More...
 
size_t page_allocation_size (void *ptr) noexcept
 Retrieves the total amount of bytes that are available for application code to use. More...
 
allocation_low_level_info page_low_level_info (void *ptr) noexcept
 Retrieves the pointer and size of the allocation provided by the OS. More...
 
bool free_page (void *ptr) noexcept
 Releases storage which has been dynamically allocated through any of the ut::malloc_page*() variants. More...
 
void * malloc_large_page_withkey (PSI_memory_key_t key, std::size_t size) noexcept
 Dynamically allocates memory backed up by large (huge) pages. More...
 
void * malloc_large_page (std::size_t size) noexcept
 Dynamically allocates memory backed up by large (huge) pages. More...
 
size_t large_page_allocation_size (void *ptr) noexcept
 Retrieves the total amount of bytes that are available for application code to use. More...
 
allocation_low_level_info large_page_low_level_info (void *ptr) noexcept
 Retrieves the pointer and size of the allocation provided by the OS. More...
 
bool free_large_page (void *ptr) noexcept
 Releases storage which has been dynamically allocated through any of the ut::malloc_large_page*() variants. More...
 
void * malloc_large_page_withkey (PSI_memory_key_t key, std::size_t size, fallback_to_normal_page_t, bool large_pages_enabled=os_use_large_pages) noexcept
 Dynamically allocates memory backed up by large (huge) pages. More...
 
void * malloc_large_page (std::size_t size, fallback_to_normal_page_t, bool large_pages_enabled=os_use_large_pages) noexcept
 Dynamically allocates memory backed up by large (huge) pages. More...
 
size_t large_page_allocation_size (void *ptr, fallback_to_normal_page_t) noexcept
 Retrieves the total amount of bytes that are available for application code to use. More...
 
allocation_low_level_info large_page_low_level_info (void *ptr, fallback_to_normal_page_t) noexcept
 Retrieves the pointer and size of the allocation provided by the OS. More...
 
bool free_large_page (void *ptr, fallback_to_normal_page_t) noexcept
 Releases storage which has been dynamically allocated through any of the ut::malloc_large_page*(fallback_to_normal_page_t) variants. More...
 
void * aligned_alloc_withkey (PSI_memory_key_t key, std::size_t size, std::size_t alignment) noexcept
 Dynamically allocates storage of given size and at the address aligned to the requested alignment. More...
 
void * aligned_alloc (std::size_t size, std::size_t alignment) noexcept
 Dynamically allocates storage of given size and at the address aligned to the requested alignment. More...
 
void * aligned_zalloc_withkey (PSI_memory_key_t key, std::size_t size, std::size_t alignment) noexcept
 Dynamically allocates zero-initialized storage of given size and at the address aligned to the requested alignment. More...
 
void * aligned_zalloc (std::size_t size, std::size_t alignment) noexcept
 Dynamically allocates zero-initialized storage of given size and at the address aligned to the requested alignment. More...
 
void aligned_free (void *ptr) noexcept
 Releases storage which has been dynamically allocated through any of the aligned_alloc_*() or aligned_zalloc_*() variants. More...
 
template<typename T , typename... Args>
T * aligned_new_withkey (PSI_memory_key_t key, std::size_t alignment, Args &&... args)
 Dynamically allocates storage for an object of type T at address aligned to the requested alignment. More...
 
template<typename T , typename... Args>
T * aligned_new (std::size_t alignment, Args &&... args)
 Dynamically allocates storage for an object of type T at address aligned to the requested alignment. More...
 
template<typename T >
void aligned_delete (T *ptr) noexcept
 Releases storage which has been dynamically allocated through any of the aligned_new_*() variants. More...
 
template<typename T , typename... Args>
T * aligned_new_arr_withkey (PSI_memory_key_t key, std::size_t alignment, Args &&... args)
 Dynamically allocates storage for an array of T's at address aligned to the requested alignment. More...
 
template<typename T >
T * aligned_new_arr_withkey (PSI_memory_key_t key, std::size_t alignment, Count count)
 Dynamically allocates storage for an array of T's at address aligned to the requested alignment. More...
 
template<typename T , typename... Args>
T * aligned_new_arr (std::size_t alignment, Args &&... args)
 Dynamically allocates storage for an array of T's at address aligned to the requested alignment. More...
 
template<typename T >
T * aligned_new_arr (std::size_t alignment, Count count)
 Dynamically allocates storage for an array of T's at address aligned to the requested alignment. More...
 
template<typename T >
void aligned_delete_arr (T *ptr) noexcept
 Releases storage which has been dynamically allocated through any of the aligned_new_arr_*() variants. More...
 
template<typename T , typename Deleter = detail::Deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::unique_ptr< T, Deleter > > make_unique (Args &&... args)
 Dynamically allocates storage for an object of type T. More...
 
template<typename T , typename Deleter = detail::Deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::unique_ptr< T, Deleter > > make_unique (PSI_memory_key_t key, Args &&... args)
 Dynamically allocates storage for an object of type T. More...
 
template<typename T , typename Deleter = detail::Array_deleter<std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, Deleter > > make_unique (size_t size)
 Dynamically allocates storage for an object of type T. More...
 
template<typename T , typename Deleter = detail::Array_deleter<std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, Deleter > > make_unique (PSI_memory_key_t key, size_t size)
 Dynamically allocates storage for an object of type T. More...
 
template<typename T , typename... Args>
std::enable_if_t< detail::is_bounded_array_v< T > > make_unique (Args &&...)=delete
 std::unique_ptr for arrays of known compile-time bound are disallowed. More...
 
template<typename T , typename... Args>
std::enable_if_t< detail::is_bounded_array_v< T > > make_unique (PSI_memory_key_t key, Args &&...)=delete
 std::unique_ptr in PFS-enabled builds for arrays of known compile-time bound are disallowed. More...
 
template<typename T , typename Deleter = detail::Aligned_deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::unique_ptr< T, Deleter > > make_unique_aligned (size_t alignment, Args &&... args)
 Dynamically allocates storage for an object of type T at address aligned to the requested alignment. More...
 
template<typename T , typename Deleter = detail::Aligned_deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::unique_ptr< T, Deleter > > make_unique_aligned (PSI_memory_key_t key, size_t alignment, Args &&... args)
 Dynamically allocates storage for an array of objects of type T at address aligned to the requested alignment. More...
 
template<typename T , typename Deleter = detail::Aligned_array_deleter< std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, Deleter > > make_unique_aligned (size_t alignment, size_t size)
 Dynamically allocates storage for an array of requested size of objects of type T at address aligned to the requested alignment. More...
 
template<typename T , typename Deleter = detail::Aligned_array_deleter< std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, Deleter > > make_unique_aligned (PSI_memory_key_t key, size_t alignment, size_t size)
 Dynamically allocates storage for an array of requested size of objects of type T at address aligned to the requested alignment. More...
 
template<typename T , typename... Args>
std::enable_if_t< detail::is_bounded_array_v< T > > make_unique_aligned (Args &&...)=delete
 std::unique_ptr for arrays of known compile-time bound are disallowed. More...
 
template<typename T , typename... Args>
std::enable_if_t< detail::is_bounded_array_v< T > > make_unique_aligned (PSI_memory_key_t key, Args &&...)=delete
 std::unique_ptr in PFS-enabled builds for arrays of known compile-time bound are disallowed. More...
 
template<typename T , typename Deleter = detail::Deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::shared_ptr< T > > make_shared (Args &&... args)
 Dynamically allocates storage for an object of type T. More...
 
template<typename T , typename Deleter = detail::Deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::shared_ptr< T > > make_shared (PSI_memory_key_t key, Args &&... args)
 Dynamically allocates storage for an object of type T. More...
 
template<typename T , typename Deleter = detail::Array_deleter<std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::shared_ptr< T > > make_shared (size_t size)
 Dynamically allocates storage for an array of requested size of objects of type T. More...
 
template<typename T , typename Deleter = detail::Array_deleter<std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::shared_ptr< T > > make_shared (PSI_memory_key_t key, size_t size)
 Dynamically allocates storage for an array of requested size of objects of type T. More...
 
template<typename T , typename Deleter = detail::Array_deleter<std::remove_extent_t<T>>>
std::enable_if_t< detail::is_bounded_array_v< T >, std::shared_ptr< T > > make_shared ()
 Dynamically allocates storage for an array of objects of type T. More...
 
template<typename T , typename Deleter = detail::Array_deleter<std::remove_extent_t<T>>>
std::enable_if_t< detail::is_bounded_array_v< T >, std::shared_ptr< T > > make_shared (PSI_memory_key_t key)
 Dynamically allocates storage for an array of objects of type T. More...
 
template<typename T , typename Deleter = detail::Aligned_deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::shared_ptr< T > > make_shared_aligned (size_t alignment, Args &&... args)
 Dynamically allocates storage for an object of type T at address aligned to the requested alignment. More...
 
template<typename T , typename Deleter = detail::Aligned_deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::shared_ptr< T > > make_shared_aligned (PSI_memory_key_t key, size_t alignment, Args &&... args)
 Dynamically allocates storage for an object of type T at address aligned to the requested alignment. More...
 
template<typename T , typename Deleter = detail::Aligned_array_deleter< std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::shared_ptr< T > > make_shared_aligned (size_t alignment, size_t size)
 Dynamically allocates storage for an array of requested size of objects of type T at address aligned to the requested alignment. More...
 
template<typename T , typename Deleter = detail::Aligned_array_deleter< std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::shared_ptr< T > > make_shared_aligned (PSI_memory_key_t key, size_t alignment, size_t size)
 Dynamically allocates storage for an array of requested size of objects of type T at address aligned to the requested alignment. More...
 
template<typename T , typename Deleter = detail::Aligned_array_deleter< std::remove_extent_t<T>>>
std::enable_if_t< detail::is_bounded_array_v< T >, std::shared_ptr< T > > make_shared_aligned (size_t alignment)
 Dynamically allocates storage for an array of objects of type T at address aligned to the requested alignment. More...
 
template<typename T , typename Deleter = detail::Aligned_array_deleter< std::remove_extent_t<T>>>
std::enable_if_t< detail::is_bounded_array_v< T >, std::shared_ptr< T > > make_shared_aligned (PSI_memory_key_t key, size_t alignment)
 Dynamically allocates storage for an array of objects of type T at address aligned to the requested alignment. More...
 
template<typename TCondition >
bool wait_for (TCondition cond, std::chrono::steady_clock::duration max_wait)
 Delays execution for at most max_wait or returns earlier if cond becomes true. More...
 
template<typename Condition >
static Wait_stats wait_for (uint64_t spins_limit, std::chrono::microseconds sleep, Condition condition={})
 Waits in loop until given condition is satisfied. More...
 

Variables

constexpr size_t INNODB_CACHE_LINE_SIZE = 64
 CPU cache line size. More...
 
constexpr bool WITH_PFS_MEMORY = true
 
ulong spin_wait_pause_multiplier = 50
 The current value of @innodb_spin_wait_pause_multiplier. More...
 

Detailed Description

This file contains a set of libraries providing overloads for regular dynamic allocation routines which allow for opt-in memory instrumentation through performance schema memory engine (PFS).

In particular, no regular dynamic allocation routines shall be used given that the end goal of instrumentation through PFS is system observability and resource control. In practice this means that we are off the chances to use any standard means of allocating the memory and that we have to provide and re-implement our own PFS-aware variants ourselves.

This does not only apply to direct memory allocation through malloc or new but also to data structures that may allocate dynamic memory under the hood, like the ones from STL. For that reason, STL data structures shall always be used with PFS-enabled custom memory allocator. STL algorithms OTOH also may allocate dynamic memory but they do not provide customization point for user-code to provide custom memory allocation mechanism so there's nothing that we can do about it.

Furthermore, facilities that allow safer memory management such as std::unique_ptr, std::shared_ptr and their respective std::make_unique and std::make_shared functions also have to be re-implemented as such so that they become PFS-aware.

Following is the list of currently implemented PFS-enabled dynamic allocation overloads and associated facilities: Primitive allocation functions: ut::malloc ut::zalloc ut::realloc ut::free ut::{malloc | zalloc | realloc}_withkey Primitive allocation functions for types with extended alignment: ut::aligned_alloc ut::aligned_zalloc ut::aligned_free ut::{aligned_alloc | aligned_zalloc}_withkey Primitive allocation functions for page-aligned allocations: ut::malloc_page ut::malloc_page_withkey ut::free_page Primitive allocation functions for large (huge) page aligned allocations: ut::malloc_large_page ut::malloc_large_page_withkey ut::free_large_page Primitive allocation functions for large (huge) aligned allocations with fallback to page-aligned allocations: ut::malloc_large_page(fallback_to_normal_page_t) ut::malloc_large_page_withkey(fallback_to_normal_page_t) ut::free_large_page(fallback_to_normal_page_t) Overloads for C++ new and delete syntax: ut::new_ ut::new_arr ut::{new_ | new_arr_}_withkey ut::delete_ ut::delete_arr Overloads for C++ new and delete syntax for types with extended alignment: ut::aligned_new ut::aligned_new_arr ut::{aligned_new_ | aligned_new_arr_}_withkey ut::aligned_delete ut::aligned_delete_arr Custom memory allocators: ut::allocator Overloads for std::unique_ptr and std::shared_ptr factory functions ut::make_unique ut::make_unique_aligned ut::make_shared ut::make_shared_aligned _withkey variants from above are the PFS-enabled dynamic allocation overloads.

Usages of PFS-enabled library functions are trying to resemble already familiar syntax as close as possible. For concrete examples please see particular function documentation but in general it applies that foo(x) becomes ut::foo(x) or ut::foo_withkey(key, x) where foo is some allocation function listed above and key is PFS key to instrument the allocation with.

Typedef Documentation

◆ ostringstream

using ut::ostringstream = typedef std::basic_ostringstream<char, std::char_traits<char>, ut::allocator<char> >

Specialization of basic_ostringstream which uses ut::allocator.

Please note that it's .str() method returns std::basic_string which is not std::string, so it has similar API (in particular .c_str()), but you can't assign it to regular, std::string.

◆ unique_ptr

template<typename T >
using ut::unique_ptr = typedef std::conditional_t< !std::is_array<T>::value, std::unique_ptr<T, detail::Deleter<T> >, std::conditional_t< detail::is_unbounded_array_v<T>, std::unique_ptr<T, detail::Array_deleter<std::remove_extent_t<T> >>, void> >

The following is a common type that is returned by all the ut::make_unique (non-aligned) specializations listed above.

This is effectively a if-ladder for the following list of conditions on the input type: !stdis_array<T>::value -> std::unique_ptr<T, detail::Deleter<T>> detail::is_unbounded_array_v<T> -> std::unique_ptr<T,detail::Array_deleter<std::remove_extent_t<T>>> else (or else if detail::is_bounded_array_v<T>) -> void (we do not support bounded array ut::make_unique)

◆ unordered_set

template<typename Key >
using ut::unordered_set = typedef std::unordered_set<Key, std::hash<Key>, std::equal_to<Key>, ut::allocator<Key> >

◆ vector

template<typename T >
using ut::vector = typedef std::vector<T, ut::allocator<T> >

Specialization of vector which uses allocator.

Function Documentation

◆ aligned_alloc()

void * ut::aligned_alloc ( std::size_t  size,
std::size_t  alignment 
)
inlinenoexcept

Dynamically allocates storage of given size and at the address aligned to the requested alignment.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]sizeSize of storage (in bytes) requested to be allocated.
[in]alignmentAlignment requirement for storage to be allocated.
Returns
Pointer to the allocated storage. nullptr if dynamic storage allocation failed.

Example: int* x = static_cast<int*>(aligned_alloc(10*sizeof(int), 64));

◆ aligned_alloc_withkey()

void * ut::aligned_alloc_withkey ( PSI_memory_key_t  key,
std::size_t  size,
std::size_t  alignment 
)
inlinenoexcept

Dynamically allocates storage of given size and at the address aligned to the requested alignment.

Instruments the memory with given PSI memory key in case PFS memory support is enabled.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]sizeSize of storage (in bytes) requested to be allocated.
[in]alignmentAlignment requirement for storage to be allocated.
Returns
Pointer to the allocated storage. nullptr if dynamic storage allocation failed.

Example: int* x = static_cast<int*>(aligned_alloc_withkey(key, 10*sizeof(int), 64));

◆ aligned_delete()

template<typename T >
void ut::aligned_delete ( T *  ptr)
inlinenoexcept

Releases storage which has been dynamically allocated through any of the aligned_new_*() variants.

Destructs the object of type T.

Parameters
[in]ptrPointer which has been obtained through any of the aligned_new_*() variants

Example: aligned_delete(ptr);

◆ aligned_delete_arr()

template<typename T >
void ut::aligned_delete_arr ( T *  ptr)
inlinenoexcept

Releases storage which has been dynamically allocated through any of the aligned_new_arr_*() variants.

Destructs all objects of type T.

Parameters
[in]ptrPointer which has been obtained through any of the aligned_new_arr_*() variants.

Example: aligned_delete_arr(ptr);

◆ aligned_free()

void ut::aligned_free ( void *  ptr)
inlinenoexcept

Releases storage which has been dynamically allocated through any of the aligned_alloc_*() or aligned_zalloc_*() variants.

Parameters
[in]ptrPointer which has been obtained through any of the aligned_alloc_*() or aligned_zalloc_*() variants.

Example: aligned_free(ptr);

◆ aligned_new()

template<typename T , typename... Args>
T * ut::aligned_new ( std::size_t  alignment,
Args &&...  args 
)
inline

Dynamically allocates storage for an object of type T at address aligned to the requested alignment.

Constructs the object of type T with provided Args.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]alignmentAlignment requirement for storage to be allocated.
[in]argsArguments one wishes to pass over to T constructor(s)
Returns
Pointer to the allocated storage. Throws std::bad_alloc exception if dynamic storage allocation could not be fulfilled.

Example 1: int *ptr = aligned_new<int>(2);

Example 2: int *ptr = aligned_new<int>(2, 10); assert(*ptr == 10);

Example 3: struct A { A(int x, int y) : _x(x), _y(y) {} int x, y; } A *ptr = aligned_new<A>(2, 1, 2); assert(ptr->x == 1); assert(ptr->y == 2);

◆ aligned_new_arr() [1/2]

template<typename T , typename... Args>
T * ut::aligned_new_arr ( std::size_t  alignment,
Args &&...  args 
)
inline

Dynamically allocates storage for an array of T's at address aligned to the requested alignment.

Constructs objects of type T with provided Args.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]alignmentAlignment requirement for storage to be allocated.
[in]argsArguments one wishes to pass over to T constructor(s)
Returns
Pointer to the first element of allocated storage. Throws std::bad_alloc exception if dynamic storage allocation could not be fulfilled.

Example 1: int *ptr = aligned_new_arr<int, 5>(2); ptr[0] ... ptr[4]

Example 2: int *ptr = aligned_new_arr<int, 5>(2, 1, 2, 3, 4, 5); assert(*ptr[0] == 1); assert(*ptr[1] == 2); ... assert(*ptr[4] == 5);

Example 3: struct A { A(int x, int y) : _x(x), _y(y) {} int x, y; } A *ptr = aligned_new_arr<A, 5>(2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); assert(ptr[0]->x == 1); assert(ptr[0]->y == 2); assert(ptr[1]->x == 3); assert(ptr[1]->y == 4); ... assert(ptr[4]->x == 9); assert(ptr[4]->y == 10);

◆ aligned_new_arr() [2/2]

template<typename T >
T * ut::aligned_new_arr ( std::size_t  alignment,
Count  count 
)
inline

Dynamically allocates storage for an array of T's at address aligned to the requested alignment.

Constructs objects of type T using default constructor.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]alignmentAlignment requirement for storage to be allocated.
[in]countNumber of T elements in an array.
Returns
Pointer to the first element of allocated storage. Throws std::bad_alloc exception if dynamic storage allocation could not be fulfilled.

Example 1: int *ptr = aligned_new_arr<int>(2, 5); assert(*ptr[0] == 0); assert(*ptr[1] == 0); ... assert(*ptr[4] == 0);

Example 2: struct A { A) : x(1), y(2) {} int x, y; } A *ptr = aligned_new_arr<A>(2, 5); assert(ptr[0].x == 1); assert(ptr[0].y == 2); ... assert(ptr[4].x == 1); assert(ptr[4].y == 2);

Example 3: struct A { A(int x, int y) : _x(x), _y(y) {} int x, y; } A *ptr = aligned_new_arr<A>(2, 5); will not compile, no default constructor

◆ aligned_new_arr_withkey() [1/2]

template<typename T , typename... Args>
T * ut::aligned_new_arr_withkey ( PSI_memory_key_t  key,
std::size_t  alignment,
Args &&...  args 
)
inline

Dynamically allocates storage for an array of T's at address aligned to the requested alignment.

Constructs objects of type T with provided Args. Arguments that are to be used to construct some respective instance of T shall be wrapped into a std::tuple. See examples down below. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

To create an array of default-intialized T's, one can use this function template but for convenience purposes one can achieve the same by using the ut::aligned_new_arr_withkey with ut::Count overload.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]alignmentAlignment requirement for storage to be allocated.
[in]argsTuples of arguments one wishes to pass over to T constructor(s).
Returns
Pointer to the first element of allocated storage. Throws std::bad_alloc exception if dynamic storage allocation could not be fulfilled. Re-throws whatever exception that may have occured during the construction of any instance of T, in which case it automatically destroys successfully constructed objects till that moment (if any), and finally cleans up the raw memory allocated for T instances.

Example 1: int *ptr = ut::aligned_new_arr_withkey<int>(key, 32, std::forward_as_tuple(1), std::forward_as_tuple(2)); assert(ptr[0] == 1); assert(ptr[1] == 2);

Example 2: struct A { A(int x, int y) : _x(x), _y(y) {} int _x, _y; }; A *ptr = ut::aligned_new_arr_withkey<A>(key, 32, std::forward_as_tuple(0, 1), std::forward_as_tuple(2, 3), std::forward_as_tuple(4, 5), std::forward_as_tuple(6, 7), std::forward_as_tuple(8, 9)); assert(ptr[0]->_x == 0 && ptr[0]->_y == 1); assert(ptr[1]->_x == 2 && ptr[1]->_y == 3); assert(ptr[2]->_x == 4 && ptr[2]->_y == 5); assert(ptr[3]->_x == 6 && ptr[3]->_y == 7); assert(ptr[4]->_x == 8 && ptr[4]->_y == 9);

Example 3: struct A { A() : _x(10), _y(100) {} A(int x, int y) : _x(x), _y(y) {} int _x, _y; }; A *ptr = ut::aligned_new_arr_withkey<A>(key, 32, std::forward_as_tuple(0, 1), std::forward_as_tuple(2, 3), std::forward_as_tuple(), std::forward_as_tuple(6, 7), std::forward_as_tuple()); assert(ptr[0]->_x == 0 && ptr[0]->_y == 1); assert(ptr[1]->_x == 2 && ptr[1]->_y == 3); assert(ptr[2]->_x == 10 && ptr[2]->_y == 100); assert(ptr[3]->_x == 6 && ptr[3]->_y == 7); assert(ptr[4]->_x == 10 && ptr[4]->_y == 100);

◆ aligned_new_arr_withkey() [2/2]

template<typename T >
T * ut::aligned_new_arr_withkey ( PSI_memory_key_t  key,
std::size_t  alignment,
Count  count 
)
inline

Dynamically allocates storage for an array of T's at address aligned to the requested alignment.

Constructs objects of type T using default constructor. If T cannot be default-initialized (e.g. default constructor does not exist), then this interace cannot be used for constructing such an array. ut::new_arr_withkey overload with user-provided initialization must be used then. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]alignmentAlignment requirement for storage to be allocated.
[in]countNumber of T elements in an array.
Returns
Pointer to the first element of allocated storage. Throws std::bad_alloc exception if dynamic storage allocation could not be fulfilled. Re-throws whatever exception that may have occured during the construction of any instance of T, in which case it automatically destroys successfully constructed objects till that moment (if any), and finally cleans up the raw memory allocated for T instances.

Example 1: int *ptr = ut::aligned_new_arr_withkey<int>(key, 32, ut::Count{2});

Example 2: struct A { A() : _x(10), _y(100) {} int _x, _y; }; A *ptr = ut::aligned_new_arr_withkey<A>(key, 32, ut::Count{5}); assert(ptr[0]->_x == 10 && ptr[0]->_y == 100); assert(ptr[1]->_x == 10 && ptr[1]->_y == 100); assert(ptr[2]->_x == 10 && ptr[2]->_y == 100); assert(ptr[3]->_x == 10 && ptr[3]->_y == 100); assert(ptr[4]->_x == 10 && ptr[4]->_y == 100);

Example 3: struct A { A(int x, int y) : _x(x), _y(y) {} int _x, _y; }; Following cannot compile because A is not default-constructible A *ptr = ut::aligned_new_arr_withkey<A>(key, 32, ut::Count{5});

◆ aligned_new_withkey()

template<typename T , typename... Args>
T * ut::aligned_new_withkey ( PSI_memory_key_t  key,
std::size_t  alignment,
Args &&...  args 
)
inline

Dynamically allocates storage for an object of type T at address aligned to the requested alignment.

Constructs the object of type T with provided Args. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]alignmentAlignment requirement for storage to be allocated.
[in]argsArguments one wishes to pass over to T constructor(s)
Returns
Pointer to the allocated storage. Throws std::bad_alloc exception if dynamic storage allocation could not be fulfilled.

Example 1: int *ptr = aligned_new_withkey<int>(key, 2);

Example 2: int *ptr = aligned_new_withkey<int>(key, 2, 10); assert(*ptr == 10);

Example 3: struct A { A(int x, int y) : _x(x), _y(y) {} int x, y; } A *ptr = aligned_new_withkey<A>(key, 2, 1, 2); assert(ptr->x == 1); assert(ptr->y == 2);

◆ aligned_zalloc()

void * ut::aligned_zalloc ( std::size_t  size,
std::size_t  alignment 
)
inlinenoexcept

Dynamically allocates zero-initialized storage of given size and at the address aligned to the requested alignment.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]sizeSize of storage (in bytes) requested to be allocated.
[in]alignmentAlignment requirement for storage to be allocated.
Returns
Pointer to the zero-initialized allocated storage. nullptr if dynamic storage allocation failed.

Example: int* x = static_cast<int*>(aligned_zalloc(10*sizeof(int), 64));

◆ aligned_zalloc_withkey()

void * ut::aligned_zalloc_withkey ( PSI_memory_key_t  key,
std::size_t  size,
std::size_t  alignment 
)
inlinenoexcept

Dynamically allocates zero-initialized storage of given size and at the address aligned to the requested alignment.

Instruments the memory with given PSI memory key in case PFS memory support is enabled.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]sizeSize of storage (in bytes) requested to be allocated.
[in]alignmentAlignment requirement for storage to be allocated.
Returns
Pointer to the zero-initialized allocated storage. nullptr if dynamic storage allocation failed.

Example: int* x = static_cast<int*>(aligned_zalloc_withkey(key, 10*sizeof(int), 64));

◆ delete_()

template<typename T >
void ut::delete_ ( T *  ptr)
inlinenoexcept

Releases storage which has been dynamically allocated through any of the ut::new*() variants.

Destructs the object of type T.

Parameters
[in]ptrPointer which has been obtained through any of the ut::new*() variants

Example: ut::delete_(ptr);

◆ delete_arr()

template<typename T >
void ut::delete_arr ( T *  ptr)
inlinenoexcept

Releases storage which has been dynamically allocated through any of the ut::new_arr*() variants.

Destructs all objects of type T.

Parameters
[in]ptrPointer which has been obtained through any of the ut::new_arr*() variants

Example: ut::delete_arr(ptr);

◆ free()

void ut::free ( void *  ptr)
inlinenoexcept

Releases storage which has been dynamically allocated through any of the ut::malloc*(), ut::realloc* or ut::zalloc*() variants.

Parameters
[in]ptrPointer which has been obtained through any of the ut::malloc*(), ut::realloc* or ut::zalloc*() variants.

Example: ut::free(ptr);

◆ free_large_page() [1/2]

bool ut::free_large_page ( void *  ptr)
inlinenoexcept

Releases storage which has been dynamically allocated through any of the ut::malloc_large_page*() variants.

Parameters
[in]ptrPointer which has been obtained through any of the ut::malloc_large_page*() variants.
Returns
True if releasing the large (huge) page-aligned memory was successful.

Example: ut::free_large_page(ptr);

◆ free_large_page() [2/2]

bool ut::free_large_page ( void *  ptr,
fallback_to_normal_page_t   
)
inlinenoexcept

Releases storage which has been dynamically allocated through any of the ut::malloc_large_page*(fallback_to_normal_page_t) variants.

Whether the pointer is representing area backed up by regular or huge-pages, this function will know the difference and therefore act accordingly.

Parameters
[in]ptrPointer which has been obtained through any of the ut::malloc_large_page*(fallback_to_normal_page_t) variants.
Returns
True if releasing the memory was successful.

Example: ut::free_large_page(ptr);

◆ free_page()

bool ut::free_page ( void *  ptr)
inlinenoexcept

Releases storage which has been dynamically allocated through any of the ut::malloc_page*() variants.

Parameters
[in]ptrPointer which has been obtained through any of the ut::malloc_page*() variants.
Returns
True if releasing the page-aligned memory was successful.

Example: ut::free_page(ptr);

◆ is_aligned_as()

template<typename T >
bool ut::is_aligned_as ( void const *const  ptr)

Checks if the pointer has address aligned properly for a given type.

Parameters
[in]ptrThe pointer, address of which we want to check if it could be pointing to object of type T.
Returns
true iff ptr address is aligned w.r.t. alignof(T)

◆ large_page_allocation_size() [1/2]

size_t ut::large_page_allocation_size ( void *  ptr)
inlinenoexcept

Retrieves the total amount of bytes that are available for application code to use.

Amount of bytes returned does not have to match bytes requested through ut::malloc_large_page*(). This is so because bytes requested will always be implicitly rounded up to the next multiple of huge-page size (e.g. 2MiB). Exact huge-page size value that is going to be used will be stored in large_page_default_size.

Parameters
[in]ptrPointer which has been obtained through any of the ut::malloc_large_page*() variants.
Returns
Number of bytes available.

Example: int x = static_cast<int>(ut::malloc_large_page(10*sizeof(int))); assert(large_page_allocation_size(x) == HUGE_PAGE_SIZE);

◆ large_page_allocation_size() [2/2]

size_t ut::large_page_allocation_size ( void *  ptr,
fallback_to_normal_page_t   
)
inlinenoexcept

Retrieves the total amount of bytes that are available for application code to use.

Amount of bytes returned does not have to match bytes requested through ut::malloc_large_page*(fallback_to_normal_page_t). This is so because bytes requested will always be implicitly rounded up to the next multiple of either huge-page size (e.g. 2MiB) or regular page size (e.g. 4K).

Parameters
[in]ptrPointer which has been obtained through any of the ut::malloc_large_page*(fallback_to_normal_page_t) variants.
Returns
Number of bytes available for use.

◆ large_page_low_level_info() [1/2]

allocation_low_level_info ut::large_page_low_level_info ( void *  ptr)
inlinenoexcept

Retrieves the pointer and size of the allocation provided by the OS.

It is a low level information, and is needed only to call low level memory-related OS functions.

Parameters
[in]ptrPointer which has been obtained through any of the ut::malloc_large_page*() variants.
Returns
Low level OS allocation info.

◆ large_page_low_level_info() [2/2]

allocation_low_level_info ut::large_page_low_level_info ( void *  ptr,
fallback_to_normal_page_t   
)
inlinenoexcept

Retrieves the pointer and size of the allocation provided by the OS.

It is a low level information, and is needed only to call low level memory-related OS functions.

Parameters
[in]ptrPointer which has been obtained through any of the ut::malloc_large_page*(fallback_to_normal_page_t) variants.
Returns
Low level OS allocation info.

◆ make_psi_memory_key()

PSI_memory_key_t ut::make_psi_memory_key ( PSI_memory_key  key)
inline

Convenience helper function to create type-safe representation of PSI_memory_key.

Parameters
[in]keyPSI memory key to be held in type-safe PSI_memory_key_t.
Returns
PSI_memory_key_t which wraps the given PSI_memory_key

◆ make_shared() [1/6]

template<typename T , typename Deleter = detail::Array_deleter<std::remove_extent_t<T>>>
std::enable_if_t< detail::is_bounded_array_v< T >, std::shared_ptr< T > > ut::make_shared ( )

Dynamically allocates storage for an array of objects of type T.

Constructs the object of type T with provided Args. Wraps the pointer to an array of T instance into the std::shared_ptr.

This overload participates in overload resolution only if T is an array type with known compile-time bound.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Returns
std::shared_ptr holding a pointer to an array of size instances of T.

◆ make_shared() [2/6]

template<typename T , typename Deleter = detail::Deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::shared_ptr< T > > ut::make_shared ( Args &&...  args)

Dynamically allocates storage for an object of type T.

Constructs the object of type T with provided Args. Wraps the pointer to T instance into the std::shared_ptr.

This overload participates in overload resolution only if T is not an array type.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]argsArguments one wishes to pass over to T constructor(s) .
Returns
std::shared_ptr holding a pointer to instance of T.

◆ make_shared() [3/6]

template<typename T , typename Deleter = detail::Array_deleter<std::remove_extent_t<T>>>
std::enable_if_t< detail::is_bounded_array_v< T >, std::shared_ptr< T > > ut::make_shared ( PSI_memory_key_t  key)

Dynamically allocates storage for an array of objects of type T.

Constructs the object of type T with provided Args. Wraps the pointer to an array of T instances into the std::shared_ptr with custom deleter which knows how to handle PFS-enabled dynamic memory allocations. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

This overload participates in overload resolution only if T is an array type with known compile-time bound.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
Returns
std::shared_ptr holding a pointer to an array of size instances of T.

◆ make_shared() [4/6]

template<typename T , typename Deleter = detail::Deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::shared_ptr< T > > ut::make_shared ( PSI_memory_key_t  key,
Args &&...  args 
)

Dynamically allocates storage for an object of type T.

Constructs the object of type T with provided Args. Wraps the pointer to T instance into the std::shared_ptr with custom deleter which knows how to handle PFS-enabled dynamic memory allocations. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

This overload participates in overload resolution only if T is not an array type.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]argsArguments one wishes to pass over to T constructor(s) .
Returns
std::shared_ptr holding a pointer to instance of T.

◆ make_shared() [5/6]

template<typename T , typename Deleter = detail::Array_deleter<std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::shared_ptr< T > > ut::make_shared ( PSI_memory_key_t  key,
size_t  size 
)

Dynamically allocates storage for an array of requested size of objects of type T.

Constructs the object of type T with provided Args. Wraps the pointer to an array of T instances into the std::shared_ptr with custom deleter which knows how to handle PFS-enabled dynamic memory allocations. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

This overload participates in overload resolution only if T is an array type with unknown compile-time bound.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]sizeSize of the array of objects T to allocate.
Returns
std::shared_ptr holding a pointer to an array of size instances of T.

◆ make_shared() [6/6]

template<typename T , typename Deleter = detail::Array_deleter<std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::shared_ptr< T > > ut::make_shared ( size_t  size)

Dynamically allocates storage for an array of requested size of objects of type T.

Constructs the object of type T with provided Args. Wraps the pointer to an array of T instance into the std::shared_ptr.

This overload participates in overload resolution only if T is an array type with unknown compile-time bound.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]sizeSize of the array of objects T to allocate.
Returns
std::shared_ptr holding a pointer to an array of size instances of T.

◆ make_shared_aligned() [1/6]

template<typename T , typename Deleter = detail::Aligned_array_deleter< std::remove_extent_t<T>>>
std::enable_if_t< detail::is_bounded_array_v< T >, std::shared_ptr< T > > ut::make_shared_aligned ( PSI_memory_key_t  key,
size_t  alignment 
)

Dynamically allocates storage for an array of objects of type T at address aligned to the requested alignment.

Constructs the object of type T with provided Args. Wraps the pointer to an array of T instances into the std::shared_ptr with custom deleter which knows how to handle PFS-enabled dynamic memory allocations. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

This overload participates in overload resolution only if T is an array type with known compile-time bound.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]alignmentAlignment requirement for storage to be allocated.
Returns
std::shared_ptr holding a pointer to an array of size instances of T.

◆ make_shared_aligned() [2/6]

template<typename T , typename Deleter = detail::Aligned_deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::shared_ptr< T > > ut::make_shared_aligned ( PSI_memory_key_t  key,
size_t  alignment,
Args &&...  args 
)

Dynamically allocates storage for an object of type T at address aligned to the requested alignment.

Constructs the object of type T with provided Args. Wraps the pointer to T instance into the std::shared_ptr with custom deleter which knows how to handle PFS-enabled dynamic memory allocations. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

This overload participates in overload resolution only if T is not an array type.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]alignmentAlignment requirement for storage to be allocated.
[in]argsArguments one wishes to pass over to T constructor(s) .
Returns
std::shared_ptr holding a pointer to instance of T.

◆ make_shared_aligned() [3/6]

template<typename T , typename Deleter = detail::Aligned_array_deleter< std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::shared_ptr< T > > ut::make_shared_aligned ( PSI_memory_key_t  key,
size_t  alignment,
size_t  size 
)

Dynamically allocates storage for an array of requested size of objects of type T at address aligned to the requested alignment.

Constructs the object of type T with provided Args. Wraps the pointer to an array of T instances into the std::shared_ptr with custom deleter which knows how to handle PFS-enabled dynamic memory allocations. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

This overload participates in overload resolution only if T is an array type with unknown compile-time bound.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]alignmentAlignment requirement for storage to be allocated.
[in]sizeSize of the array of objects T to allocate.
Returns
std::shared_ptr holding a pointer to an array of size instances of T.

◆ make_shared_aligned() [4/6]

template<typename T , typename Deleter = detail::Aligned_array_deleter< std::remove_extent_t<T>>>
std::enable_if_t< detail::is_bounded_array_v< T >, std::shared_ptr< T > > ut::make_shared_aligned ( size_t  alignment)

Dynamically allocates storage for an array of objects of type T at address aligned to the requested alignment.

Constructs the object of type T with provided Args. Wraps the pointer to an array of T instance into the std::shared_ptr.

This overload participates in overload resolution only if T is an array type with known compile-time bound.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]alignmentAlignment requirement for storage to be allocated.
Returns
std::shared_ptr holding a pointer to an array of size instances of T.

◆ make_shared_aligned() [5/6]

template<typename T , typename Deleter = detail::Aligned_deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::shared_ptr< T > > ut::make_shared_aligned ( size_t  alignment,
Args &&...  args 
)

Dynamically allocates storage for an object of type T at address aligned to the requested alignment.

Constructs the object of type T with provided Args. Wraps the pointer to T instance into the std::shared_ptr.

This overload participates in overload resolution only if T is not an array type.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]alignmentAlignment requirement for storage to be allocated.
[in]argsArguments one wishes to pass over to T constructor(s) .
Returns
std::shared_ptr holding a pointer to instance of T.

◆ make_shared_aligned() [6/6]

template<typename T , typename Deleter = detail::Aligned_array_deleter< std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::shared_ptr< T > > ut::make_shared_aligned ( size_t  alignment,
size_t  size 
)

Dynamically allocates storage for an array of requested size of objects of type T at address aligned to the requested alignment.

Constructs the object of type T with provided Args. Wraps the pointer to an array of T instance into the std::shared_ptr.

This overload participates in overload resolution only if T is an array type with unknown compile-time bound.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]alignmentAlignment requirement for storage to be allocated.
[in]sizeSize of the array of objects T to allocate.
Returns
std::shared_ptr holding a pointer to an array of size instances of T.

◆ make_unique() [1/6]

template<typename T , typename Deleter = detail::Deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::unique_ptr< T, Deleter > > ut::make_unique ( Args &&...  args)

Dynamically allocates storage for an object of type T.

Constructs the object of type T with provided Args. Wraps the pointer to T instance into the std::unique_ptr.

This overload participates in overload resolution only if T is not an array type.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]argsArguments one wishes to pass over to T constructor(s) .
Returns
std::unique_ptr holding a pointer to instance of T.

◆ make_unique() [2/6]

template<typename T , typename... Args>
std::enable_if_t< detail::is_bounded_array_v< T > > ut::make_unique ( Args &&  ...)
delete

std::unique_ptr for arrays of known compile-time bound are disallowed.

For more details see 4.3 paragraph from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3588.txt

◆ make_unique() [3/6]

template<typename T , typename Deleter = detail::Deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::unique_ptr< T, Deleter > > ut::make_unique ( PSI_memory_key_t  key,
Args &&...  args 
)

Dynamically allocates storage for an object of type T.

Constructs the object of type T with provided Args. Wraps the pointer to T instance into the std::unique_ptr with custom deleter which knows how to handle PFS-enabled dynamic memory allocations. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

This overload participates in overload resolution only if T is not an array type.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]argsArguments one wishes to pass over to T constructor(s) .
Returns
std::unique_ptr holding a pointer to instance of T.

◆ make_unique() [4/6]

template<typename T , typename... Args>
std::enable_if_t< detail::is_bounded_array_v< T > > ut::make_unique ( PSI_memory_key_t  key,
Args &&  ... 
)
delete

std::unique_ptr in PFS-enabled builds for arrays of known compile-time bound are disallowed.

For more details see 4.3 paragraph from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3588.txt

◆ make_unique() [5/6]

template<typename T , typename Deleter = detail::Array_deleter<std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, Deleter > > ut::make_unique ( PSI_memory_key_t  key,
size_t  size 
)

Dynamically allocates storage for an object of type T.

Constructs the object of type T with provided Args. Wraps the pointer to an array of T instances into the std::unique_ptr with custom deleter which knows how to handle PFS-enabled dyanmic memory allocations. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

This overload participates in overload resolution only if T is an array type with unknown compile-time bound.

Returns
std::unique_ptr holding a pointer to an array of size instances of T.

◆ make_unique() [6/6]

template<typename T , typename Deleter = detail::Array_deleter<std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, Deleter > > ut::make_unique ( size_t  size)

Dynamically allocates storage for an object of type T.

Constructs the object of type T with provided Args. Wraps the pointer to an array of T instance into the std::unique_ptr.

This overload participates in overload resolution only if T is an array type with unknown compile-time bound.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Returns
std::unique_ptr holding a pointer to an array of size instances of T.

◆ make_unique_aligned() [1/6]

template<typename T , typename... Args>
std::enable_if_t< detail::is_bounded_array_v< T > > ut::make_unique_aligned ( Args &&  ...)
delete

std::unique_ptr for arrays of known compile-time bound are disallowed.

For more details see 4.3 paragraph from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3588.txt

◆ make_unique_aligned() [2/6]

template<typename T , typename... Args>
std::enable_if_t< detail::is_bounded_array_v< T > > ut::make_unique_aligned ( PSI_memory_key_t  key,
Args &&  ... 
)
delete

std::unique_ptr in PFS-enabled builds for arrays of known compile-time bound are disallowed.

For more details see 4.3 paragraph from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3588.txt

◆ make_unique_aligned() [3/6]

template<typename T , typename Deleter = detail::Aligned_deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::unique_ptr< T, Deleter > > ut::make_unique_aligned ( PSI_memory_key_t  key,
size_t  alignment,
Args &&...  args 
)

Dynamically allocates storage for an array of objects of type T at address aligned to the requested alignment.

Constructs the object of type T with provided Args. Wraps the pointer to T instance into the std::unique_ptr with custom deleter which knows how to handle PFS-enabled dynamic memory allocations. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

This overload participates in overload resolution only if T is not an array type.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]alignmentAlignment requirement for storage to be allocated.
[in]argsArguments one wishes to pass over to T constructor(s) .
Returns
std::unique_ptr holding a pointer to instance of T.

◆ make_unique_aligned() [4/6]

template<typename T , typename Deleter = detail::Aligned_array_deleter< std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, Deleter > > ut::make_unique_aligned ( PSI_memory_key_t  key,
size_t  alignment,
size_t  size 
)

Dynamically allocates storage for an array of requested size of objects of type T at address aligned to the requested alignment.

Constructs the object of type T with provided Args. Wraps the pointer to an array of T instances into the std::unique_ptr with custom deleter which knows how to handle PFS-enabled dynamic memory allocations. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

This overload participates in overload resolution only if T is an array type with unknown compile-time bound.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]alignmentAlignment requirement for storage to be allocated.
[in]sizeSize of the array of objects T to allocate.
Returns
std::unique_ptr holding a pointer to an array of size instances of T.

◆ make_unique_aligned() [5/6]

template<typename T , typename Deleter = detail::Aligned_deleter<T>, typename... Args>
std::enable_if_t<!std::is_array< T >::value, std::unique_ptr< T, Deleter > > ut::make_unique_aligned ( size_t  alignment,
Args &&...  args 
)

Dynamically allocates storage for an object of type T at address aligned to the requested alignment.

Constructs the object of type T with provided Args. Wraps the pointer to T instance into the std::unique_ptr.

This overload participates in overload resolution only if T is not an array type.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]alignmentAlignment requirement for storage to be allocated.
[in]argsArguments one wishes to pass over to T constructor(s) .
Returns
std::unique_ptr holding a pointer to instance of T.

◆ make_unique_aligned() [6/6]

template<typename T , typename Deleter = detail::Aligned_array_deleter< std::remove_extent_t<T>>>
std::enable_if_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, Deleter > > ut::make_unique_aligned ( size_t  alignment,
size_t  size 
)

Dynamically allocates storage for an array of requested size of objects of type T at address aligned to the requested alignment.

Constructs the object of type T with provided Args. Wraps the pointer to an array of T instance into the std::unique_ptr.

This overload participates in overload resolution only if T is an array type with unknown compile-time bound.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]alignmentAlignment requirement for storage to be allocated.
[in]sizeSize of the array of objects T to allocate.
Returns
std::unique_ptr holding a pointer to an array of size instances of T.

◆ malloc()

void * ut::malloc ( std::size_t  size)
inlinenoexcept

Dynamically allocates storage of given size.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]sizeSize of storage (in bytes) requested to be allocated.
Returns
Pointer to the allocated storage. nullptr if dynamic storage allocation failed.

Example: int x = static_cast<int>(ut::malloc_withkey(UT_NEW_THIS_FILE_PSI_KEY, 10*sizeof(int)));

◆ malloc_large_page() [1/2]

void * ut::malloc_large_page ( std::size_t  size)
inlinenoexcept

Dynamically allocates memory backed up by large (huge) pages.

For large (huge) pages to be functional, usually some steps in system admin preparation is required. Exact steps vary from system to system.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]sizeSize of storage (in bytes) requested to be allocated.
Returns
Pointer to the page-aligned storage. nullptr if dynamic storage allocation failed.

Example: int x = static_cast<int>(ut::malloc_large_page(10*sizeof(int)));

◆ malloc_large_page() [2/2]

void * ut::malloc_large_page ( std::size_t  size,
fallback_to_normal_page_t  ,
bool  large_pages_enabled = os_use_large_pages 
)
inlinenoexcept

Dynamically allocates memory backed up by large (huge) pages.

In the event that large (huge) pages are unavailable or disabled explicitly through os_use_large_pages, it will fallback to dynamic allocation backed by page-aligned memory.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]sizeSize of storage (in bytes) requested to be allocated.
[in]large_pages_enabledIf true, the large pages will be tried to be used.
Returns
Pointer to the page-aligned storage. nullptr if dynamic storage allocation failed.

Example: int x = static_cast<int>( ut::malloc_large_page( 10*sizeof(int), fallback_to_normal_page_t{} ) );

◆ malloc_large_page_withkey() [1/2]

void * ut::malloc_large_page_withkey ( PSI_memory_key_t  key,
std::size_t  size 
)
inlinenoexcept

Dynamically allocates memory backed up by large (huge) pages.

Instruments the memory with given PSI memory key in case PFS memory support is enabled.

For large (huge) pages to be functional, usually some steps in system admin preparation is required. Exact steps vary from system to system.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]sizeSize of storage (in bytes) requested to be allocated.
Returns
Pointer to the page-aligned storage. nullptr if dynamic storage allocation failed.

Example: int x = static_cast<int>( ut::malloc_large_page_withkey(key, 10*sizeof(int)) );

◆ malloc_large_page_withkey() [2/2]

void * ut::malloc_large_page_withkey ( PSI_memory_key_t  key,
std::size_t  size,
fallback_to_normal_page_t  ,
bool  large_pages_enabled = os_use_large_pages 
)
inlinenoexcept

Dynamically allocates memory backed up by large (huge) pages.

In the event that large (huge) pages are unavailable or disabled explicitly through os_use_large_pages, it will fallback to dynamic allocation backed by page-aligned memory. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]sizeSize of storage (in bytes) requested to be allocated.
[in]large_pages_enabledIf true, the large pages will be tried to be used.
Returns
Pointer to the page-aligned storage. nullptr if dynamic storage allocation failed.

Example: int x = static_cast<int>( ut::malloc_large_page_withkey( key, 10*sizeof(int), fallback_to_normal_page_t{} ) );

◆ malloc_page()

void * ut::malloc_page ( std::size_t  size)
inlinenoexcept

Dynamically allocates system page-aligned storage of given size.

Actual page-alignment, and thus page-size, will depend on CPU architecture but in general page is traditionally mostly 4K large. In contrast to Unices, Windows do make an exception here and implement 64K granularity on top of regular page-size for some legacy reasons. For more details see: https://devblogs.microsoft.com/oldnewthing/20031008-00/?p=42223

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]sizeSize of storage (in bytes) requested to be allocated.
Returns
Pointer to the page-aligned storage. nullptr if dynamic storage allocation failed.

Example: int x = static_cast<int>(ut::malloc_page(10*sizeof(int)));

◆ malloc_page_withkey()

void * ut::malloc_page_withkey ( PSI_memory_key_t  key,
std::size_t  size 
)
inlinenoexcept

Dynamically allocates system page-aligned storage of given size.

Instruments the memory with given PSI memory key in case PFS memory support is enabled.

Actual page-alignment, and thus page-size, will depend on CPU architecture but in general page is traditionally mostly 4K large. In contrast to Unices, Windows do make an exception here and implement 64K granularity on top of regular page-size for some legacy reasons. For more details see: https://devblogs.microsoft.com/oldnewthing/20031008-00/?p=42223

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]sizeSize of storage (in bytes) requested to be allocated.
Returns
Pointer to the page-aligned storage. nullptr if dynamic storage allocation failed.

Example: int x = static_cast<int>(ut::malloc_page_withkey(key, 10*sizeof(int)));

◆ malloc_withkey()

void * ut::malloc_withkey ( PSI_memory_key_t  key,
std::size_t  size 
)
inlinenoexcept

Dynamically allocates storage of given size.

Instruments the memory with given PSI memory key in case PFS memory support is enabled.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]sizeSize of storage (in bytes) requested to be allocated.
Returns
Pointer to the allocated storage. nullptr if dynamic storage allocation failed.

Example: int x = static_cast<int>(ut::malloc_withkey(key, 10*sizeof(int)));

◆ new_()

template<typename T , typename... Args>
T * ut::new_ ( Args &&...  args)
inline

Dynamically allocates storage for an object of type T.

Constructs the object of type T with provided Args.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]argsArguments one wishes to pass over to T constructor(s)
Returns
Pointer to the allocated storage. Throws std::bad_alloc exception if dynamic storage allocation could not be fulfilled. Re-throws whatever exception that may have occured during the construction of T, in which case it automatically cleans up the raw memory allocated for it.

Example 1: int *ptr = ut::new_withkey<int>(UT_NEW_THIS_FILE_PSI_KEY);

Example 2: int *ptr = ut::new_withkey<int>(UT_NEW_THIS_FILE_PSI_KEY, 10); assert(*ptr == 10);

Example 3: struct A { A(int x, int y) : _x(x), _y(y) {} int _x, _y; }; A *ptr = ut::new_withkey<A>(UT_NEW_THIS_FILE_PSI_KEY, 1, 2); assert(ptr->_x == 1); assert(ptr->_y == 2);

◆ new_arr() [1/2]

template<typename T , typename... Args>
T * ut::new_arr ( Args &&...  args)
inline

Dynamically allocates storage for an array of T's.

Constructs objects of type T with provided Args. Arguments that are to be used to construct some respective instance of T shall be wrapped into a std::tuple. See examples down below.

To create an array of default-intialized T's, one can use this function template but for convenience purposes one can achieve the same by using the ut::new_arr_withkey with ut::Count overload.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]argsTuples of arguments one wishes to pass over to T constructor(s).
Returns
Pointer to the first element of allocated storage. Throws std::bad_alloc exception if dynamic storage allocation could not be fulfilled. Re-throws whatever exception that may have occured during the construction of any instance of T, in which case it automatically destroys successfully constructed objects till that moment (if any), and finally cleans up the raw memory allocated for T instances.

Example 1: int *ptr = ut::new_arr_withkey<int>(UT_NEW_THIS_FILE_PSI_KEY, std::forward_as_tuple(1), std::forward_as_tuple(2)); assert(ptr[0] == 1); assert(ptr[1] == 2);

Example 2: struct A { A(int x, int y) : _x(x), _y(y) {} int _x, _y; }; A *ptr = ut::new_arr_withkey<A>(UT_NEW_THIS_FILE_PSI_KEY, std::forward_as_tuple(0, 1), std::forward_as_tuple(2, 3), std::forward_as_tuple(4, 5), std::forward_as_tuple(6, 7), std::forward_as_tuple(8, 9)); assert(ptr[0]->_x == 0 && ptr[0]->_y == 1); assert(ptr[1]->_x == 2 && ptr[1]->_y == 3); assert(ptr[2]->_x == 4 && ptr[2]->_y == 5); assert(ptr[3]->_x == 6 && ptr[3]->_y == 7); assert(ptr[4]->_x == 8 && ptr[4]->_y == 9);

Example 3: struct A { A() : _x(10), _y(100) {} A(int x, int y) : _x(x), _y(y) {} int _x, _y; }; A *ptr = ut::new_arr_withkey<A>(UT_NEW_THIS_FILE_PSI_KEY, std::forward_as_tuple(0, 1), std::forward_as_tuple(2, 3), std::forward_as_tuple(), std::forward_as_tuple(6, 7), std::forward_as_tuple()); assert(ptr[0]->_x == 0 && ptr[0]->_y == 1); assert(ptr[1]->_x == 2 && ptr[1]->_y == 3); assert(ptr[2]->_x == 10 && ptr[2]->_y == 100); assert(ptr[3]->_x == 6 && ptr[3]->_y == 7); assert(ptr[4]->_x == 10 && ptr[4]->_y == 100);

◆ new_arr() [2/2]

template<typename T >
T * ut::new_arr ( Count  count)
inline

Dynamically allocates storage for an array of T's.

Constructs objects of type T using default constructor. If T cannot be default-initialized (e.g. default constructor does not exist), then this interace cannot be used for constructing such an array. ut::new_arr overload with user-provided initialization must be used then.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]countNumber of T elements in an array.
Returns
Pointer to the first element of allocated storage. Throws std::bad_alloc exception if dynamic storage allocation could not be fulfilled. Re-throws whatever exception that may have occured during the construction of any instance of T, in which case it automatically destroys successfully constructed objects till that moment (if any), and finally cleans up the raw memory allocated for T instances.

Example 1: int *ptr = ut::new_arr_withkey<int>(UT_NEW_THIS_FILE_PSI_KEY, ut::Count{2});

Example 2: struct A { A() : _x(10), _y(100) {} int _x, _y; }; A *ptr = ut::new_arr_withkey<A>(UT_NEW_THIS_FILE_PSI_KEY, ut::Count{5}); assert(ptr[0]->_x == 10 && ptr[0]->_y == 100); assert(ptr[1]->_x == 10 && ptr[1]->_y == 100); assert(ptr[2]->_x == 10 && ptr[2]->_y == 100); assert(ptr[3]->_x == 10 && ptr[3]->_y == 100); assert(ptr[4]->_x == 10 && ptr[4]->_y == 100);

Example 3: struct A { A(int x, int y) : _x(x), _y(y) {} int _x, _y; }; Following cannot compile because A is not default-constructible A *ptr = ut::new_arr_withkey<A>(UT_NEW_THIS_FILE_PSI_KEY, ut::Count{5});

◆ new_arr_withkey() [1/2]

template<typename T , typename... Args>
T * ut::new_arr_withkey ( PSI_memory_key_t  key,
Args &&...  args 
)
inline

Dynamically allocates storage for an array of T's.

Constructs objects of type T with provided Args. Arguments that are to be used to construct some respective instance of T shall be wrapped into a std::tuple. See examples down below. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

To create an array of default-intialized T's, one can use this function template but for convenience purposes one can achieve the same by using the ut::new_arr_withkey with ut::Count overload.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]argsTuples of arguments one wishes to pass over to T constructor(s).
Returns
Pointer to the first element of allocated storage. Throws std::bad_alloc exception if dynamic storage allocation could not be fulfilled. Re-throws whatever exception that may have occured during the construction of any instance of T, in which case it automatically destroys successfully constructed objects till that moment (if any), and finally cleans up the raw memory allocated for T instances.

Example 1: int *ptr = ut::new_arr_withkey<int>(key, std::forward_as_tuple(1), std::forward_as_tuple(2)); assert(ptr[0] == 1); assert(ptr[1] == 2);

Example 2: struct A { A(int x, int y) : _x(x), _y(y) {} int _x, _y; }; A *ptr = ut::new_arr_withkey<A>(key, std::forward_as_tuple(0, 1), std::forward_as_tuple(2, 3), std::forward_as_tuple(4, 5), std::forward_as_tuple(6, 7), std::forward_as_tuple(8, 9)); assert(ptr[0]->_x == 0 && ptr[0]->_y == 1); assert(ptr[1]->_x == 2 && ptr[1]->_y == 3); assert(ptr[2]->_x == 4 && ptr[2]->_y == 5); assert(ptr[3]->_x == 6 && ptr[3]->_y == 7); assert(ptr[4]->_x == 8 && ptr[4]->_y == 9);

Example 3: struct A { A() : _x(10), _y(100) {} A(int x, int y) : _x(x), _y(y) {} int _x, _y; }; A *ptr = ut::new_arr_withkey<A>(key, std::forward_as_tuple(0, 1), std::forward_as_tuple(2, 3), std::forward_as_tuple(), std::forward_as_tuple(6, 7), std::forward_as_tuple()); assert(ptr[0]->_x == 0 && ptr[0]->_y == 1); assert(ptr[1]->_x == 2 && ptr[1]->_y == 3); assert(ptr[2]->_x == 10 && ptr[2]->_y == 100); assert(ptr[3]->_x == 6 && ptr[3]->_y == 7); assert(ptr[4]->_x == 10 && ptr[4]->_y == 100);

◆ new_arr_withkey() [2/2]

template<typename T >
T * ut::new_arr_withkey ( PSI_memory_key_t  key,
Count  count 
)
inline

Dynamically allocates storage for an array of T's.

Constructs objects of type T using default constructor. If T cannot be default-initialized (e.g. default constructor does not exist), then this interace cannot be used for constructing such an array. ut::new_arr_withkey overload with user-provided initialization must be used then. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]countNumber of T elements in an array.
Returns
Pointer to the first element of allocated storage. Throws std::bad_alloc exception if dynamic storage allocation could not be fulfilled. Re-throws whatever exception that may have occured during the construction of any instance of T, in which case it automatically destroys successfully constructed objects till that moment (if any), and finally cleans up the raw memory allocated for T instances.

Example 1: int *ptr = ut::new_arr_withkey<int>(key, ut::Count{2});

Example 2: struct A { A() : _x(10), _y(100) {} int _x, _y; }; A *ptr = ut::new_arr_withkey<A>(key, ut::Count{5}); assert(ptr[0]->_x == 10 && ptr[0]->_y == 100); assert(ptr[1]->_x == 10 && ptr[1]->_y == 100); assert(ptr[2]->_x == 10 && ptr[2]->_y == 100); assert(ptr[3]->_x == 10 && ptr[3]->_y == 100); assert(ptr[4]->_x == 10 && ptr[4]->_y == 100);

Example 3: struct A { A(int x, int y) : _x(x), _y(y) {} int _x, _y; }; Following cannot compile because A is not default-constructible A *ptr = ut::new_arr_withkey<A>(key, ut::Count{5});

◆ new_withkey()

template<typename T , typename... Args>
T * ut::new_withkey ( PSI_memory_key_t  key,
Args &&...  args 
)
inline

Dynamically allocates storage for an object of type T.

Constructs the object of type T with provided Args. Instruments the memory with given PSI memory key in case PFS memory support is enabled.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]argsArguments one wishes to pass over to T constructor(s)
Returns
Pointer to the allocated storage. Throws std::bad_alloc exception if dynamic storage allocation could not be fulfilled. Re-throws whatever exception that may have occured during the construction of T, in which case it automatically cleans up the raw memory allocated for it.

Example 1: int *ptr = ut::new_withkey<int>(key);

Example 2: int *ptr = ut::new_withkey<int>(key, 10); assert(*ptr == 10);

Example 3: struct A { A(int x, int y) : _x(x), _y(y) {} int _x, _y; }; A *ptr = ut::new_withkey<A>(key, 1, 2); assert(ptr->_x == 1); assert(ptr->_y == 2);

◆ page_allocation_size()

size_t ut::page_allocation_size ( void *  ptr)
inlinenoexcept

Retrieves the total amount of bytes that are available for application code to use.

Amount of bytes returned does not have to match bytes requested through ut::malloc_page*(). This is so because bytes requested will always be implicitly rounded up to the next regular page size (e.g. 4K).

Parameters
[in]ptrPointer which has been obtained through any of the ut::malloc_page*() variants.
Returns
Number of bytes available.

Example: int x = static_cast<int>(ut::malloc_page(10*sizeof(int))); assert(page_allocation_size(x) == CPU_PAGE_SIZE);

◆ page_low_level_info()

allocation_low_level_info ut::page_low_level_info ( void *  ptr)
inlinenoexcept

Retrieves the pointer and size of the allocation provided by the OS.

It is a low level information, and is needed only to call low level memory-related OS functions.

Parameters
[in]ptrPointer which has been obtained through any of the ut::malloc_page*() variants.
Returns
Low level OS allocation info.

◆ pfs_overhead()

size_t ut::pfs_overhead ( )
inlinenoexcept

Returns number of bytes that ut::malloc_*, ut::zalloc_*, ut::realloc_* and ut::new_* variants will be using to store the necessary metadata for PFS.

Returns
Size of the PFS metadata.

◆ realloc()

void * ut::realloc ( void *  ptr,
std::size_t  size 
)
inlinenoexcept

Upsizes or downsizes already dynamically allocated storage to the new size.

It also supports standard realloc() semantics by: allocating size bytes of memory when passed ptr is nullptr freeing the memory pointed by ptr if passed size is 0

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]ptrPointer to the memory area to be reallocated.
[in]sizeNew size of storage (in bytes) requested to be reallocated.
Returns
Pointer to the reallocated storage. nullptr if dynamic storage allocation failed.

Example: int x = static_cast<int>(ut::malloc_withkey(UT_NEW_THIS_FILE_PSI_KEY, 10*sizeof(int)); x = static_cast<int*>(ut::realloc(key, ptr, 100*sizeof(int)));

◆ realloc_withkey()

void * ut::realloc_withkey ( PSI_memory_key_t  key,
void *  ptr,
std::size_t  size 
)
inlinenoexcept

Upsizes or downsizes already dynamically allocated storage to the new size.

Instruments the memory with given PSI memory key in case PFS memory support is enabled.

It also supports standard realloc() semantics by: allocating size bytes of memory when passed ptr is nullptr freeing the memory pointed by ptr if passed size is 0

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]ptrPointer to the memory area to be reallocated.
[in]sizeNew size of storage (in bytes) requested to be reallocated.
Returns
Pointer to the reallocated storage. nullptr if dynamic storage allocation failed.

Example: int x = static_cast<int>(ut::malloc_withkey(key, 10*sizeof(int)); x = static_cast<int*>(ut::realloc_withkey(key, ptr, 100*sizeof(int)));

◆ wait_for() [1/2]

template<typename TCondition >
bool ut::wait_for ( TCondition  cond,
std::chrono::steady_clock::duration  max_wait 
)

Delays execution for at most max_wait or returns earlier if cond becomes true.

Parameters
condin: condition to wait for; evaluated every 2 ms
max_waitin: maximum delay to wait
Returns
Returns true if condition have evaluated to true, false on timeout.

◆ wait_for() [2/2]

template<typename Condition >
static Wait_stats ut::wait_for ( uint64_t  spins_limit,
std::chrono::microseconds  sleep,
Condition  condition = {} 
)
inlinestatic

Waits in loop until given condition is satisfied.

It starts waiting using spin loop with pauses and after reaching maximum iterations, it switches to loop with sleeps. The sleep time is multiplied by two after every k-sleeps, until it reaches 100ms (starting at provided value).

Parameters
[in]spins_limitmaximum iterations without sleep
[in]sleepinitial sleep time
[in]conditionreturns true when condition is satisfied
Returns
number of loops with sleep that have been used

◆ zalloc()

void * ut::zalloc ( std::size_t  size)
inlinenoexcept

Dynamically allocates zero-initialized storage of given size.

NOTE: Given that this function will NOT be instrumenting the allocation through PFS, observability for particular parts of the system which want to use it will be lost or in best case inaccurate. Please have a strong reason to do so.

Parameters
[in]sizeSize of storage (in bytes) requested to be allocated.
Returns
Pointer to the zero-initialized allocated storage. nullptr if dynamic storage allocation failed.

Example: int x = static_cast<int>(ut::zalloc_withkey(UT_NEW_THIS_FILE_PSI_KEY, 10*sizeof(int)));

◆ zalloc_withkey()

void * ut::zalloc_withkey ( PSI_memory_key_t  key,
std::size_t  size 
)
inlinenoexcept

Dynamically allocates zero-initialized storage of given size.

Instruments the memory with given PSI memory key in case PFS memory support is enabled.

Parameters
[in]keyPSI memory key to be used for PFS memory instrumentation.
[in]sizeSize of storage (in bytes) requested to be allocated.
Returns
Pointer to the zero-initialized allocated storage. nullptr if dynamic storage allocation failed.

Example: int x = static_cast<int>(ut::zalloc_withkey(key, 10*sizeof(int)));

Variable Documentation

◆ INNODB_CACHE_LINE_SIZE

constexpr size_t ut::INNODB_CACHE_LINE_SIZE = 64
constexpr

CPU cache line size.

◆ spin_wait_pause_multiplier

ulong ut::spin_wait_pause_multiplier = 50

The current value of @innodb_spin_wait_pause_multiplier.

Determines how many PAUSE instructions to emit for each requested unit of delay when calling ut_delay(delay). The default value of 50 causes delay*50 PAUSES which was equivalent to delay microseconds on 100 MHz Pentium + Visual C++. Useful on processors which have "non-standard" duration of a single PAUSE instruction - one can compensate for longer PAUSES by setting the spin_wait_pause_multiplier to a smaller value on such machine

◆ WITH_PFS_MEMORY

constexpr bool ut::WITH_PFS_MEMORY = true
constexpr