MySQL 8.4.0
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_aligned
 A utility wrapper class, which aligns T to cacheline boundary. 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  fast_modulo_t
 Allows to execute x % mod for a specified mod in a fast way, without using a slow operation of division. More...
 
class  Guarded
 
struct  Location
 
class  mt_fast_modulo_t
 A class that allows to atomically set new modulo value for fast modulo computations. More...
 
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  Seq_lock
 A class that allows to read value of variable of some type T atomically and allows the value to be changed, all using lock-free operations. More...
 
class  Stateful_latching_rules
 This is a generic mechanism for verifying correctness of latching rules for state transitions and querying 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...
 
template<typename T >
using unique_ptr_aligned = std::conditional_t< !std::is_array< T >::value, std::unique_ptr< T, detail::Aligned_deleter< T > >, std::conditional_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, detail::Aligned_array_deleter< std::remove_extent_t< T > > >, void > >
 The following is a common type that is returned by all the ut::make_unique_aligned (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 T >
using list = std::list< T, ut::allocator< T > >
 Specialization of list which uses ut_allocator. More...
 
template<typename Key , typename Compare = std::less<Key>>
using set = std::set< Key, Compare, ut::allocator< Key > >
 Specialization of set which uses ut_allocator. More...
 
template<typename Key >
using unordered_set = std::unordered_set< Key, std::hash< Key >, std::equal_to< Key >, ut::allocator< Key > >
 
template<typename Key , typename Value , typename Compare = std::less<Key>>
using map = std::map< Key, Value, Compare, ut::allocator< std::pair< const Key, Value > > >
 Specialization of map which uses ut_allocator. More...
 
template<typename Key , typename Value , typename Hash = std::hash<Key>, typename Key_equal = std::equal_to<Key>>
using unordered_map = std::unordered_map< Key, Value, Hash, Key_equal, ut::allocator< std::pair< const Key, Value > > >
 

Functions

static uint64_t multiply_uint64 (uint64_t x, uint64_t y, uint64_t &hi)
 Calculates the 128bit result of multiplication of the two specified 64bit integers. More...
 
static uint64_t divide_128 (uint64_t high, uint64_t low, uint64_t div)
 
uint64_t find_prime (uint64_t n)
 Looks for a prime number slightly greater than the given argument. More...
 
template<typename T >
bool is_aligned_as (void const *const ptr)
 Checks if the pointer has address aligned properly for a given type. More...
 
bool is_zeros (const void *start, size_t number_of_bytes)
 Checks if memory range is all zeros. 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...
 
static uint64_t random_64 ()
 The following function generates pseudo-random 64bit integers which enumerate the value space generated by a linear congruence. More...
 
static uint64_t random_64_fast ()
 The following function returns fine clock count as random value. More...
 
static uint64_t random_from_interval (uint64_t low, uint64_t high)
 Generates a pseudo-random integer from a given interval. More...
 
static uint64_t random_from_interval_fast (uint64_t low, uint64_t high)
 Generates a light-weight pseudo-random integer from a given interval. More...
 
static uint64_t hash_uint64 (uint64_t value)
 Hashes a 64-bit integer. More...
 
static uint64_t hash_string (const char *str)
 Hashes a character string ending in the null character. More...
 
static uint64_t hash_uint64_pair (uint64_t n1, uint64_t n2)
 Hashes a pair of 64bit integers. More...
 
static uint64_t hash_binary (const byte *buf, size_t len, uint64_t seed=0xacb1f3526e25dd39)
 Hashes a binary buffer of given length. More...
 
static uint32_t hash_binary_ib (const byte *str, size_t len)
 Hashes a binary buffer of given length in the old innobase way. More...
 
template<uint64_t random_64_func>
static uint64_t random_from_interval_gen (uint64_t low, uint64_t high)
 
template<typename T , typename U >
constexpr bool can_type_fit_value (const U value)
 
template<typename T , typename U >
clamp (U x)
 
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

const thread_local size_t this_thread_hash
 The hash value of the current thread's id. More...
 
constexpr size_t INNODB_CACHE_LINE_SIZE = 64
 CPU cache line size. More...
 
constexpr size_t INNODB_KERNEL_PAGE_SIZE_DEFAULT = 4 * 1024
 Default kernel page size (not assuming huge pages support). 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

◆ list

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

Specialization of list which uses ut_allocator.

◆ map

template<typename Key , typename Value , typename Compare = std::less<Key>>
using ut::map = typedef std::map<Key, Value, Compare, ut::allocator<std::pair<const Key, Value> >>

Specialization of map which uses ut_allocator.

◆ 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.

◆ set

template<typename Key , typename Compare = std::less<Key>>
using ut::set = typedef std::set<Key, Compare, ut::allocator<Key> >

Specialization of set which uses ut_allocator.

◆ 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)

◆ unique_ptr_aligned

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

The following is a common type that is returned by all the ut::make_unique_aligned (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::Aligned_deleter<T>> detail::is_unbounded_array_v<T> -> std::unique_ptr<T,detail::Aligned_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_map

template<typename Key , typename Value , typename Hash = std::hash<Key>, typename Key_equal = std::equal_to<Key>>
using ut::unordered_map = typedef std::unordered_map<Key, Value, Hash, Key_equal, ut::allocator<std::pair<const Key, Value> >>

◆ 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-initialized 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 occurred 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 interface 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 occurred 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));

◆ can_type_fit_value()

