bmv2
Designing your own switch target with bmv2
Loading...
Searching...
No Matches
header_unions.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_HEADER_UNIONS_H_
24#define BM_BM_SIM_HEADER_UNIONS_H_
25
26#include <algorithm> // std::swap
27#include <functional> // std::reference_wrapper
28#include <string>
29#include <utility>
30#include <vector>
31
32#include "named_p4object.h"
33#include "headers.h"
34
35namespace bm {
36
37using header_union_id_t = p4object_id_t;
38
51class HeaderUnion : public NamedP4Object {
52 public:
53 friend class PHV;
54
55 HeaderUnion(const std::string &name, p4object_id_t id)
56 : NamedP4Object(name, id) { }
57
58 void make_header_valid(size_t new_valid_idx) {
59 if (valid && valid_header_idx != new_valid_idx)
60 headers[valid_header_idx].get().mark_invalid();
61 valid_header_idx = new_valid_idx;
62 valid = true;
63 // the caller is responsible for making the new header valid
64 }
65
66 void make_header_invalid(size_t idx) {
67 if (valid && valid_header_idx == idx) valid = false;
68 }
69
70 // used for stacks of header unions
71 void swap_values(HeaderUnion *other) {
72 assert(headers.size() == other->headers.size());
73 std::swap(valid, other->valid);
74 std::swap(valid_header_idx, other->valid_header_idx);
75 // this is probably too conservative, I think we only need to swap valid
76 // headers, but this is a good place to start
77 for (size_t i = 0; i < headers.size(); i++)
78 headers[i].get().swap_values(&other->headers[i].get());
79 }
80
84 return valid ? &headers[valid_header_idx].get() : nullptr;
85 }
86
88 size_t get_num_headers() const { return headers.size(); }
89
92 Header &at(size_t idx) { return headers.at(idx); }
94 const Header &at(size_t idx) const { return headers.at(idx); }
95
96 // compare to another union instance; returns true iff both unions are valid,
97 // and the valid headers are the same in both unions.
98 bool cmp(const HeaderUnion &other) const;
99
101 bool is_valid() const { return valid; }
102
103 // no-ops on purpose
104 void mark_invalid() { }
105 void mark_valid() { }
106
107 private:
108 // To be called by PHV class
109 // This is a special case, as I want to store a reference
110 // NOLINTNEXTLINE
111 void set_next_header(Header &h) {
112 headers.emplace_back(h);
113 }
114
115 using HeaderRef = std::reference_wrapper<Header>;
116
117 std::vector<HeaderRef> headers{};
118 bool valid{false};
119 size_t valid_header_idx{0};
120};
121
122} // namespace bm
123
124#endif // BM_BM_SIM_HEADER_UNIONS_H_
Definition header_unions.h:51
size_t get_num_headers() const
Returns the number of headers included in the union.
Definition header_unions.h:88
Header * get_valid_header() const
Definition header_unions.h:83
bool is_valid() const
Returns true if one of the headers in the union is valid.
Definition header_unions.h:101
const Header & at(size_t idx) const
Definition header_unions.h:94
Header & at(size_t idx)
Definition header_unions.h:92
Definition headers.h:147
Definition named_p4object.h:39
Definition phv.h:68