77template <
typename Position = u
int64_t>
 
  110  void add_link(Position from, Position to);
 
  132  template <
typename Stop_condition>
 
  134                          uint32_t max_retry = 1);
 
  148  Position 
tail() 
const;
 
  197template <
typename Position>
 
  199    : m_capacity(capacity), m_tail(0) {
 
  210  for (
size_t i = 0; i < 
capacity; ++i) {
 
  215template <
typename Position>
 
  218template <
typename Position>
 
  220    : m_capacity(rhs.m_capacity), m_tail(rhs.m_tail.
load()) {
 
  222  rhs.m_links = 
nullptr;
 
  225template <
typename Position>
 
  229  m_capacity = rhs.m_capacity;
 
  231  m_tail.store(rhs.m_tail.load());
 
  233  m_links = rhs.m_links;
 
  234  rhs.m_links = 
nullptr;
 
  239template <
typename Position>
 
  244template <
typename Position>
 
  246  if (m_links != 
nullptr) {
 
  252template <
typename Position>
 
  255  ut_ad(to - from <= std::numeric_limits<Distance>::max());
 
  257  const auto index = slot_index(from);
 
  259  auto &slot = m_links[index];
 
  264template <
typename Position>
 
  267  const auto index = slot_index(position);
 
  269  auto &slot = m_links[index];
 
  271  next = slot.load(std::memory_order_relaxed);
 
  273  return next <= position;
 
  276template <
typename Position>
 
  280  ut_ad(to - from <= std::numeric_limits<Distance>::max());
 
  282  auto position = m_tail.load(std::memory_order_acquire);
 
  284  ut_ad(position <= from);
 
  286  if (position == from) {
 
  288    m_tail.store(to, std::memory_order_release);
 
  290    auto index = slot_index(from);
 
  291    auto &slot = m_links[index];
 
  294    slot.store(to, std::memory_order_release);
 
  296    auto stop_condition = [&](Position prev_pos, Position) {
 
  297      return (prev_pos > from);
 
  300    advance_tail_until(stop_condition);
 
  304template <
typename Position>
 
  305template <
typename Stop_condition>
 
  307                                            uint32_t max_retry) {
 
  309  auto position = m_tail.load(std::memory_order_acquire);
 
  310  auto from = position;
 
  314    auto index = slot_index(position);
 
  315    auto &slot = m_links[index];
 
  317    auto next_load = slot.load(std::memory_order_acquire);
 
  319    if (next_load >= position + m_capacity) {
 
  322      position = m_tail.load(std::memory_order_acquire);
 
  323      if (position != from) {
 
  329    if (next_load <= position || stop_condition(position, next_load)) {
 
  335    if (slot.compare_exchange_strong(next_load, position,
 
  336                                     std::memory_order_acq_rel)) {
 
  342      position = m_tail.load(std::memory_order_acquire);
 
  343      if (position == from) {
 
  345        position = next_load;
 
  351    if (
retry > max_retry) {
 
  357    position = m_tail.load(std::memory_order_acquire);
 
  358    if (position == from) {
 
  368    bool stop = next_position(position, next);
 
  370    if (stop || stop_condition(position, next)) {
 
  377  ut_a(from == m_tail.load(std::memory_order_acquire));
 
  380  m_tail.store(position, std::memory_order_release);
 
  382  if (position == from) {
 
  389template <
typename Position>
 
  391  auto stop_condition = [](Position, Position) { 
return false; };
 
  393  return advance_tail_until(stop_condition);
 
  396template <
typename Position>
 
  401template <
typename Position>
 
  403  return m_tail.load(std::memory_order_acquire);
 
  406template <
typename Position>
 
  408  auto tail = m_tail.load(std::memory_order_acquire);
 
  409  if (tail + m_capacity > position) {
 
  413  auto stop_condition = [](Position, Position) { 
return false; };
 
  414  advance_tail_until(stop_condition, 0);
 
  416  tail = m_tail.load(std::memory_order_acquire);
 
  417  return tail + m_capacity > position;
 
  420template <
typename Position>
 
  422  return position & (m_capacity - 1);
 
  425template <
typename Position>
 
  427  const auto tail = m_tail.load();
 
  434    const size_t index = slot_index(
begin);
 
  436    const auto &slot = m_links[index];
 
  438    ut_a(slot.load() <= tail);
 
  442template <
typename Position>
 
  444  validate_no_links(0, m_capacity);
 
Concurrent data structure, which allows to track concurrently performed operations which locally migh...
Definition: ut0link_buf.h:78
 
bool advance_tail_until(Stop_condition stop_condition, uint32_t max_retry=1)
Advances the tail pointer in the buffer by following connected path created by links.
Definition: ut0link_buf.h:306
 
std::atomic< Position > m_tail
Tail pointer in the buffer (expressed in original unit).
Definition: ut0link_buf.h:194
 
Link_buf & operator=(const Link_buf &rhs)=delete
 
void add_link(Position from, Position to)
Add a directed link between two given positions.
Definition: ut0link_buf.h:253
 
~Link_buf()
Destructs the link buffer.
Definition: ut0link_buf.h:240
 
size_t m_capacity
Capacity of the buffer.
Definition: ut0link_buf.h:188
 
void add_link_advance_tail(Position from, Position to)
Add a directed link between two given positions.
Definition: ut0link_buf.h:277
 
bool has_space(Position position)
Checks if there is space to add link at given position.
Definition: ut0link_buf.h:407
 
bool next_position(Position position, Position &next)
Computes next position by looking into slots array and following single link which starts in provided...
Definition: ut0link_buf.h:265
 
void validate_no_links()
Validates (using assertions) that there no links at all.
Definition: ut0link_buf.h:443
 
std::atomic< Distance > * m_links
Pointer to the ring buffer (unaligned).
Definition: ut0link_buf.h:191
 
size_t slot_index(Position position) const
Translates position expressed in original unit to position in the m_links (which is a ring buffer).
Definition: ut0link_buf.h:421
 
Position Distance
Type used to express distance between two positions.
Definition: ut0link_buf.h:83
 
void free()
Deallocated memory, if it was allocated.
Definition: ut0link_buf.h:245
 
bool advance_tail()
Advances the tail pointer in the buffer without additional condition for stop.
Definition: ut0link_buf.h:390
 
Link_buf(const Link_buf &rhs)=delete
 
Link_buf()
Definition: ut0link_buf.h:216
 
Position tail() const
Definition: ut0link_buf.h:402
 
size_t capacity() const
Definition: ut0link_buf.h:397
 
Link_buf & operator=(Link_buf &&rhs)
Definition: ut0link_buf.h:226
 
#define free(A)
Definition: lexyy.cc:915
 
bool load(THD *, const dd::String_type &fname, dd::String_type *buf)
Read an sdi file from disk and store in a buffer.
Definition: sdi_file.cc:308
 
const char * begin(const char *const c)
Definition: base64.h:44
 
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:192
 
constexpr size_t INNODB_CACHE_LINE_SIZE
CPU cache line size.
Definition: ut0cpu_cache.h:41
 
void delete_arr(T *ptr) noexcept
Releases storage which has been dynamically allocated through any of the ut::new_arr*() variants.
Definition: ut0new.h:1110
 
Light-weight and type-safe wrapper which serves a purpose of being able to select proper ut::new_arr*...
Definition: ut0new.h:982
 
Debug utilities for Innobase.
 
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:105
 
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:93
 
Dynamic memory allocation routines and custom allocators specifically crafted to support memory instr...
 
#define UT_NEW_THIS_FILE_PSI_KEY
Definition: ut0new.h:565
 
#define UT_RELAX_CPU()
Definition: ut0ut.h:93
 
static task_env * retry
Definition: xcom_base.cc:436