template<typename T , typename U >
constexpr bool ut::can_type_fit_value ( const U  value)
constexpr

◆ clamp()

template<typename T , typename U >
T ut::clamp ( U  x)

◆ 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);

◆ divide_128()

static uint64_t ut::divide_128 ( uint64_t  high,
uint64_t  low,
uint64_t  div 
)
inlinestatic

◆ find_prime()

uint64_t ut::find_prime ( uint64_t  n)

Looks for a prime number slightly greater than the given argument.

The prime is chosen so that it is not near any power of 2.

Parameters
[in]npositive number > 100
Returns
prime

◆ 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);

◆ hash_binary()

static uint64_t ut::hash_binary ( const byte buf,
size_t  len,
uint64_t  seed = 0xacb1f3526e25dd39 
)
inlinestatic

Hashes a binary buffer of given length.

Parameters
[in]bufbuffer of bytes
[in]lenlength
[in]seedseed to be used in calculation. Can be previous value. A default value is just a randomly chosen number.
Returns
hashed value

◆ hash_binary_ib()

static uint32_t ut::hash_binary_ib ( const byte str,
size_t  len 
)
inlinestatic

Hashes a binary buffer of given length in the old innobase way.

This is highly inefficient, don't use outside areas that require backward compatibility on data written to disk.

Parameters
[in]strbuffer of bytes
[in]lenlength
Returns
hashed value

◆ hash_string()

static uint64_t ut::hash_string ( const char *  str)
inlinestatic

Hashes a character string ending in the null character.

Returns
hashed value

◆ hash_uint64()

static uint64_t ut::hash_uint64 ( uint64_t  value)
inlinestatic

Hashes a 64-bit integer.

Parameters
[in]value64-bit integer
Returns
hashed value

◆ hash_uint64_pair()

static uint64_t ut::hash_uint64_pair ( uint64_t  n1,
uint64_t  n2 
)
inlinestatic

Hashes a pair of 64bit integers.

Parameters
[in]n1first 64bit integer
[in]n2second 64bit integer
Returns
hashed value

◆ 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)

◆ is_zeros()

bool ut::is_zeros ( const void *  start,
size_t  number_of_bytes 
)
inline

Checks if memory range is all zeros.

Parameters
[in]startThe pointer to first byte of a buffer
[in]number_of_bytesThe number of bytes in the buffer
Returns
true if and only if number_of_bytes bytes pointed by start are all zeros.

◆ 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 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.

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)));

◆ multiply_uint64()

static uint64_t ut::multiply_uint64 ( uint64_t  x,
uint64_t  y,
uint64_t &  hi 
)
inlinestatic

Calculates the 128bit result of multiplication of the two specified 64bit integers.

May use CPU native instructions for speed of standard uint64_t multiplication.

Parameters
[in]xFirst number to multiply.
[in]ySecond number to multiply.
[out]hiA reference to 64bit integer that will store higher 64bits of the result.
Returns
The lower 64bit of the result.

◆ 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 occurred 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 occurred 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 interface 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 occurred 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 occurred 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 interface 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 occurred 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 occurred 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.

◆ random_64()

static uint64_t ut::random_64 ( )
inlinestatic

The following function generates pseudo-random 64bit integers which enumerate the value space generated by a linear congruence.

This is very similar to what can be achieved with std::linear_congruential_engine<uint64_t, ...>. If you need reliably good pseudo-random numbers for some reason, please consider using std::mersenne_twister_engine<>.

Returns
a pseudo-random number

◆ random_64_fast()

static uint64_t ut::random_64_fast ( )
inlinestatic

The following function returns fine clock count as random value.

This is used for cases which need performance more than the true randomness. It is not causing any loads or stores, so it is very CPU-cache-friendly. Even for very frequent use, it doesn't cause any CPU cache pollution.

Returns
a pseudo-random number

◆ random_from_interval()

static uint64_t ut::random_from_interval ( uint64_t  low,
uint64_t  high 
)
inlinestatic

Generates a pseudo-random integer from a given interval.

Parameters
[in]lowlow limit; can generate also this value
[in]highhigh limit; can generate also this value
Returns
the pseudo-random number within the [low, high] two-side inclusive range

◆ random_from_interval_fast()

static uint64_t ut::random_from_interval_fast ( uint64_t  low,
uint64_t  high 
)
inlinestatic

Generates a light-weight pseudo-random integer from a given interval.

This is used for the cases which need performance more than the true randomness.

Parameters
[in]lowlow limit; can generate also this value
[in]highhigh limit; can generate also this value
Returns
the pseudo-random number within the [low, high] two-side inclusive range

◆ random_from_interval_gen()

template<uint64_t random_64_func>
static uint64_t ut::random_from_interval_gen ( uint64_t  low,
uint64_t  high 
)
inlinestatic

◆ 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.

◆ INNODB_KERNEL_PAGE_SIZE_DEFAULT

constexpr size_t ut::INNODB_KERNEL_PAGE_SIZE_DEFAULT = 4 * 1024
constexpr

Default kernel page size (not assuming huge pages support).

◆ 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

◆ this_thread_hash

const thread_local size_t ut::this_thread_hash
inline
Initial value:
=
std::hash<std::thread::id>{}(std::this_thread::get_id())
pid_type get_id()
Definition: process.h:48

The hash value of the current thread's id.

◆ WITH_PFS_MEMORY

constexpr bool ut::WITH_PFS_MEMORY = true
constexpr