bmv2
Designing your own switch target with bmv2
queue.h
Go to the documentation of this file.
1 /* Copyright 2013-present Barefoot Networks, Inc.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 /*
17  * Antonin Bas (antonin@barefootnetworks.com)
18  *
19  */
20 
22 
23 #ifndef BM_BM_SIM_QUEUE_H_
24 #define BM_BM_SIM_QUEUE_H_
25 
26 #include <condition_variable>
27 #include <deque>
28 #include <mutex>
29 #include <utility>
30 
31 namespace bm {
32 
33 /* TODO(antonin): implement non blocking read behavior */
34 
41 template <class T>
42 class Queue {
43  public:
50  };
52  enum ReadBehavior {
57  };
58 
59  public:
60  Queue()
61  : capacity(1024), wb(WriteBlock), rb(ReadBlock) { }
62 
64  Queue(size_t capacity,
66  : capacity(capacity), wb(wb), rb(rb) {}
67 
69  void push_front(const T &item) {
70  std::unique_lock<std::mutex> lock(q_mutex);
71  while (!is_not_full()) {
72  if (wb == WriteReturn) return;
73  q_not_full.wait(lock);
74  }
75  queue.push_front(item);
76  lock.unlock();
77  q_not_empty.notify_one();
78  }
79 
81  void push_front(T &&item) {
82  std::unique_lock<std::mutex> lock(q_mutex);
83  while (!is_not_full()) {
84  if (wb == WriteReturn) return;
85  q_not_full.wait(lock);
86  }
87  queue.push_front(std::move(item));
88  lock.unlock();
89  q_not_empty.notify_one();
90  }
91 
93  void pop_back(T* pItem) {
94  std::unique_lock<std::mutex> lock(q_mutex);
95  while (!is_not_empty())
96  q_not_empty.wait(lock);
97  *pItem = std::move(queue.back());
98  queue.pop_back();
99  lock.unlock();
100  q_not_full.notify_one();
101  }
102 
104  size_t size() const {
105  std::unique_lock<std::mutex> lock(q_mutex);
106  return queue.size();
107  }
108 
110  void set_capacity(const size_t c) {
111  // change capacity but does not discard elements
112  std::unique_lock<std::mutex> lock(q_mutex);
113  capacity = c;
114  }
115 
117  Queue(const Queue &) = delete;
119  Queue &operator =(const Queue &) = delete;
120 
122  Queue(Queue &&) = delete;
124  Queue &&operator =(Queue &&) = delete;
125 
126  private:
127  bool is_not_empty() const { return queue.size() > 0; }
128  bool is_not_full() const { return queue.size() < capacity; }
129 
130  size_t capacity;
131  std::deque<T> queue;
132  WriteBehavior wb;
133  ReadBehavior rb;
134 
135  mutable std::mutex q_mutex;
136  mutable std::condition_variable q_not_empty;
137  mutable std::condition_variable q_not_full;
138 };
139 
140 } // namespace bm
141 
142 #endif // BM_BM_SIM_QUEUE_H_
bm::Queue::operator=
Queue & operator=(const Queue &)=delete
Deleted copy assignment operator.
bm::Queue
Definition: queue.h:42
bm::Queue::push_front
void push_front(const T &item)
Makes a copy of item and pushes it to the front of the queue.
Definition: queue.h:69
bm::Queue::WriteBehavior
WriteBehavior
Implementation behavior when an item is pushed to a full queue.
Definition: queue.h:45
bm::Queue::WriteBlock
@ WriteBlock
block and wait until a slot is available
Definition: queue.h:47
bm::Queue::size
size_t size() const
Get queue occupancy.
Definition: queue.h:104
bm::Queue::ReadBlock
@ ReadBlock
block and wait until the queue becomes non-empty
Definition: queue.h:54
bm::Queue::WriteReturn
@ WriteReturn
return immediately
Definition: queue.h:49
bm::Queue::ReadBehavior
ReadBehavior
Implementation behavior when an element is popped from an empty queue.
Definition: queue.h:52
bm::Queue::push_front
void push_front(T &&item)
Moves item to the front of the queue.
Definition: queue.h:81
bm::Queue::ReadReturn
@ ReadReturn
not implemented yet
Definition: queue.h:56
bm::Queue::Queue
Queue(size_t capacity, WriteBehavior wb=WriteBlock, ReadBehavior rb=ReadBlock)
Constructs a queue with specified capacity and read / write behaviors.
Definition: queue.h:64
bm::Queue::pop_back
void pop_back(T *pItem)
Pops an element from the back of the queue: moves the element to *pItem.
Definition: queue.h:93
bm::Queue::set_capacity
void set_capacity(const size_t c)
Change the capacity of the queue.
Definition: queue.h:110