From d9359cfa8e330e32dcc85f4432ccd75f17f65a29 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Sat, 5 Nov 2022 14:54:21 -0400 Subject: [PATCH] Implement scatter-gather array Signed-off-by: Mathieu Desnoyers --- include/side/trace.h | 110 ++++++++++++++++++++++-------------- src/test.c | 51 +++++++++++++++++ src/tracer.c | 129 +++++++++++++++++++++++++++---------------- 3 files changed, 201 insertions(+), 89 deletions(-) diff --git a/include/side/trace.h b/include/side/trace.h index 99faee9..69b165f 100644 --- a/include/side/trace.h +++ b/include/side/trace.h @@ -95,6 +95,7 @@ enum side_type_label { SIDE_TYPE_SG_SIGNED_INT, SIDE_TYPE_SG_FLOAT, SIDE_TYPE_SG_STRUCT, + SIDE_TYPE_SG_ARRAY, /* Dynamic types */ SIDE_TYPE_DYNAMIC_NULL, @@ -344,6 +345,7 @@ struct side_type_sg { union { struct side_type_sg_integer side_integer; struct side_type_float side_float; + struct side_type_array side_array; const struct side_type_struct *side_struct; } SIDE_PACKED u; } SIDE_PACKED; @@ -419,6 +421,7 @@ struct side_arg_static { /* Scatter-gather */ void *side_integer_sg_ptr; void *side_float_sg_ptr; + void *side_array_sg_ptr; void *side_struct_sg_ptr; } SIDE_PACKED; @@ -802,6 +805,50 @@ struct side_event_description { SIDE_COMPOUND_LITERAL(const struct side_type_struct, \ _side_type_struct_define(SIDE_PARAM(_fields), SIDE_PARAM(_attr))) +#define side_type_array(_elem_type, _length, _attr) \ + { \ + .type = SIDE_TYPE_ARRAY, \ + .u = { \ + .side_array = { \ + .elem_type = _elem_type, \ + .attr = _attr, \ + .length = _length, \ + .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + }, \ + }, \ + } +#define side_field_array(_name, _elem_type, _length, _attr) \ + _side_field(_name, side_type_array(SIDE_PARAM(_elem_type), _length, SIDE_PARAM(_attr))) + +#define side_type_vla(_elem_type, _attr) \ + { \ + .type = SIDE_TYPE_VLA, \ + .u = { \ + .side_vla = { \ + .elem_type = _elem_type, \ + .attr = _attr, \ + .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + }, \ + }, \ + } +#define side_field_vla(_name, _elem_type, _attr) \ + _side_field(_name, side_type_vla(SIDE_PARAM(_elem_type), SIDE_PARAM(_attr))) + +#define side_type_vla_visitor(_elem_type, _visitor, _attr) \ + { \ + .type = SIDE_TYPE_VLA_VISITOR, \ + .u = { \ + .side_vla_visitor = { \ + .elem_type = SIDE_PARAM(_elem_type), \ + .visitor = _visitor, \ + .attr = _attr, \ + .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + }, \ + }, \ + } +#define side_field_vla_visitor(_name, _elem_type, _visitor, _attr) \ + _side_field(_name, side_type_vla_visitor(SIDE_PARAM(_elem_type), _visitor, SIDE_PARAM(_attr))) + /* Scatter-gather fields */ #define _side_type_sg_integer(_type, _signedness, _byte_order, _offset, _integer_size_bits, _offset_bits, _len_bits, _attr) \ @@ -910,49 +957,25 @@ struct side_event_description { #define side_field_sg_struct(_name, _struct_sg, _offset) \ _side_field(_name, side_type_sg_struct(SIDE_PARAM(_struct_sg), _offset)) -#define side_type_array(_elem_type, _length, _attr) \ +#define side_type_sg_array(_elem_type_sg, _length, _offset, _attr) \ { \ - .type = SIDE_TYPE_ARRAY, \ + .type = SIDE_TYPE_SG_ARRAY, \ .u = { \ - .side_array = { \ - .elem_type = _elem_type, \ - .attr = _attr, \ - .length = _length, \ - .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ - }, \ - }, \ - } -#define side_field_array(_name, _elem_type, _length, _attr) \ - _side_field(_name, side_type_array(SIDE_PARAM(_elem_type), _length, SIDE_PARAM(_attr))) - -#define side_type_vla(_elem_type, _attr) \ - { \ - .type = SIDE_TYPE_VLA, \ - .u = { \ - .side_vla = { \ - .elem_type = _elem_type, \ - .attr = _attr, \ - .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ - }, \ - }, \ - } -#define side_field_vla(_name, _elem_type, _attr) \ - _side_field(_name, side_type_vla(SIDE_PARAM(_elem_type), SIDE_PARAM(_attr))) - -#define side_type_vla_visitor(_elem_type, _visitor, _attr) \ - { \ - .type = SIDE_TYPE_VLA_VISITOR, \ - .u = { \ - .side_vla_visitor = { \ - .elem_type = SIDE_PARAM(_elem_type), \ - .visitor = _visitor, \ - .attr = _attr, \ - .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + .side_sg = { \ + .offset = _offset, \ + .u = { \ + .side_array = { \ + .elem_type = _elem_type_sg, \ + .attr = _attr, \ + .length = _length, \ + .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \ + }, \ + }, \ }, \ }, \ } -#define side_field_vla_visitor(_name, _elem_type, _visitor, _attr) \ - _side_field(_name, side_type_vla_visitor(SIDE_PARAM(_elem_type), _visitor, SIDE_PARAM(_attr))) +#define side_field_sg_array(_name, _elem_type, _length, _offset, _attr) \ + _side_field(_name, side_type_sg_array(SIDE_PARAM(_elem_type), _length, _offset, SIDE_PARAM(_attr))) #define side_elem(...) \ SIDE_COMPOUND_LITERAL(const struct side_type, __VA_ARGS__) @@ -988,10 +1011,6 @@ struct side_event_description { #define side_arg_float_binary128(_val) { .type = SIDE_TYPE_FLOAT_BINARY128, .u = { .side_static = { .float_value = { .side_float_binary128 = (_val) } } } } #define side_arg_struct(_side_type) { .type = SIDE_TYPE_STRUCT, .u = { .side_static = { .side_struct = (_side_type) } } } -#define side_arg_sg_struct(_ptr) { .type = SIDE_TYPE_SG_STRUCT, .u = { .side_static = { .side_struct_sg_ptr = (_ptr) } } } -#define side_arg_sg_unsigned_integer(_ptr) { .type = SIDE_TYPE_SG_UNSIGNED_INT, .u = { .side_static = { .side_integer_sg_ptr = (_ptr) } } } -#define side_arg_sg_signed_integer(_ptr) { .type = SIDE_TYPE_SG_SIGNED_INT, .u = { .side_static = { .side_integer_sg_ptr = (_ptr) } } } -#define side_arg_sg_float(_ptr) { .type = SIDE_TYPE_SG_FLOAT, .u = { .side_static = { .side_float_sg_ptr = (_ptr) } } } #define side_arg_array(_side_type) { .type = SIDE_TYPE_ARRAY, .u = { .side_static = { .side_array = (_side_type) } } } #define side_arg_vla(_side_type) { .type = SIDE_TYPE_VLA, .u = { .side_static = { .side_vla = (_side_type) } } } #define side_arg_vla_visitor(_ctx) { .type = SIDE_TYPE_VLA_VISITOR, .u = { .side_static = { .side_vla_app_visitor_ctx = (_ctx) } } } @@ -1018,6 +1037,13 @@ struct side_event_description { #define side_arg_vla_byte(_ptr, _length) { .type = SIDE_TYPE_VLA_BYTE, .u = { .side_static = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } } } #define side_arg_vla_pointer(_ptr, _length) { .type = SIDE_TYPE_VLA_POINTER_HOST, .u = { .side_static = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } } } +/* Scatter-gather field arguments */ +#define side_arg_sg_unsigned_integer(_ptr) { .type = SIDE_TYPE_SG_UNSIGNED_INT, .u = { .side_static = { .side_integer_sg_ptr = (_ptr) } } } +#define side_arg_sg_signed_integer(_ptr) { .type = SIDE_TYPE_SG_SIGNED_INT, .u = { .side_static = { .side_integer_sg_ptr = (_ptr) } } } +#define side_arg_sg_float(_ptr) { .type = SIDE_TYPE_SG_FLOAT, .u = { .side_static = { .side_float_sg_ptr = (_ptr) } } } +#define side_arg_sg_struct(_ptr) { .type = SIDE_TYPE_SG_STRUCT, .u = { .side_static = { .side_struct_sg_ptr = (_ptr) } } } +#define side_arg_sg_array(_ptr) { .type = SIDE_TYPE_SG_ARRAY, .u = { .side_static = { .side_array_sg_ptr = (_ptr) } } } + /* Dynamic field arguments */ #define side_arg_dynamic_null(_attr) \ diff --git a/src/test.c b/src/test.c index 9f3bbc5..fd0a6ee 100644 --- a/src/test.c +++ b/src/test.c @@ -1710,6 +1710,56 @@ void test_struct_sg_float(void) } } +uint32_t mysgarray[] = { 1, 2, 3, 4, 5 }; + +uint16_t mysgarray2[] = { 6, 7, 8, 9 }; + +struct testarray { + int a; + uint32_t *ptr; +}; + +static side_define_struct(mystructsgarray, + side_field_list( + side_field_sg_array("array", + side_elem(side_type_sg_unsigned_integer(0, 32, 0, 32, side_attr_list())), + SIDE_ARRAY_SIZE(mysgarray), + offsetof(struct testarray, ptr), + side_attr_list()), + ), + side_attr_list() +); + +side_static_event(my_provider_event_structsgarray, + "myprovider", "myeventstructsgarray", SIDE_LOGLEVEL_DEBUG, + side_field_list( + side_field_sg_struct("structsgarray", &mystructsgarray, 0), + side_field_sg_array("array2", + side_elem(side_type_sg_unsigned_integer(0, 16, 0, 16, side_attr_list())), + SIDE_ARRAY_SIZE(mysgarray2), 0, + side_attr_list() + ), + ), + side_attr_list() +); + +static +void test_array_sg(void) +{ + side_event_cond(my_provider_event_structsgarray) { + struct testarray mystruct = { + .a = 55, + .ptr = mysgarray, + }; + side_event_call(my_provider_event_structsgarray, + side_arg_list( + side_arg_sg_struct(&mystruct), + side_arg_sg_array(&mysgarray2), + ) + ); + } +} + int main() { test_fields(); @@ -1753,5 +1803,6 @@ int main() test_struct_sg(); test_struct_sg_nest(); test_struct_sg_float(); + test_array_sg(); return 0; } diff --git a/src/tracer.c b/src/tracer.c index a208e8f..b071ee0 100644 --- a/src/tracer.c +++ b/src/tracer.c @@ -24,12 +24,6 @@ static struct side_tracer_handle *tracer_handle; static void tracer_print_struct(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec); static -void tracer_print_sg_struct(const struct side_type_sg *type_sg, const void *_ptr); -static -void tracer_print_sg_integer_type(const struct side_type_sg *type_sg, const void *_ptr); -static -void tracer_print_sg_float_type(const struct side_type_sg *type_sg, const void *_ptr); -static void tracer_print_array(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec); static void tracer_print_vla(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec); @@ -42,6 +36,14 @@ void tracer_print_vla_fixint(const struct side_type *type_desc, const struct sid static void tracer_print_dynamic(const struct side_arg *dynamic_item); static +uint32_t tracer_print_sg_struct(const struct side_type_sg *type_sg, const void *_ptr); +static +uint32_t tracer_print_sg_integer_type(const struct side_type_sg *type_sg, const void *_ptr); +static +uint32_t tracer_print_sg_float_type(const struct side_type_sg *type_sg, const void *_ptr); +static +uint32_t tracer_print_sg_array(const struct side_type_sg *type_sg, const void *_ptr); +static void tracer_print_type(const struct side_type *type_desc, const struct side_arg *item); static @@ -902,14 +904,17 @@ void tracer_print_type(const struct side_type *type_desc, const struct side_arg tracer_print_struct(type_desc, item->u.side_static.side_struct); break; case SIDE_TYPE_SG_STRUCT: - tracer_print_sg_struct(&type_desc->u.side_sg, &item->u.side_static.side_struct_sg_ptr); + (void) tracer_print_sg_struct(&type_desc->u.side_sg, &item->u.side_static.side_struct_sg_ptr); + break; + case SIDE_TYPE_SG_ARRAY: + (void) tracer_print_sg_array(&type_desc->u.side_sg, &item->u.side_static.side_array_sg_ptr); break; case SIDE_TYPE_SG_UNSIGNED_INT: case SIDE_TYPE_SG_SIGNED_INT: - tracer_print_sg_integer_type(&type_desc->u.side_sg, item->u.side_static.side_integer_sg_ptr); + (void) tracer_print_sg_integer_type(&type_desc->u.side_sg, item->u.side_static.side_integer_sg_ptr); break; case SIDE_TYPE_SG_FLOAT: - tracer_print_sg_float_type(&type_desc->u.side_sg, item->u.side_static.side_float_sg_ptr); + (void) tracer_print_sg_float_type(&type_desc->u.side_sg, item->u.side_static.side_float_sg_ptr); break; case SIDE_TYPE_ARRAY: tracer_print_array(type_desc, item->u.side_static.side_array); @@ -1007,10 +1012,49 @@ void tracer_print_struct(const struct side_type *type_desc, const struct side_ar } static -void tracer_print_sg_integer_type(const struct side_type_sg *type_sg, const void *_ptr) +void tracer_print_array(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec) +{ + const struct side_arg *sav = side_arg_vec->sav; + uint32_t i, side_sav_len = side_arg_vec->len; + + if (type_desc->u.side_array.length != side_sav_len) { + fprintf(stderr, "ERROR: length mismatch between description and arguments of array\n"); + abort(); + } + print_attributes("attr", ":", type_desc->u.side_array.attr, type_desc->u.side_array.nr_attr); + printf("%s", type_desc->u.side_array.nr_attr ? ", " : ""); + printf("elements: "); + printf("[ "); + for (i = 0; i < side_sav_len; i++) { + printf("%s", i ? ", " : ""); + tracer_print_type(type_desc->u.side_array.elem_type, &sav[i]); + } + printf(" ]"); +} + +static +void tracer_print_vla(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec) +{ + const struct side_arg *sav = side_arg_vec->sav; + uint32_t i, side_sav_len = side_arg_vec->len; + + print_attributes("attr", ":", type_desc->u.side_vla.attr, type_desc->u.side_vla.nr_attr); + printf("%s", type_desc->u.side_vla.nr_attr ? ", " : ""); + printf("elements: "); + printf("[ "); + for (i = 0; i < side_sav_len; i++) { + printf("%s", i ? ", " : ""); + tracer_print_type(type_desc->u.side_vla.elem_type, &sav[i]); + } + printf(" ]"); +} + +static +uint32_t tracer_print_sg_integer_type(const struct side_type_sg *type_sg, const void *_ptr) { const char *ptr = (const char *) _ptr; union side_integer_value value; + uint32_t integer_size_bytes = type_sg->u.side_integer.type.integer_size_bits >> 3; switch (type_sg->u.side_integer.type.integer_size_bits) { case 8: @@ -1021,16 +1065,18 @@ void tracer_print_sg_integer_type(const struct side_type_sg *type_sg, const void default: abort(); } - memcpy(&value, ptr + type_sg->offset, type_sg->u.side_integer.type.integer_size_bits >> 3); + memcpy(&value, ptr + type_sg->offset, integer_size_bytes); tracer_print_type_integer(":", &type_sg->u.side_integer.type, &value, type_sg->u.side_integer.offset_bits, TRACER_DISPLAY_BASE_10); + return integer_size_bytes; } static -void tracer_print_sg_float_type(const struct side_type_sg *type_sg, const void *_ptr) +uint32_t tracer_print_sg_float_type(const struct side_type_sg *type_sg, const void *_ptr) { const char *ptr = (const char *) _ptr; union side_float_value value; + uint32_t float_size_bytes = type_sg->u.side_float.float_size_bits >> 3; switch (type_sg->u.side_float.float_size_bits) { case 16: @@ -1041,41 +1087,48 @@ void tracer_print_sg_float_type(const struct side_type_sg *type_sg, const void * default: abort(); } - memcpy(&value, ptr + type_sg->offset, type_sg->u.side_float.float_size_bits >> 3); + memcpy(&value, ptr + type_sg->offset, float_size_bytes); tracer_print_type_float(":", &type_sg->u.side_float, &value); + return float_size_bytes; } static -void tracer_print_sg_type(const struct side_type *type_desc, void *ptr) +uint32_t tracer_print_sg_type(const struct side_type *type_desc, void *ptr) { + uint32_t len; + printf("{ "); switch (type_desc->type) { case SIDE_TYPE_SG_UNSIGNED_INT: case SIDE_TYPE_SG_SIGNED_INT: - tracer_print_sg_integer_type(&type_desc->u.side_sg, ptr); + len = tracer_print_sg_integer_type(&type_desc->u.side_sg, ptr); break; case SIDE_TYPE_SG_FLOAT: - tracer_print_sg_float_type(&type_desc->u.side_sg, ptr); + len = tracer_print_sg_float_type(&type_desc->u.side_sg, ptr); break; case SIDE_TYPE_SG_STRUCT: - tracer_print_sg_struct(&type_desc->u.side_sg, ptr); + len = tracer_print_sg_struct(&type_desc->u.side_sg, ptr); + break; + case SIDE_TYPE_SG_ARRAY: + len = tracer_print_sg_array(&type_desc->u.side_sg, ptr); break; default: fprintf(stderr, ""); abort(); } printf(" }"); + return len; } static void tracer_print_sg_field(const struct side_event_field *field, void *ptr) { printf("%s: ", field->field_name); - tracer_print_sg_type(&field->side_type, ptr); + (void) tracer_print_sg_type(&field->side_type, ptr); } static -void tracer_print_sg_struct(const struct side_type_sg *type_sg, const void *_ptr) +uint32_t tracer_print_sg_struct(const struct side_type_sg *type_sg, const void *_ptr) { char *ptr = (char *) _ptr; uint32_t i; @@ -1089,44 +1142,26 @@ void tracer_print_sg_struct(const struct side_type_sg *type_sg, const void *_ptr tracer_print_sg_field(&type_sg->u.side_struct->fields[i], ptr); } printf(" }"); + return sizeof(void *); } static -void tracer_print_array(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec) +uint32_t tracer_print_sg_array(const struct side_type_sg *type_sg, const void *_ptr) { - const struct side_arg *sav = side_arg_vec->sav; - uint32_t i, side_sav_len = side_arg_vec->len; - - if (type_desc->u.side_array.length != side_sav_len) { - fprintf(stderr, "ERROR: length mismatch between description and arguments of array\n"); - abort(); - } - print_attributes("attr", ":", type_desc->u.side_array.attr, type_desc->u.side_array.nr_attr); - printf("%s", type_desc->u.side_array.nr_attr ? ", " : ""); - printf("elements: "); - printf("[ "); - for (i = 0; i < side_sav_len; i++) { - printf("%s", i ? ", " : ""); - tracer_print_type(type_desc->u.side_array.elem_type, &sav[i]); - } - printf(" ]"); -} - -static -void tracer_print_vla(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec) -{ - const struct side_arg *sav = side_arg_vec->sav; - uint32_t i, side_sav_len = side_arg_vec->len; + char *ptr = (char *) _ptr; + uint32_t i; - print_attributes("attr", ":", type_desc->u.side_vla.attr, type_desc->u.side_vla.nr_attr); - printf("%s", type_desc->u.side_vla.nr_attr ? ", " : ""); + memcpy(&ptr, ptr + type_sg->offset, sizeof(ptr)); + print_attributes("attr", ":", type_sg->u.side_array.attr, type_sg->u.side_array.nr_attr); + printf("%s", type_sg->u.side_array.nr_attr ? ", " : ""); printf("elements: "); printf("[ "); - for (i = 0; i < side_sav_len; i++) { + for (i = 0; i < type_sg->u.side_array.length; i++) { printf("%s", i ? ", " : ""); - tracer_print_type(type_desc->u.side_vla.elem_type, &sav[i]); + ptr += tracer_print_sg_type(type_sg->u.side_array.elem_type, ptr); } printf(" ]"); + return sizeof(void *); } struct tracer_visitor_priv { -- 2.34.1