From 79f677bab9e673dc18b1043add99042bbf1e673b Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 20 Oct 2022 21:08:19 -0400 Subject: [PATCH] Implement enum type Signed-off-by: Mathieu Desnoyers --- include/side/trace.h | 69 ++++++++++++++++++++++++++++++++++++++++++++ src/test.c | 34 ++++++++++++++++++++++ src/tracer.c | 53 ++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+) diff --git a/include/side/trace.h b/include/side/trace.h index 8618638..5c18a56 100644 --- a/include/side/trace.h +++ b/include/side/trace.h @@ -19,6 +19,8 @@ //fixed forever, or think of a scheme that would allow their binary //representation to be extended if need be. +//TODO: enum bitmap + struct side_arg_vec; struct side_arg_vec_description; struct side_arg_dynamic_vec; @@ -41,6 +43,15 @@ enum side_type { SIDE_TYPE_S32, SIDE_TYPE_S64, + SIDE_TYPE_ENUM_U8, + SIDE_TYPE_ENUM_U16, + SIDE_TYPE_ENUM_U32, + SIDE_TYPE_ENUM_U64, + SIDE_TYPE_ENUM_S8, + SIDE_TYPE_ENUM_S16, + SIDE_TYPE_ENUM_S32, + SIDE_TYPE_ENUM_S64, + SIDE_TYPE_FLOAT_BINARY16, SIDE_TYPE_FLOAT_BINARY32, SIDE_TYPE_FLOAT_BINARY64, @@ -185,6 +196,17 @@ struct side_attr { const struct side_attr_value value; }; +struct side_enum_mapping { + int64_t range_begin; + int64_t range_end; + const char *label; +}; + +struct side_enum_mappings { + const struct side_enum_mapping *mappings; + uint32_t nr_mappings; +}; + struct side_type_description { uint32_t type; /* enum side_type */ uint32_t nr_attr; @@ -205,6 +227,7 @@ struct side_type_description { const struct side_type_description *elem_type; side_visitor visitor; } side_vla_visitor; + const struct side_enum_mappings *side_enum_mappings; } u; }; @@ -383,6 +406,21 @@ struct side_tracer_dynamic_vla_visitor_ctx { .side_type = side_type_decl(_type, SIDE_PARAM(_attr)), \ } +#define side_type_enum_decl(_type, _mappings, _attr) \ + { \ + .type = _type, \ + .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .attr = _attr, \ + .u = { \ + .side_enum_mappings = _mappings, \ + }, \ + } +#define side_field_enum(_name, _type, _mappings, _attr) \ + { \ + .field_name = _name, \ + .side_type = side_type_enum_decl(_type, SIDE_PARAM(_mappings), SIDE_PARAM(_attr)), \ + } + #define side_type_struct_decl(_fields, _attr) \ { \ .type = SIDE_TYPE_STRUCT, \ @@ -472,6 +510,14 @@ struct side_tracer_dynamic_vla_visitor_ctx { #define side_arg_s16(val) { .type = SIDE_TYPE_S16, .u = { .side_s16 = (val) } } #define side_arg_s32(val) { .type = SIDE_TYPE_S32, .u = { .side_s32 = (val) } } #define side_arg_s64(val) { .type = SIDE_TYPE_S64, .u = { .side_s64 = (val) } } +#define side_arg_enum_u8(val) { .type = SIDE_TYPE_ENUM_U8, .u = { .side_u8 = (val) } } +#define side_arg_enum_u16(val) { .type = SIDE_TYPE_ENUM_U16, .u = { .side_u16 = (val) } } +#define side_arg_enum_u32(val) { .type = SIDE_TYPE_ENUM_U32, .u = { .side_u32 = (val) } } +#define side_arg_enum_u64(val) { .type = SIDE_TYPE_ENUM_U64, .u = { .side_u64 = (val) } } +#define side_arg_enum_s8(val) { .type = SIDE_TYPE_ENUM_S8, .u = { .side_s8 = (val) } } +#define side_arg_enum_s16(val) { .type = SIDE_TYPE_ENUM_S16, .u = { .side_s16 = (val) } } +#define side_arg_enum_s32(val) { .type = SIDE_TYPE_ENUM_S32, .u = { .side_s32 = (val) } } +#define side_arg_enum_s64(val) { .type = SIDE_TYPE_ENUM_S64, .u = { .side_s64 = (val) } } #define side_arg_float_binary16(val) { .type = SIDE_TYPE_FLOAT_BINARY16, .u = { .side_float_binary16 = (val) } } #define side_arg_float_binary32(val) { .type = SIDE_TYPE_FLOAT_BINARY32, .u = { .side_float_binary32 = (val) } } #define side_arg_float_binary64(val) { .type = SIDE_TYPE_FLOAT_BINARY64, .u = { .side_float_binary64 = (val) } } @@ -772,6 +818,29 @@ struct side_tracer_dynamic_vla_visitor_ctx { side_event_cond(desc) \ side_event_call_variadic(desc, SIDE_PARAM(sav), SIDE_PARAM(var)) +#define side_define_enum(_identifier, _mappings) \ + const struct side_enum_mappings _identifier = { \ + .mappings = _mappings, \ + .nr_mappings = SIDE_ARRAY_SIZE(SIDE_PARAM(_mappings)), \ + } + +#define side_mapping_list(...) \ + SIDE_COMPOUND_LITERAL(const struct side_enum_mapping, __VA_ARGS__) + +#define side_enum_mapping_range(_label, _begin, _end) \ + { \ + .range_begin = _begin, \ + .range_end = _end, \ + .label = _label, \ + } + +#define side_enum_mapping_value(_label, _value) \ + { \ + .range_begin = _value, \ + .range_end = _value, \ + .label = _label, \ + } + #define _side_define_event(_identifier, _provider, _event, _loglevel, _fields, _attr, _flags) \ struct side_event_description _identifier = { \ .version = 0, \ diff --git a/src/test.c b/src/test.c index 76b288c..45a0428 100644 --- a/src/test.c +++ b/src/test.c @@ -931,6 +931,39 @@ void test_variadic_float(void) ); } +static side_define_enum(myenum, + side_mapping_list( + side_enum_mapping_range("one-ten", 1, 10), + side_enum_mapping_range("100-200", 100, 200), + side_enum_mapping_value("200", 200), + side_enum_mapping_value("300", 300), + ) +); + +static side_define_event(my_provider_event_enum, "myprovider", "myeventenum", SIDE_LOGLEVEL_DEBUG, + side_field_list( + side_field_enum("5", SIDE_TYPE_ENUM_U32, &myenum, side_attr_list()), + side_field_enum("400", SIDE_TYPE_ENUM_U64, &myenum, side_attr_list()), + side_field_enum("200", SIDE_TYPE_ENUM_U8, &myenum, side_attr_list()), + side_field_enum("-100", SIDE_TYPE_ENUM_S8, &myenum, side_attr_list()), + ), + side_attr_list() +); + +static +void test_enum(void) +{ + my_provider_event_enum.enabled = 1; + side_event(&my_provider_event_enum, + side_arg_list( + side_arg_enum_u32(5), + side_arg_enum_u64(400), + side_arg_enum_u8(200), + side_arg_enum_s8(-100), + ) + ); +} + int main() { test_fields(); @@ -962,5 +995,6 @@ int main() test_variadic_struct_attr(); test_float(); test_variadic_float(); + test_enum(); return 0; } diff --git a/src/tracer.c b/src/tracer.c index d1065b2..7c8f373 100644 --- a/src/tracer.c +++ b/src/tracer.c @@ -114,6 +114,25 @@ void print_attributes(const char *prefix_str, const struct side_attr *attr, uint printf(" ]"); } +static +void print_enum(const struct side_enum_mappings *side_enum_mappings, int64_t value) +{ + int i, print_count = 0; + + printf("%" PRId64 ", labels: [ ", value); + for (i = 0; i < side_enum_mappings->nr_mappings; i++) { + const struct side_enum_mapping *mapping = &side_enum_mappings->mappings[i]; + + if (value >= mapping->range_begin && value <= mapping->range_end) { + printf("%s", print_count++ ? ", " : ""); + printf("\"%s\"", mapping->label); + } + } + if (!print_count) + printf(""); + printf(" ]"); +} + static void tracer_print_type(const struct side_type_description *type_desc, const struct side_arg_vec *item) { @@ -184,6 +203,40 @@ void tracer_print_type(const struct side_type_description *type_desc, const stru case SIDE_TYPE_S64: printf("%" PRId64, item->u.side_s64); break; + + case SIDE_TYPE_ENUM_U8: + print_enum(type_desc->u.side_enum_mappings, + (int64_t) item->u.side_u8); + break; + case SIDE_TYPE_ENUM_U16: + print_enum(type_desc->u.side_enum_mappings, + (int64_t) item->u.side_u16); + break; + case SIDE_TYPE_ENUM_U32: + print_enum(type_desc->u.side_enum_mappings, + (int64_t) item->u.side_u32); + break; + case SIDE_TYPE_ENUM_U64: + print_enum(type_desc->u.side_enum_mappings, + (int64_t) item->u.side_u64); + break; + case SIDE_TYPE_ENUM_S8: + print_enum(type_desc->u.side_enum_mappings, + (int64_t) item->u.side_s8); + break; + case SIDE_TYPE_ENUM_S16: + print_enum(type_desc->u.side_enum_mappings, + (int64_t) item->u.side_s16); + break; + case SIDE_TYPE_ENUM_S32: + print_enum(type_desc->u.side_enum_mappings, + (int64_t) item->u.side_s32); + break; + case SIDE_TYPE_ENUM_S64: + print_enum(type_desc->u.side_enum_mappings, + item->u.side_s64); + break; + case SIDE_TYPE_FLOAT_BINARY16: #if __HAVE_FLOAT16 printf("%g", (double) item->u.side_float_binary16); -- 2.34.1