hmbdc
simplify-high-performance-messaging-programming
LockFreeBufferMisc.hpp
1 #include "hmbdc/Copyright.hpp"
2 #pragma once
3 
4 #include "hmbdc/os/Allocators.hpp"
5 #include <stdint.h>
6 #include <stddef.h>
7 #include <malloc.h>
8 #include <stdlib.h>
9 #include <memory.h>
10 
11 #include <utility>
12 #include <stdexcept>
13 
14 #include <cstddef>
15 
16 #ifndef SMP_CACHE_BYTES
17 #define SMP_CACHE_BYTES 64
18 #endif
19 
20 namespace hmbdc { namespace pattern {
21 namespace lf_misc {
22 
23 struct DeadConsumer : std::runtime_error {
24  DeadConsumer(const std::string& what_arg)
25  : std::runtime_error(what_arg){}
26 };
27 
28 template <typename Seq>
30  template<typename Allocator = os::DefaultAllocator>
31  chunk_base_ptr(uint32_t valueTypeSizePower2Num, uint32_t ringSizePower2Num
32  , Allocator& allocator = os::DefaultAllocator::instance)
33  : space_((char*)allocator.memalign(SMP_CACHE_BYTES, (1u << valueTypeSizePower2Num) * (1u << ringSizePower2Num))
34  - (char*)this)
35  , MASK((1u << ringSizePower2Num) - 1)
36  , valueTypeSizePower2Num_(valueTypeSizePower2Num)
37  , allocateFromHeap_(Allocator::fromHeap) {
38  }
39 
40  static size_t footprint(uint32_t valueTypeSizePower2Num, uint32_t ringSizePower2Num) {
41  return sizeof(chunk_base_ptr) + SMP_CACHE_BYTES * 2
42  + (1u << valueTypeSizePower2Num) * (1u << ringSizePower2Num);
43  }
44 
45  ~chunk_base_ptr() {
46  if (allocateFromHeap_) {
47  ::free(((char* const)this) + space_);
48  }
49  }
50 
51  void* operator + (size_t index) const __restrict__ {
52  return (((char* const)this) + space_) + (index << valueTypeSizePower2Num_) + sizeof(Seq);
53  }
54 
55  Seq* getSeq(size_t index) const __restrict__ {
56  return reinterpret_cast<Seq*>((((char* const)this) + space_) + (index << valueTypeSizePower2Num_));
57  }
58 
59  friend
60  size_t operator - (void const* __restrict__ from, chunk_base_ptr<Seq> const& __restrict__ start) {
61  return (static_cast<char const*>(from) - sizeof(Seq) - (((char* const)&start) + start.space_))
62  >> start.valueTypeSizePower2Num_;
63  }
64  std::ptrdiff_t const space_;
65  Seq const MASK;
66  uint32_t const valueTypeSizePower2Num_;
67  bool allocateFromHeap_;
68  chunk_base_ptr(chunk_base_ptr<Seq> const&) = delete;
69  chunk_base_ptr& operator = (chunk_base_ptr<Seq> const&) = delete;
70 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
71 
72 template <typename Seq>
73 struct iterator {
74  using Sequence = Seq;
75  chunk_base_ptr<Seq> const * __restrict__ start_;
76  Seq seq_;
77 
78  //this ctor is only used by LockFreeBuffer itself
79  iterator(chunk_base_ptr<Seq> const& __restrict__ start, Seq seq)
80  : start_(&start), seq_(seq){}
81  iterator() : start_(nullptr), seq_(0){}
82  Seq seq() const {return seq_;}
83  void clear() {start_ = nullptr;}
84 
85  iterator& operator ++() __restrict__ {
86  ++seq_;
87  return *this;
88  }
89 
90  iterator operator ++(int) __restrict__ {
91  iterator tmp = *this;
92  ++*this;
93  return tmp;
94  }
95 
96  iterator operator + (size_t dis) const __restrict__ {
97  iterator tmp = *this;
98  tmp.seq_ += dis;
99  return tmp;
100  }
101 
102  size_t operator - (iterator const& other) const __restrict__ {
103  return seq_ - other.seq_;
104  }
105 
106  explicit operator bool() const __restrict__ {
107  return start_;
108  }
109 
110  bool operator < (iterator const& other) const __restrict__ {
111  return seq_ < other.seq_;
112  }
113 
114  bool operator == (iterator const& other) const __restrict__ {return seq_ == other.seq_;}
115  bool operator != (iterator const& other) const __restrict__ {return seq_ != other.seq_;}
116  void* operator*() const __restrict__ {return *start_ + (seq_ & start_->MASK);}
117  template <typename T> T& get() const __restrict__ { return *static_cast<T*>(**this); }
118  template <typename T>
119  T* operator->() __restrict__ {return static_cast<T*>(*start_ + (seq_ & start_->MASK));}
120 };
121 
122 } //lf_misc
123 }}
Definition: LockFreeBufferMisc.hpp:29
Definition: LockFreeBufferMisc.hpp:23
Definition: Client.hpp:11
Definition: LockFreeBufferMisc.hpp:73