21 #ifndef BM_BM_SIM_ACTION_PROFILE_H_
22 #define BM_BM_SIM_ACTION_PROFILE_H_
31 #include <boost/thread/shared_mutex.hpp>
33 #include "action_entry.h"
35 #include "handle_mgr.h"
36 #include "match_error_codes.h"
41 class ActionProfile :
public NamedP4Object {
42 friend class MatchTableIndirect;
43 friend class MatchTableIndirectWS;
46 using mbr_hdl_t = uint32_t;
47 using grp_hdl_t = uint32_t;
49 using hash_t =
unsigned int;
55 bool is_mbr()
const {
return ((index >> 24) == _mbr); }
56 bool is_grp()
const {
return ((index >> 24) == _grp); }
57 unsigned int get()
const {
return (index & _index_mask); }
58 unsigned int get_mbr()
const { assert(is_mbr());
return get(); }
59 unsigned int get_grp()
const { assert(is_grp());
return get(); }
61 void dump(std::ostream *stream)
const {
63 (*stream) <<
"group(" << get() <<
")";
65 (*stream) <<
"member(" << get() <<
")";
68 friend std::ostream& operator<<(std::ostream &out,
const IndirectIndex &i) {
73 void serialize(std::ostream *out)
const;
74 void deserialize(std::istream *in,
const P4Objects &objs);
76 static IndirectIndex make_mbr_index(
unsigned int index) {
77 assert(index <= _index_mask);
78 return IndirectIndex((_mbr << 24) | index);
81 static IndirectIndex make_grp_index(
unsigned int index) {
82 assert(index <= _index_mask);
83 return IndirectIndex((_grp << 24) | index);
87 explicit IndirectIndex(
unsigned int index) : index(index) { }
89 static const unsigned char _mbr = 0x00;
90 static const unsigned char _grp = 0x01;
91 static const unsigned int _index_mask = 0x00FFFFFF;
93 unsigned int index{0};
98 const ActionFn *action_fn;
99 ActionData action_data;
104 std::vector<mbr_hdl_t> mbr_handles;
107 class GroupSelectionIface {
109 virtual ~GroupSelectionIface() { }
111 virtual void add_member_to_group(grp_hdl_t grp, mbr_hdl_t mbr) = 0;
112 virtual void remove_member_from_group(grp_hdl_t grp, mbr_hdl_t mbr) = 0;
113 virtual mbr_hdl_t get_from_hash(grp_hdl_t grp, hash_t h)
const = 0;
114 virtual void reset() = 0;
117 ActionProfile(
const std::string &name, p4object_id_t
id,
bool with_selection);
119 bool has_selection()
const;
121 void set_hash(std::unique_ptr<Calculation> h) {
126 void set_group_selector(std::shared_ptr<GroupSelectionIface> selector);
130 MatchErrorCode add_member(
const ActionFn *action_fn,
131 ActionData action_data,
134 MatchErrorCode delete_member(mbr_hdl_t mbr);
136 MatchErrorCode modify_member(mbr_hdl_t mbr,
137 const ActionFn *action_fn,
138 ActionData action_data);
140 MatchErrorCode create_group(grp_hdl_t *grp);
142 MatchErrorCode delete_group(grp_hdl_t grp);
144 MatchErrorCode add_member_to_group(mbr_hdl_t mbr, grp_hdl_t grp);
146 MatchErrorCode remove_member_from_group(mbr_hdl_t mbr, grp_hdl_t grp);
150 MatchErrorCode get_member(mbr_hdl_t mbr, Member *member)
const;
152 std::vector<Member> get_members()
const;
154 MatchErrorCode get_group(grp_hdl_t grp, Group *group)
const;
156 std::vector<Group> get_groups()
const;
158 size_t get_num_members()
const;
159 size_t get_num_groups()
const;
161 MatchErrorCode get_num_members_in_group(grp_hdl_t grp,
size_t *nb)
const;
165 void serialize(std::ostream *out)
const;
166 void deserialize(std::istream *in,
const P4Objects &objs);
169 using ReadLock = boost::shared_lock<boost::shared_mutex>;
170 using WriteLock = boost::unique_lock<boost::shared_mutex>;
172 class IndirectIndexRefCount {
174 using count_t =
unsigned int;
177 void set(
const IndirectIndex &index, count_t value) {
178 unsigned int i = index.get();
179 auto &v = (index.is_mbr()) ? mbr_count : grp_count;
180 assert(i <= v.size());
187 count_t get(
const IndirectIndex &index)
const {
188 unsigned int i = index.get();
189 return (index.is_mbr()) ? mbr_count[i] : grp_count[i];
192 void increase(
const IndirectIndex &index) {
193 unsigned int i = index.get();
200 void decrease(
const IndirectIndex &index) {
201 unsigned int i = index.get();
208 void serialize(std::ostream *out)
const;
209 void deserialize(std::istream *in);
212 std::vector<count_t> mbr_count{};
213 std::vector<count_t> grp_count{};
218 using iterator = RandAccessUIntSet::iterator;
219 using const_iterator = RandAccessUIntSet::const_iterator;
221 MatchErrorCode add_member(mbr_hdl_t mbr);
222 MatchErrorCode delete_member(mbr_hdl_t mbr);
223 bool contains_member(mbr_hdl_t mbr)
const;
225 mbr_hdl_t get_nth(
size_t n)
const;
228 iterator begin() {
return mbrs.begin(); }
229 const_iterator begin()
const {
return mbrs.begin(); }
230 iterator end() {
return mbrs.end(); }
231 const_iterator end()
const {
return mbrs.end(); }
233 void serialize(std::ostream *out)
const;
234 void deserialize(std::istream *in);
237 RandAccessUIntSet mbrs{};
240 class GroupMgr :
public GroupSelectionIface {
242 void add_member_to_group(grp_hdl_t grp, mbr_hdl_t mbr)
override;
243 void remove_member_from_group(grp_hdl_t grp, mbr_hdl_t mbr)
override;
245 mbr_hdl_t get_from_hash(grp_hdl_t grp, hash_t h)
const override;
247 void reset()
override;
249 void insert_group(grp_hdl_t grp);
251 size_t group_size(grp_hdl_t grp)
const;
253 GroupInfo &at(grp_hdl_t grp);
254 const GroupInfo &at(grp_hdl_t grp)
const;
259 std::vector<GroupInfo> groups{};
263 mbr_hdl_t choose_from_group(grp_hdl_t grp,
const Packet &pkt)
const;
265 MatchErrorCode get_member_(mbr_hdl_t handle, Member *member)
const;
267 MatchErrorCode get_group_(grp_hdl_t grp, Group *group)
const;
269 void entries_insert(mbr_hdl_t mbr, ActionEntry &&entry);
272 ReadLock lock_read()
const {
return ReadLock(t_mutex); }
273 WriteLock lock_write()
const {
return WriteLock(t_mutex); }
277 void dump_entry(std::ostream *out,
const IndirectIndex &index)
const;
281 void ref_count_increase(
const IndirectIndex &index);
282 void ref_count_decrease(
const IndirectIndex &index);
284 bool is_valid_mbr(mbr_hdl_t mbr)
const {
285 return mbr_handles.valid_handle(mbr);
288 bool is_valid_grp(grp_hdl_t grp)
const {
289 return grp_handles.valid_handle(grp);
292 bool group_is_empty(grp_hdl_t grp)
const;
294 const ActionEntry &lookup(
const Packet &pkt,
295 const IndirectIndex &index)
const;
298 mutable boost::shared_mutex t_mutex{};
300 std::vector<ActionEntry> action_entries{};
301 IndirectIndexRefCount index_ref_count{};
302 HandleMgr mbr_handles{};
303 HandleMgr grp_handles{};
304 size_t num_members{0};
305 size_t num_groups{0};
307 std::shared_ptr<GroupSelectionIface> grp_selector_{
nullptr};
308 GroupSelectionIface *grp_selector{&grp_mgr};
309 std::unique_ptr<Calculation> hash{
nullptr};
314 #endif // BM_BM_SIM_ACTION_PROFILE_H_