1 #include "hmbdc/Copyright.hpp" 4 #include "hmbdc/os/Allocators.hpp" 5 #include "hmbdc/time/Time.hpp" 6 #include "hmbdc/Config.hpp" 8 #include <condition_variable> 11 namespace hmbdc {
namespace pattern {
13 namespace classic_buffer_detail {
19 using value_type =
void *;
25 value_type getItem(
size_t seq) {
26 return store_ + seq % capacity_ * maxItemSize_;
29 size_t maxItemSize()
const {
return maxItemSize_;}
30 size_t capacity()
const {
return capacity_;}
31 void put(
void const* item,
size_t sizeHint = 0) {
33 unique_lock<mutex> lck(mutex_);
34 hasSlot_.wait(lck, [
this]{
return capacity_ > size_;});
35 memcpy(getItem(seq_++), item, min(sizeHint, maxItemSize_));
36 if (++size_ == 1) hasItem_.notify_one();
39 template <
typename T,
typename... Ts>
41 put(T&& item, Ts&&... items) {
43 unique_lock<mutex> lck(mutex_);
44 hasSlot_.wait(lck, [
this]{
return capacity_ > size_ +
sizeof...(Ts);});
45 fill(std::forward<T>(item), std::forward<Ts>(items)...);
46 size_ +=
sizeof...(items) + 1;
47 if (size_ ==
sizeof...(items) + 1) hasItem_.notify_one();
50 template <
typename T>
void putSome(T
const& item) {put(&item);}
51 template <
typename T,
typename ...Args>
52 void putInPlace(Args&&... args) {
54 unique_lock<mutex> lck(mutex_);
55 hasSlot_.wait(lck, [
this](){
return capacity_ > size_;});
56 new (getItem(seq_++)) T(std::forward<Args>(args)...);
57 if (++size_ == 1) hasItem_.notify_one();
59 template <
typename T,
typename ...Args>
60 bool tryPutInPlace(Args&&... args) {
62 unique_lock<mutex> lck(mutex_);
63 if (!hasSlot_.wait_for(lck, chrono::seconds(0), [
this](){return capacity_ > size_;}))
65 new (getItem(seq_++)) T(std::forward<Args>(args)...);
66 if (++size_ == 1) hasItem_.notify_one();
70 bool tryPut(
void const* item,
size_t sizeHint = 0) {
72 unique_lock<mutex> lck(mutex_);
73 if (!hasSlot_.wait_for(lck, chrono::seconds(0), [
this](){return capacity_ > size_;}))
75 memcpy(getItem(seq_++), item, min(sizeHint, maxItemSize_));
76 if (++size_ == 1) hasItem_.notify_one();
81 bool tryPut(T
const& item) {
82 return tryPut(&item,
sizeof(item));
85 bool isFull()
const {
return size_ == capacity_;}
86 void take(
void *dest,
size_t len = 0) {
88 unique_lock<mutex> lck(mutex_);
89 hasItem_.wait(lck, [
this](){
return size_;});
90 memcpy(dest, getItem(seq_ - size_), min(len, maxItemSize_));
91 if (size_-- == capacity_) hasSlot_.notify_all();
96 take(&dest,
sizeof(T));
100 bool tryTake(
void *dest,
size_t sizeHint = 0) {
102 unique_lock<mutex> lck(mutex_);
103 if (!hasItem_.wait_for(lck, chrono::seconds(0), [
this](){return size_;}))
return false;
104 memcpy(dest, getItem(seq_ - size_), min(sizeHint, maxItemSize_));
105 if (size_-- == capacity_) hasSlot_.notify_all();
109 template <
typename T>
110 bool tryTake(T& dest) {
111 return tryTake(&dest,
sizeof(T));
114 template <
typename itOut>
115 size_t take(itOut b, itOut e) {
117 unique_lock<mutex> lck(mutex_);
118 hasItem_.wait(lck, [
this](){
return size_;});
120 while (s && b != e) {
121 memcpy(&*b++, getItem(seq_ - s--), min(maxItemSize_,
sizeof(*b)));
123 auto ret = size_ - s;
125 if (size_ + ret == capacity_) {
126 hasSlot_.notify_all();
133 void wasteAfterPeek(
size_t len) {
134 std::unique_lock<std::mutex> lck(mutex_);
135 if (size_ == capacity_) hasSlot_.notify_all();
141 unique_lock<mutex> lck(mutex_);
142 hasItem_.wait_for(lck, std::chrono::nanoseconds(timeout.nanoseconds())
143 , [
this](){
return size_;});
146 size_t remainingSize()
const {
152 hasSlot_.notify_all();
157 template <
typename T,
typename... Ts>
159 fill(T&& item, Ts&&... items) {
160 memcpy(getItem(seq_++), &item, maxItemSize_);
161 fill(std::forward<Ts>(items)...);
170 std::condition_variable hasItem_;
171 std::condition_variable hasSlot_;
174 namespace classic_buffer_detail {
177 : buf_(buf), seq_(seq){}
178 iterator() : buf_(
nullptr), seq_(0){}
179 void clear() {buf_ =
nullptr;}
181 iterator& operator ++() HMBDC_RESTRICT {
186 iterator operator ++(
int) HMBDC_RESTRICT {
192 iterator operator + (
size_t dis)
const HMBDC_RESTRICT {
198 iterator& operator += (
size_t dis) HMBDC_RESTRICT {
203 size_t operator - (
iterator const& other)
const HMBDC_RESTRICT {
204 return seq_ - other.seq_;
207 explicit operator bool()
const HMBDC_RESTRICT {
211 bool operator < (
iterator const& other)
const HMBDC_RESTRICT {
212 return seq_ < other.seq_;
215 bool operator == (
iterator const& other)
const HMBDC_RESTRICT {
return seq_ == other.seq_;}
216 bool operator != (
iterator const& other)
const HMBDC_RESTRICT {
return seq_ != other.seq_;}
217 void* operator*()
const HMBDC_RESTRICT {
return buf_->getItem(seq_);}
218 template <
typename T> T&
get()
const HMBDC_RESTRICT {
return *
static_cast<T*
>(**this);}
219 template <
typename T>
220 T* operator->() HMBDC_RESTRICT {
return static_cast<T*
>(buf_->getItem(seq_));}
231 std::unique_lock<std::mutex> lck(mutex_);
241 std::unique_lock<std::mutex> lck(mutex_);
243 return iterator(
this, seq_ - size_);
Definition: BlockingBuffer.hpp:17
Definition: TypedString.hpp:74
Definition: BlockingBuffer.hpp:175