void recirc_run(void);
+/* Recirculation IDs on which references are held. */
+struct recirc_refs {
+ unsigned n_recircs;
+ union {
+ uint32_t recirc[2]; /* When n_recircs == 1 or 2 */
+ uint32_t *recircs; /* When 'n_recircs' > 2 */
+ };
+};
+
+#define RECIRC_REFS_EMPTY_INITIALIZER ((struct recirc_refs) \
+ { 0, { { 0, 0 } } })
+/* Helpers to abstract the recirculation union away. */
+static inline void
+recirc_refs_init(struct recirc_refs *rr)
+{
+ *rr = RECIRC_REFS_EMPTY_INITIALIZER;
+}
+
+static inline void
+recirc_refs_add(struct recirc_refs *rr, uint32_t id)
+{
+ if (OVS_LIKELY(rr->n_recircs < ARRAY_SIZE(rr->recirc))) {
+ rr->recirc[rr->n_recircs++] = id;
+ } else {
+ if (rr->n_recircs == ARRAY_SIZE(rr->recirc)) {
+ uint32_t *recircs = xmalloc(sizeof rr->recirc + sizeof id);
+
+ memcpy(recircs, rr->recirc, sizeof rr->recirc);
+ rr->recircs = recircs;
+ } else {
+ rr->recircs = xrealloc(rr->recircs,
+ (rr->n_recircs + 1) * sizeof id);
+ }
+ rr->recircs[rr->n_recircs++] = id;
+ }
+}
+
+static inline void
+recirc_refs_swap(struct recirc_refs *a, struct recirc_refs *b)
+{
+ struct recirc_refs tmp;
+
+ tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+static inline void
+recirc_refs_unref(struct recirc_refs *rr)
+{
+ if (OVS_LIKELY(rr->n_recircs <= ARRAY_SIZE(rr->recirc))) {
+ for (int i = 0; i < rr->n_recircs; i++) {
+ recirc_free_id(rr->recirc[i]);
+ }
+ } else {
+ for (int i = 0; i < rr->n_recircs; i++) {
+ recirc_free_id(rr->recircs[i]);
+ }
+ free(rr->recircs);
+ }
+ rr->n_recircs = 0;
+}
+
#endif