Flags are not always bad. For example, as a function argument they allow easier extension in the future. But with datatype's "flags" argument and enum datatype_flags there are no advantages of this approach. - replace DTYPE_F_PREFIX with a "bool f_prefix" field. This could even be a bool:1 bitfield if we cared to represent the information with one bit only. For now it's not done because that would not help reducing the size of the struct, so a bitfield is less preferable. - instead of DTYPE_F_ALLOC, use the refcnt of zero to represent static instances. Drop this redundant flag. - move the integer field "refcnt" in struct datatype beside other fields of similar size/alignment. This makes the size of the struct by one pointer size smaller (on x86-64). Signed-off-by: Thomas Haller <thaller@xxxxxxxxxx> --- include/datatype.h | 24 +++++++++--------------- src/datatype.c | 20 ++++++++------------ src/meta.c | 2 +- src/netlink_delinearize.c | 2 +- src/rt.c | 2 +- src/segtree.c | 5 ++--- 6 files changed, 22 insertions(+), 33 deletions(-) diff --git a/include/datatype.h b/include/datatype.h index 52a2e943b252..5b85adc15857 100644 --- a/include/datatype.h +++ b/include/datatype.h @@ -120,24 +120,13 @@ enum byteorder { struct expr; -/** - * enum datatype_flags - * - * @DTYPE_F_ALLOC: datatype is dynamically allocated - * @DTYPE_F_PREFIX: preferred representation for ranges is a prefix - */ -enum datatype_flags { - DTYPE_F_ALLOC = (1 << 0), - DTYPE_F_PREFIX = (1 << 1), -}; - struct parse_ctx; /** * struct datatype * * @type: numeric identifier * @byteorder: byteorder of type (non-basetypes only) - * @flags: flags + * @f_prefix: preferred representation for ranges is a prefix * @size: type size (fixed sized non-basetypes only) * @subtypes: number of subtypes (concat type) * @name: type name @@ -147,14 +136,20 @@ struct parse_ctx; * @print: function to print a constant of this type * @parse: function to parse a symbol and return an expression * @sym_tbl: symbol table for this type - * @refcnt: reference counter (only for DTYPE_F_ALLOC) + * @refcnt: reference counter for dynamically allocated instances. */ struct datatype { uint32_t type; enum byteorder byteorder; - unsigned int flags; + bool f_prefix; unsigned int size; unsigned int subtypes; + + /* Refcount for dynamically allocated instances. For static instances + * this is zero (get() and free() are NOPs). + */ + unsigned int refcnt; + const char *name; const char *desc; const struct datatype *basetype; @@ -169,7 +164,6 @@ struct datatype { struct error_record *(*err)(const struct expr *sym); void (*describe)(struct output_ctx *octx); const struct symbol_table *sym_tbl; - unsigned int refcnt; }; extern const struct datatype *datatype_lookup(enum datatypes type); diff --git a/src/datatype.c b/src/datatype.c index 70c84846f70e..c5d88d9a90b6 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -641,7 +641,7 @@ const struct datatype ipaddr_type = { .basetype = &integer_type, .print = ipaddr_type_print, .parse = ipaddr_type_parse, - .flags = DTYPE_F_PREFIX, + .f_prefix = true, }; static void ip6addr_type_print(const struct expr *expr, struct output_ctx *octx) @@ -708,7 +708,7 @@ const struct datatype ip6addr_type = { .basetype = &integer_type, .print = ip6addr_type_print, .parse = ip6addr_type_parse, - .flags = DTYPE_F_PREFIX, + .f_prefix = true, }; static void inet_protocol_type_print(const struct expr *expr, @@ -944,7 +944,7 @@ const struct datatype mark_type = { .print = mark_type_print, .json = mark_type_json, .parse = mark_type_parse, - .flags = DTYPE_F_PREFIX, + .f_prefix = true, }; static const struct symbol_table icmp_code_tbl = { @@ -1203,9 +1203,7 @@ static struct datatype *datatype_alloc(void) struct datatype *dtype; dtype = xzalloc(sizeof(*dtype)); - dtype->flags = DTYPE_F_ALLOC; dtype->refcnt = 1; - return dtype; } @@ -1215,10 +1213,10 @@ struct datatype *datatype_get(const struct datatype *ptr) if (!dtype) return NULL; - if (!(dtype->flags & DTYPE_F_ALLOC)) - return dtype; - dtype->refcnt++; + if (dtype->refcnt > 0) + dtype->refcnt++; + return dtype; } @@ -1245,7 +1243,6 @@ struct datatype *datatype_clone(const struct datatype *orig_dtype) *dtype = *orig_dtype; dtype->name = xstrdup(orig_dtype->name); dtype->desc = xstrdup(orig_dtype->desc); - dtype->flags = DTYPE_F_ALLOC | orig_dtype->flags; dtype->refcnt = 1; return dtype; @@ -1257,10 +1254,9 @@ void datatype_free(const struct datatype *ptr) if (!dtype) return; - if (!(dtype->flags & DTYPE_F_ALLOC)) - return; - assert(dtype->refcnt != 0); + if (dtype->refcnt == 0) + return; if (--dtype->refcnt > 0) return; diff --git a/src/meta.c b/src/meta.c index 181e111cbbdc..7bf749b34fb4 100644 --- a/src/meta.c +++ b/src/meta.c @@ -368,7 +368,7 @@ const struct datatype devgroup_type = { .print = devgroup_type_print, .json = devgroup_type_json, .parse = devgroup_type_parse, - .flags = DTYPE_F_PREFIX, + .f_prefix = true, }; const struct datatype ifname_type = { diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 41cb37a3ccb3..f3939be2d063 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -2568,7 +2568,7 @@ static void relational_binop_postprocess(struct rule_pp_ctx *ctx, default: break; } - } else if (binop->left->dtype->flags & DTYPE_F_PREFIX && + } else if (binop->left->dtype->f_prefix && binop->op == OP_AND && expr->right->etype == EXPR_VALUE && expr_mask_is_prefix(binop->right)) { expr->left = expr_get(binop->left); diff --git a/src/rt.c b/src/rt.c index 9ddcb210eaad..ccea0aa9bc44 100644 --- a/src/rt.c +++ b/src/rt.c @@ -55,7 +55,7 @@ const struct datatype realm_type = { .basetype = &integer_type, .print = realm_type_print, .parse = realm_type_parse, - .flags = DTYPE_F_PREFIX, + .f_prefix = true, }; const struct rt_template rt_templates[] = { diff --git a/src/segtree.c b/src/segtree.c index 0a12a0cd5151..637457b087b9 100644 --- a/src/segtree.c +++ b/src/segtree.c @@ -402,8 +402,7 @@ void concat_range_aggregate(struct expr *set) goto next; } - if (prefix_len < 0 || - !(r1->dtype->flags & DTYPE_F_PREFIX)) { + if (prefix_len < 0 || !r1->dtype->f_prefix) { tmp = range_expr_alloc(&r1->location, r1, r2); @@ -518,7 +517,7 @@ add_interval(struct expr *set, struct expr *low, struct expr *i) expr = expr_get(low); } else if (range_is_prefix(range) && !mpz_cmp_ui(p, 0)) { - if (i->dtype->flags & DTYPE_F_PREFIX) + if (i->dtype->f_prefix) expr = interval_to_prefix(low, i, range); else if (expr_basetype(i)->type == TYPE_STRING) expr = interval_to_string(low, i, range); -- 2.41.0