MySQL 8.4.3
Source Code Documentation
|
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 | Sharded_bitset |
A Sharded_bitset<SHARDS_COUNT>(n) is like a bitset<n> in that it represents a vector of n bits, which can be set(pos) or reset(pos) for 0<=pos<n. 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 | |
template<typename T > | |
constexpr T | div_ceil (T numerator, T denominator) |
Computes the result of division rounded towards positive infinity. More... | |
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 > | |
T | 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... | |
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.
using ut::list = typedef std::list<T, ut::allocator<T> > |
Specialization of list which uses ut_allocator.
using ut::map = typedef std::map<Key, Value, Compare, ut::allocator<std::pair<const Key, Value> >> |
Specialization of map which uses ut_allocator.
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.
using ut::set = typedef std::set<Key, Compare, ut::allocator<Key> > |
Specialization of set which uses ut_allocator.
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)
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)
using ut::unordered_map = typedef std::unordered_map<Key, Value, Hash, Key_equal, ut::allocator<std::pair<const Key, Value> >> |
using ut::unordered_set = typedef std::unordered_set<Key, std::hash<Key>, std::equal_to<Key>, ut::allocator<Key> > |
using ut::vector = typedef std::vector<T, ut::allocator<T> > |
Specialization of vector which uses allocator.
|
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.
[in] | size | Size of storage (in bytes) requested to be allocated. |
[in] | alignment | Alignment requirement for storage to be allocated. |
Example: int* x = static_cast<int*>(aligned_alloc(10*sizeof(int), 64));
|
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | size | Size of storage (in bytes) requested to be allocated. |
[in] | alignment | Alignment requirement for storage to be allocated. |
Example: int* x = static_cast<int*>(aligned_alloc_withkey(key, 10*sizeof(int), 64));
|
inlinenoexcept |
Releases storage which has been dynamically allocated through any of the aligned_new_*() variants.
Destructs the object of type T.
[in] | ptr | Pointer which has been obtained through any of the aligned_new_*() variants |
Example: aligned_delete(ptr);
|
inlinenoexcept |
Releases storage which has been dynamically allocated through any of the aligned_new_arr_*() variants.
Destructs all objects of type T.
[in] | ptr | Pointer which has been obtained through any of the aligned_new_arr_*() variants. |
Example: aligned_delete_arr(ptr);
|
inlinenoexcept |
Releases storage which has been dynamically allocated through any of the aligned_alloc_*() or aligned_zalloc_*() variants.
[in] | ptr | Pointer which has been obtained through any of the aligned_alloc_*() or aligned_zalloc_*() variants. |
Example: aligned_free(ptr);
|
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.
[in] | alignment | Alignment requirement for storage to be allocated. |
[in] | args | Arguments one wishes to pass over to T constructor(s) |
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);
|
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.
[in] | alignment | Alignment requirement for storage to be allocated. |
[in] | args | Arguments one wishes to pass over to T constructor(s) |
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);
|
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.
[in] | alignment | Alignment requirement for storage to be allocated. |
[in] | count | Number of T elements in an array. |
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
|
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | alignment | Alignment requirement for storage to be allocated. |
[in] | args | Tuples of arguments one wishes to pass over to T constructor(s). |
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);
|
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | alignment | Alignment requirement for storage to be allocated. |
[in] | count | Number of T elements in an array. |
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});
|
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | alignment | Alignment requirement for storage to be allocated. |
[in] | args | Arguments one wishes to pass over to T constructor(s) |
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);
|
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.
[in] | size | Size of storage (in bytes) requested to be allocated. |
[in] | alignment | Alignment requirement for storage to be allocated. |
Example: int* x = static_cast<int*>(aligned_zalloc(10*sizeof(int), 64));
|
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | size | Size of storage (in bytes) requested to be allocated. |
[in] | alignment | Alignment requirement for storage to be allocated. |
Example: int* x = static_cast<int*>(aligned_zalloc_withkey(key, 10*sizeof(int), 64));
|
inlinenoexcept |
Releases storage which has been dynamically allocated through any of the ut::new*() variants.
Destructs the object of type T.
[in] | ptr | Pointer which has been obtained through any of the ut::new*() variants |
Example: ut::delete_(ptr);
|
inlinenoexcept |
Releases storage which has been dynamically allocated through any of the ut::new_arr*() variants.
Destructs all objects of type T.
[in] | ptr | Pointer which has been obtained through any of the ut::new_arr*() variants |
Example: ut::delete_arr(ptr);
|
constexpr |
Computes the result of division rounded towards positive infinity.
[in] | numerator | The number you want to be divided |
[in] | denominator | The number you want to divide by |
|
inlinestatic |
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.
[in] | n | positive number > 100 |
|
inlinenoexcept |
Releases storage which has been dynamically allocated through any of the ut::malloc*(), ut::realloc* or ut::zalloc*() variants.
[in] | ptr | Pointer which has been obtained through any of the ut::malloc*(), ut::realloc* or ut::zalloc*() variants. |
Example: ut::free(ptr);
|
inlinenoexcept |
Releases storage which has been dynamically allocated through any of the ut::malloc_large_page*() variants.
[in] | ptr | Pointer which has been obtained through any of the ut::malloc_large_page*() variants. |
Example: ut::free_large_page(ptr);
|
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.
[in] | ptr | Pointer which has been obtained through any of the ut::malloc_large_page*(fallback_to_normal_page_t) variants. |
Example: ut::free_large_page(ptr);
|
inlinenoexcept |
Releases storage which has been dynamically allocated through any of the ut::malloc_page*() variants.
[in] | ptr | Pointer which has been obtained through any of the ut::malloc_page*() variants. |
Example: ut::free_page(ptr);
|
inlinestatic |
Hashes a binary buffer of given length.
[in] | buf | buffer of bytes |
[in] | len | length |
[in] | seed | seed to be used in calculation. Can be previous value. A default value is just a randomly chosen number. |
|
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.
[in] | str | buffer of bytes |
[in] | len | length |
|
inlinestatic |
Hashes a character string ending in the null character.
|
inlinestatic |
Hashes a 64-bit integer.
[in] | value | 64-bit integer |
|
inlinestatic |
Hashes a pair of 64bit integers.
[in] | n1 | first 64bit integer |
[in] | n2 | second 64bit integer |
bool ut::is_aligned_as | ( | void const *const | ptr | ) |
Checks if the pointer has address aligned properly for a given type.
[in] | ptr | The pointer, address of which we want to check if it could be pointing to object of type T. |
|
inline |
Checks if memory range is all zeros.
[in] | start | The pointer to first byte of a buffer |
[in] | number_of_bytes | The number of bytes in the buffer |
number_of_bytes
bytes pointed by start
are all zeros.
|
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.
[in] | ptr | Pointer which has been obtained through any of the ut::malloc_large_page*() variants. |
Example: int x = static_cast<int>(ut::malloc_large_page(10*sizeof(int))); assert(large_page_allocation_size(x) == HUGE_PAGE_SIZE);
|
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).
[in] | ptr | Pointer which has been obtained through any of the ut::malloc_large_page*(fallback_to_normal_page_t) variants. |
|
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.
[in] | ptr | Pointer which has been obtained through any of the ut::malloc_large_page*() variants. |
|
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.
[in] | ptr | Pointer which has been obtained through any of the ut::malloc_large_page*(fallback_to_normal_page_t) variants. |
|
inline |
Convenience helper function to create type-safe representation of PSI_memory_key.
[in] | key | PSI memory key to be held in type-safe PSI_memory_key_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.
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.
[in] | args | Arguments one wishes to pass over to T constructor(s) . |
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | args | Arguments one wishes to pass over to T constructor(s) . |
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | size | Size of the array of objects T to allocate. |
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.
[in] | size | Size of the array of objects T to allocate. |
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | alignment | Alignment requirement for storage to be allocated. |
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | alignment | Alignment requirement for storage to be allocated. |
[in] | args | Arguments one wishes to pass over to T constructor(s) . |
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | alignment | Alignment requirement for storage to be allocated. |
[in] | size | Size of the array of objects T to allocate. |
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.
[in] | alignment | Alignment requirement for storage to be allocated. |
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.
[in] | alignment | Alignment requirement for storage to be allocated. |
[in] | args | Arguments one wishes to pass over to T constructor(s) . |
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.
[in] | alignment | Alignment requirement for storage to be allocated. |
[in] | size | Size of the array of objects T to allocate. |
|
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
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.
[in] | args | Arguments one wishes to pass over to T constructor(s) . |
|
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
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | args | Arguments one wishes to pass over to T constructor(s) . |
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.
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.
|
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
|
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
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | alignment | Alignment requirement for storage to be allocated. |
[in] | args | Arguments one wishes to pass over to T constructor(s) . |
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | alignment | Alignment requirement for storage to be allocated. |
[in] | size | Size of the array of objects T to allocate. |
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.
[in] | alignment | Alignment requirement for storage to be allocated. |
[in] | args | Arguments one wishes to pass over to T constructor(s) . |
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.
[in] | alignment | Alignment requirement for storage to be allocated. |
[in] | size | Size of the array of objects T to allocate. |
|
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.
[in] | size | Size of storage (in bytes) requested to be allocated. |
Example: int x = static_cast<int>(ut::malloc_withkey(UT_NEW_THIS_FILE_PSI_KEY, 10*sizeof(int)));
|
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.
[in] | size | Size of storage (in bytes) requested to be allocated. |
Example: int x = static_cast<int>(ut::malloc_large_page(10*sizeof(int)));
|
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.
[in] | size | Size of storage (in bytes) requested to be allocated. |
[in] | large_pages_enabled | If true, the large pages will be tried to be used. |
Example: int x = static_cast<int>( ut::malloc_large_page( 10*sizeof(int), fallback_to_normal_page_t{} ) );
|
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | size | Size of storage (in bytes) requested to be allocated. |
Example: int x = static_cast<int>( ut::malloc_large_page_withkey(key, 10*sizeof(int)) );
|
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | size | Size of storage (in bytes) requested to be allocated. |
[in] | large_pages_enabled | If true, the large pages will be tried to be used. |
Example: int x = static_cast<int>( ut::malloc_large_page_withkey( key, 10*sizeof(int), fallback_to_normal_page_t{} ) );
|
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.
[in] | size | Size of storage (in bytes) requested to be allocated. |
Example: int x = static_cast<int>(ut::malloc_page(10*sizeof(int)));
|
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
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | size | Size of storage (in bytes) requested to be allocated. |
Example: int x = static_cast<int>(ut::malloc_page_withkey(key, 10*sizeof(int)));
|
inlinenoexcept |
Dynamically allocates storage of given size.
Instruments the memory with given PSI memory key in case PFS memory support is enabled.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | size | Size of storage (in bytes) requested to be allocated. |
Example: int x = static_cast<int>(ut::malloc_withkey(key, 10*sizeof(int)));
|
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.
[in] | x | First number to multiply. |
[in] | y | Second number to multiply. |
[out] | hi | A reference to 64bit integer that will store higher 64bits of the result. |
|
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.
[in] | args | Arguments one wishes to pass over to T constructor(s) |
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);
|
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.
[in] | args | Tuples of arguments one wishes to pass over to T constructor(s). |
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);
|
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.
[in] | count | Number of T elements in an array. |
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});
|
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | args | Tuples of arguments one wishes to pass over to T constructor(s). |
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);
|
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | count | Number of T elements in an array. |
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});
|
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.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | args | Arguments one wishes to pass over to T constructor(s) |
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);
|
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).
[in] | ptr | Pointer which has been obtained through any of the ut::malloc_page*() variants. |
Example: int x = static_cast<int>(ut::malloc_page(10*sizeof(int))); assert(page_allocation_size(x) == CPU_PAGE_SIZE);
|
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.
[in] | ptr | Pointer which has been obtained through any of the ut::malloc_page*() variants. |
|
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.
|
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<>.
|
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.
|
inlinestatic |
Generates a pseudo-random integer from a given interval.
[in] | low | low limit; can generate also this value |
[in] | high | high limit; can generate also this value |
|
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.
[in] | low | low limit; can generate also this value |
[in] | high | high limit; can generate also this value |
|
inlinestatic |
|
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.
[in] | ptr | Pointer to the memory area to be reallocated. |
[in] | size | New size of storage (in bytes) requested to be reallocated. |
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)));
|
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
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | ptr | Pointer to the memory area to be reallocated. |
[in] | size | New size of storage (in bytes) requested to be reallocated. |
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)));
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.
cond | in: condition to wait for; evaluated every 2 ms |
max_wait | in: maximum delay to wait |
|
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).
[in] | spins_limit | maximum iterations without sleep |
[in] | sleep | initial sleep time |
[in] | condition | returns true when condition is satisfied |
|
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.
[in] | size | Size of storage (in bytes) requested to be allocated. |
Example: int x = static_cast<int>(ut::zalloc_withkey(UT_NEW_THIS_FILE_PSI_KEY, 10*sizeof(int)));
|
inlinenoexcept |
Dynamically allocates zero-initialized storage of given size.
Instruments the memory with given PSI memory key in case PFS memory support is enabled.
[in] | key | PSI memory key to be used for PFS memory instrumentation. |
[in] | size | Size of storage (in bytes) requested to be allocated. |
Example: int x = static_cast<int>(ut::zalloc_withkey(key, 10*sizeof(int)));
|
constexpr |
CPU cache line size.
|
constexpr |
Default kernel page size (not assuming huge pages support).
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
|
inline |
The hash value of the current thread's id.
|
constexpr |