bmv2
Designing your own switch target with bmv2
stacks.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_STACKS_H_
24 #define BM_BM_SIM_STACKS_H_
25 
26 #include <string>
27 #include <vector>
28 
29 #include "headers.h"
30 #include "header_unions.h"
31 #include "named_p4object.h"
32 
33 namespace bm {
34 
35 using header_stack_id_t = p4object_id_t;
36 
45 class StackIface {
46  public:
47  virtual ~StackIface() { }
48 
52  virtual size_t pop_front() = 0;
53 
57  virtual size_t pop_front(size_t num) = 0;
58 
64  virtual size_t push_front() = 0;
65 
72  virtual size_t push_front(size_t num) = 0;
73 
74  virtual size_t pop_back() = 0;
75 
76  // basically, meant to be called by the parser
77  virtual size_t push_back() = 0;
78 
80  virtual size_t get_depth() const = 0;
81 
83  virtual size_t get_count() const = 0;
84 
86  virtual bool is_full() const = 0;
87 
88  virtual void reset() = 0;
89 };
90 
91 // Forward declarations for core action primitives which need to have access to
92 // the stack's internal state (i.e. "next"). These are declared as friends in
93 // the Stack class definition.
94 namespace core {
95 
96 struct assign_header_stack;
97 struct assign_union_stack;
98 
99 } // namespace core
100 
101 // We use CRTP for Stack class to implement either legacy behavior or strict
102 // P4_16 behavior by providing different implementations of push_front and
103 // pop_front.
104 
110 template <typename T, typename ShiftImpl>
111 class Stack : public StackIface, public NamedP4Object {
112  public:
113  friend class PHV;
114  // These core action primitives are friends as they need to have access to the
115  // stack's internal state.
116  friend struct core::assign_header_stack;
117  friend struct core::assign_union_stack;
118 
119  Stack(const std::string &name, p4object_id_t id);
120 
121  size_t pop_front() override;
122  size_t pop_front(size_t num) override;
123 
124  size_t push_front() override;
125  size_t push_front(size_t num) override;
126 
127  size_t pop_back() override;
128 
129  size_t push_back() override;
130 
131  size_t get_depth() const override;
132  size_t get_count() const override;
133  bool is_full() const override;
134 
135  void reset() override;
136 
137  T &get_last();
138  const T &get_last() const;
139 
140  T &get_next();
141  const T &get_next() const;
142 
143  T &at(size_t idx);
144  const T &at(size_t idx) const;
145 
146  protected:
147  using TRef = std::reference_wrapper<T>;
148 
149  // To be called by PHV class
150  // This is a special case, as I want to store a reference
151  // NOLINTNEXTLINE
152  void set_next_element(T &e);
153 
154  std::vector<TRef> elements{};
155  // first empty index; if next == headers.size(), stack is full
156  size_t next{0};
157 };
158 
159 namespace detail {
160 
161 // Implements legacy behavior for stacks. push_front and pop_front only shift
162 // the portion of the stack up to the next index. Pushed elements are marked as
163 // valid.
164 template <typename T>
165 class StackLegacy : public Stack<T, StackLegacy<T> > {
166  public:
167  StackLegacy(const std::string &name, p4object_id_t id);
168 
169  size_t pop_front();
170  size_t pop_front(size_t num);
171 
172  size_t push_front();
173  size_t push_front(size_t num);
174 };
175 
176 // Implements strict P4_16 behavior for stacks. push_front and pop_front shift
177 // the entire stack. Pushed elements are marked as invalid.
178 template <typename T>
179 class StackP4_16 : public Stack<T, StackP4_16<T> > {
180  public:
181  StackP4_16(const std::string &name, p4object_id_t id);
182 
183  size_t pop_front();
184  size_t pop_front(size_t num);
185 
186  size_t push_front();
187  size_t push_front(size_t num);
188 };
189 
190 #ifdef BM_WP4_16_STACKS
191 template <typename T>
192 // using MyStack = StackP4_16<T>;
193 using MyStack = StackP4_16<T>;
194 #else
195 template <typename T>
196 using MyStack = StackLegacy<T>;
197 #endif // BM_WP4_16_STACKS
198 
199 } // namespace detail
200 
201 using header_stack_id_t = p4object_id_t;
202 using header_union_stack_id_t = p4object_id_t;
203 
212 using HeaderStack = detail::MyStack<Header>;
223 using HeaderUnionStack = detail::MyStack<HeaderUnion>;
224 
225 #undef _P4_16_STACKS
226 
227 } // namespace bm
228 
229 #endif // BM_BM_SIM_STACKS_H_
bm::NamedP4Object
Definition: named_p4object.h:39
bm::Stack::push_front
size_t push_front() override
bm::StackIface::get_count
virtual size_t get_count() const =0
Returns the current occupancy of the stack.
header_unions.h
bm::StackIface::pop_front
virtual size_t pop_front()=0
headers.h
bm::StackIface
Definition: stacks.h:45
named_p4object.h
bm::StackIface::push_front
virtual size_t push_front()=0
bm::Stack::get_count
size_t get_count() const override
Returns the current occupancy of the stack.
bm::HeaderStack
detail::MyStack< Header > HeaderStack
Definition: stacks.h:212
bm::Stack::is_full
bool is_full() const override
Returns true if the header stack is full.
bm::Stack
Definition: stacks.h:111
bm::Stack::pop_front
size_t pop_front() override
bm::HeaderUnionStack
detail::MyStack< HeaderUnion > HeaderUnionStack
Definition: stacks.h:223
bm::Stack::get_depth
size_t get_depth() const override
Returns the maximum capacity of the stack.
bm::StackIface::get_depth
virtual size_t get_depth() const =0
Returns the maximum capacity of the stack.
bm::StackIface::is_full
virtual bool is_full() const =0
Returns true if the header stack is full.
bm::PHV
Definition: phv.h:68