Implement scatter-gather array
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 5 Nov 2022 18:54:21 +0000 (14:54 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 5 Nov 2022 18:54:21 +0000 (14:54 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/side/trace.h
src/test.c
src/tracer.c

index 99faee911aed3855fd707a49e83f0a5f95b71b62..69b165f7496b37965219e7172bb65f530ed7fb65 100644 (file)
@@ -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) \
index 9f3bbc5421687d2b9e96e4dcc5ca3bcae3226a01..fd0a6ee13ae6e739e970aa579e5feaac2854057d 100644 (file)
@@ -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;
 }
index a208e8fb0c7ca8508fabf40393171fa3ffb3e512..b071ee0fbc569091f55e442a0c903c3c1ac53e45 100644 (file)
@@ -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, "<UNKNOWN SCATTER-GATHER TYPE>");
                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 {
This page took 0.031535 seconds and 4 git commands to generate.