SIDE_TYPE_SG_FLOAT,
SIDE_TYPE_SG_STRUCT,
SIDE_TYPE_SG_ARRAY,
+ SIDE_TYPE_SG_VLA,
/* Dynamic types */
SIDE_TYPE_DYNAMIC_NULL,
} SIDE_PACKED;
struct side_type_sg_integer {
+ uint64_t offset; /* bytes */
+ uint8_t access_mode; /* enum side_type_sg_access_mode */
struct side_type_integer type;
- uint16_t offset_bits; /* bits */
+ uint16_t offset_bits; /* bits */
+} SIDE_PACKED;
+
+struct side_type_sg_float {
+ uint64_t offset; /* bytes */
+ uint8_t access_mode; /* enum side_type_sg_access_mode */
+ struct side_type_float type;
} SIDE_PACKED;
struct side_type_sg_struct {
+ uint64_t offset; /* bytes */
+ uint8_t access_mode; /* enum side_type_sg_access_mode */
const struct side_type_struct *type;
- uint32_t size; /* bytes */
+ uint32_t size; /* bytes */
+} SIDE_PACKED;
+
+struct side_type_sg_array {
+ uint64_t offset; /* bytes */
+ uint8_t access_mode; /* enum side_type_sg_access_mode */
+ struct side_type_array type;
+} SIDE_PACKED;
+
+struct side_type_sg_vla {
+ const struct side_type *length_type; /* side_length() */
+
+ uint64_t offset; /* bytes */
+ uint8_t access_mode; /* enum side_type_sg_access_mode */
+ struct side_type_vla type;
} SIDE_PACKED;
enum side_type_sg_access_mode {
};
struct side_type_sg {
- uint64_t offset; /* bytes */
- uint8_t access_mode; /* enum side_type_sg_access_mode */
union {
struct side_type_sg_integer side_integer;
- struct side_type_float side_float;
- struct side_type_array side_array;
+ struct side_type_sg_float side_float;
+ struct side_type_sg_array side_array;
+ struct side_type_sg_vla side_vla;
struct side_type_sg_struct side_struct;
} SIDE_PACKED u;
} SIDE_PACKED;
void *side_float_sg_ptr;
void *side_array_sg_ptr;
void *side_struct_sg_ptr;
+ struct {
+ void *ptr;
+ void *length_ptr;
+ } SIDE_PACKED side_vla_sg;
} SIDE_PACKED;
struct side_arg_dynamic_vla {
.type = _type, \
.u = { \
.side_sg = { \
- .offset = _offset, \
- .access_mode = _access_mode, \
.u = { \
.side_integer = { \
+ .offset = _offset, \
+ .access_mode = _access_mode, \
.type = { \
.attr = _attr, \
.nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \
.type = SIDE_TYPE_SG_FLOAT, \
.u = { \
.side_sg = { \
- .offset = _offset, \
- .access_mode = _access_mode, \
.u = { \
.side_float = { \
- .attr = _attr, \
- .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \
- .float_size_bits = _float_size_bits, \
- .byte_order = _byte_order, \
+ .offset = _offset, \
+ .access_mode = _access_mode, \
+ .type = { \
+ .attr = _attr, \
+ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \
+ .float_size_bits = _float_size_bits, \
+ .byte_order = _byte_order, \
+ }, \
}, \
}, \
}, \
.type = SIDE_TYPE_SG_STRUCT, \
.u = { \
.side_sg = { \
- .offset = _offset, \
- .access_mode = _access_mode, \
.u = { \
.side_struct = { \
+ .offset = _offset, \
+ .access_mode = _access_mode, \
.type = _struct_sg, \
.size = _size, \
}, \
.type = SIDE_TYPE_SG_ARRAY, \
.u = { \
.side_sg = { \
- .offset = _offset, \
- .access_mode = _access_mode, \
.u = { \
.side_array = { \
- .elem_type = _elem_type_sg, \
- .attr = _attr, \
- .length = _length, \
- .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \
+ .offset = _offset, \
+ .access_mode = _access_mode, \
+ .type = { \
+ .elem_type = _elem_type_sg, \
+ .attr = _attr, \
+ .length = _length, \
+ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \
+ }, \
}, \
}, \
}, \
#define side_field_sg_array(_name, _elem_type, _length, _offset, _access_mode, _attr) \
_side_field(_name, side_type_sg_array(SIDE_PARAM(_elem_type), _length, _offset, _access_mode, SIDE_PARAM(_attr)))
+#define side_type_sg_vla(_elem_type_sg, _offset, _access_mode, _length_type_sg, _attr) \
+ { \
+ .type = SIDE_TYPE_SG_VLA, \
+ .u = { \
+ .side_sg = { \
+ .u = { \
+ .side_vla = { \
+ .offset = _offset, \
+ .access_mode = _access_mode, \
+ .type = { \
+ .elem_type = _elem_type_sg, \
+ .attr = _attr, \
+ .nr_attr = SIDE_ARRAY_SIZE(SIDE_PARAM(_attr)), \
+ }, \
+ .length_type = _length_type_sg, \
+ }, \
+ }, \
+ }, \
+ }, \
+ }
+#define side_field_sg_vla(_name, _elem_type_sg, _offset, _access_mode, _length_type_sg, _attr) \
+ _side_field(_name, side_type_sg_vla(SIDE_PARAM(_elem_type_sg), _offset, _access_mode, SIDE_PARAM(_length_type_sg), SIDE_PARAM(_attr)))
+
#define side_elem(...) \
SIDE_COMPOUND_LITERAL(const struct side_type, __VA_ARGS__)
+#define side_length(...) \
+ SIDE_COMPOUND_LITERAL(const struct side_type, __VA_ARGS__)
+
#define side_field_list(...) \
SIDE_COMPOUND_LITERAL(const struct side_event_field, __VA_ARGS__)
/* 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) } } }
+#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) } } }
+#define side_arg_sg_vla(_ptr, _length_ptr) { .type = SIDE_TYPE_SG_VLA, .u = { .side_static = { .side_vla_sg = { .ptr = (_ptr), .length_ptr = (_length_ptr) } } } }
/* Dynamic field arguments */
}
}
+uint32_t sgvla[] = { 1, 2, 3, 4 };
+
+struct testsgvla {
+ int a;
+ uint16_t len;
+ uint32_t *p;
+};
+
+static side_define_struct(mystructsgvla,
+ side_field_list(
+ side_field_sg_signed_integer("a", offsetof(struct testsgvla, a),
+ side_struct_field_sizeof_bit(struct testsgvla, a), 0,
+ side_struct_field_sizeof_bit(struct testsgvla, a),
+ SIDE_TYPE_SG_ACCESS_ADDRESS, side_attr_list()
+ ),
+ side_field_sg_vla("nestvla",
+ side_elem(side_type_sg_unsigned_integer(0, 32, 0, 32, SIDE_TYPE_SG_ACCESS_ADDRESS, side_attr_list())),
+ offsetof(struct testsgvla, p),
+ SIDE_TYPE_SG_ACCESS_POINTER,
+ side_length(side_type_sg_unsigned_integer(offsetof(struct testsgvla, len),
+ 16, 0, 16, SIDE_TYPE_SG_ACCESS_ADDRESS, side_attr_list())),
+ side_attr_list()
+ ),
+ ),
+ side_attr_list()
+);
+
+side_static_event(my_provider_event_sgvla,
+ "myprovider", "myeventsgvla", SIDE_LOGLEVEL_DEBUG,
+ side_field_list(
+ side_field_sg_struct("structsgvla", &mystructsgvla, 0,
+ sizeof(struct testsgvla), SIDE_TYPE_SG_ACCESS_POINTER),
+ ),
+ side_attr_list()
+);
+
+static
+void test_sg_vla(void)
+{
+ side_event_cond(my_provider_event_sgvla) {
+ struct testsgvla mystruct = {
+ .a = 55,
+ .len = SIDE_ARRAY_SIZE(sgvla),
+ .p = sgvla,
+ };
+ side_event_call(my_provider_event_sgvla,
+ side_arg_list(
+ side_arg_sg_struct(&mystruct),
+ )
+ );
+ }
+}
+
+struct testsgvlaflex {
+ uint8_t len;
+ uint32_t otherfield;
+ uint64_t array[];
+};
+
+static side_define_struct(mystructsgvlaflex,
+ side_field_list(
+ side_field_sg_vla("vlaflex",
+ side_elem(side_type_sg_unsigned_integer(0, 64, 0, 64, SIDE_TYPE_SG_ACCESS_ADDRESS, side_attr_list())),
+ offsetof(struct testsgvlaflex, array),
+ SIDE_TYPE_SG_ACCESS_ADDRESS,
+ side_length(side_type_sg_unsigned_integer(offsetof(struct testsgvlaflex, len),
+ 8, 0, 8, SIDE_TYPE_SG_ACCESS_ADDRESS, side_attr_list())),
+ side_attr_list()
+ ),
+ ),
+ side_attr_list()
+);
+
+side_static_event(my_provider_event_sgvlaflex,
+ "myprovider", "myeventsgvlaflex", SIDE_LOGLEVEL_DEBUG,
+ side_field_list(
+ side_field_sg_struct("structsgvlaflex", &mystructsgvlaflex, 0,
+ sizeof(struct testsgvlaflex), SIDE_TYPE_SG_ACCESS_POINTER),
+ ),
+ side_attr_list()
+);
+
+#define VLAFLEXLEN 6
+static
+void test_sg_vla_flex(void)
+{
+ side_event_cond(my_provider_event_sgvlaflex) {
+ struct testsgvlaflex *mystruct = malloc(sizeof(*mystruct) + VLAFLEXLEN + sizeof(uint64_t));
+
+ mystruct->len = VLAFLEXLEN;
+ mystruct->otherfield = 0;
+ mystruct->array[0] = 1;
+ mystruct->array[1] = 2;
+ mystruct->array[2] = 3;
+ mystruct->array[3] = 4;
+ mystruct->array[4] = 5;
+ mystruct->array[5] = 6;
+ side_event_call(my_provider_event_sgvlaflex,
+ side_arg_list(
+ side_arg_sg_struct(mystruct),
+ )
+ );
+ free(mystruct);
+ }
+}
+
int main()
{
test_fields();
test_struct_sg_float();
test_array_sg();
test_sg_structnest();
+ test_sg_vla();
+ test_sg_vla_flex();
return 0;
}
static
uint32_t tracer_print_sg_array(const struct side_type_sg *type_sg, const void *_ptr);
static
+uint32_t tracer_print_sg_vla(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
case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
tracer_print_dynamic(item);
break;
+ case SIDE_TYPE_SG_VLA:
+ fprintf(stderr, "<scatter-gather VLA only supported within scatter-gather structures>\n");
+ abort();
default:
fprintf(stderr, "<UNKNOWN TYPE>");
abort();
}
static
-const char *tracer_sg_access(const struct side_type_sg *type_sg, const char *ptr)
+const char *tracer_sg_access(enum side_type_sg_access_mode access_mode, const char *ptr)
{
- switch (type_sg->access_mode) {
+ switch (access_mode) {
case SIDE_TYPE_SG_ACCESS_ADDRESS:
return ptr;
case SIDE_TYPE_SG_ACCESS_POINTER:
}
static
-uint32_t tracer_sg_size(const struct side_type_sg *type_sg, uint32_t len)
+uint32_t tracer_sg_size(enum side_type_sg_access_mode access_mode, uint32_t len)
{
- switch (type_sg->access_mode) {
+ switch (access_mode) {
case SIDE_TYPE_SG_ACCESS_ADDRESS:
return len;
case SIDE_TYPE_SG_ACCESS_POINTER:
}
static
-uint32_t tracer_print_sg_integer_type(const struct side_type_sg *type_sg, const void *_ptr)
+uint64_t tracer_load_sg_integer_type(const struct side_type_sg *type_sg, const void *_ptr)
{
+ enum side_type_sg_access_mode access_mode = type_sg->u.side_integer.access_mode;
+ uint32_t integer_size_bytes = type_sg->u.side_integer.type.integer_size_bits >> 3;
const char *ptr = (const char *) _ptr;
union side_integer_value value;
+
+ ptr = tracer_sg_access(access_mode, ptr + type_sg->u.side_integer.offset);
+ memcpy(&value, ptr, integer_size_bytes);
+ switch (type_sg->u.side_integer.type.integer_size_bits) {
+ case 8:
+ return (uint64_t) value.side_u8;
+ case 16:
+ return (uint64_t) value.side_u16;
+ case 32:
+ return (uint64_t) value.side_u32;
+ case 64:
+ return (uint64_t) value.side_u64;
+ default:
+ abort();
+ }
+}
+
+static
+uint32_t tracer_print_sg_integer_type(const struct side_type_sg *type_sg, const void *_ptr)
+{
+ enum side_type_sg_access_mode access_mode = type_sg->u.side_integer.access_mode;
uint32_t integer_size_bytes = type_sg->u.side_integer.type.integer_size_bits >> 3;
+ const char *ptr = (const char *) _ptr;
+ union side_integer_value value;
switch (type_sg->u.side_integer.type.integer_size_bits) {
case 8:
default:
abort();
}
- ptr = tracer_sg_access(type_sg, ptr + type_sg->offset);
+ ptr = tracer_sg_access(access_mode, ptr + type_sg->u.side_integer.offset);
memcpy(&value, ptr, 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 tracer_sg_size(type_sg, integer_size_bytes);
+ return tracer_sg_size(access_mode, integer_size_bytes);
}
static
uint32_t tracer_print_sg_float_type(const struct side_type_sg *type_sg, const void *_ptr)
{
+ enum side_type_sg_access_mode access_mode = type_sg->u.side_float.access_mode;
+ uint32_t float_size_bytes = type_sg->u.side_float.type.float_size_bits >> 3;
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) {
+ switch (type_sg->u.side_float.type.float_size_bits) {
case 16:
case 32:
case 64:
default:
abort();
}
- ptr = tracer_sg_access(type_sg, ptr + type_sg->offset);
+ ptr = tracer_sg_access(access_mode, ptr + type_sg->u.side_float.offset);
memcpy(&value, ptr, float_size_bytes);
- tracer_print_type_float(":", &type_sg->u.side_float, &value);
- return tracer_sg_size(type_sg, float_size_bytes);
+ tracer_print_type_float(":", &type_sg->u.side_float.type, &value);
+ return tracer_sg_size(access_mode, float_size_bytes);
}
static
case SIDE_TYPE_SG_ARRAY:
len = tracer_print_sg_array(&type_desc->u.side_sg, ptr);
break;
+ case SIDE_TYPE_SG_VLA:
+ len = tracer_print_sg_vla(&type_desc->u.side_sg, ptr);
+ break;
default:
fprintf(stderr, "<UNKNOWN SCATTER-GATHER TYPE>");
abort();
static
uint32_t tracer_print_sg_struct(const struct side_type_sg *type_sg, const void *_ptr)
{
+ enum side_type_sg_access_mode access_mode = type_sg->u.side_struct.access_mode;
const char *ptr = (const char *) _ptr;
uint32_t i;
- ptr = tracer_sg_access(type_sg, ptr + type_sg->offset);
+ ptr = tracer_sg_access(access_mode, ptr + type_sg->u.side_struct.offset);
print_attributes("attr", ":", type_sg->u.side_struct.type->attr, type_sg->u.side_struct.type->nr_attr);
printf("%s", type_sg->u.side_struct.type->nr_attr ? ", " : "");
printf("fields: { ");
tracer_print_sg_field(&type_sg->u.side_struct.type->fields[i], ptr);
}
printf(" }");
- return tracer_sg_size(type_sg, type_sg->u.side_struct.size);
+ return tracer_sg_size(access_mode, type_sg->u.side_struct.size);
}
static
uint32_t tracer_print_sg_array(const struct side_type_sg *type_sg, const void *_ptr)
{
+ enum side_type_sg_access_mode access_mode = type_sg->u.side_array.access_mode;
const char *ptr = (const char *) _ptr, *orig_ptr;
uint32_t i;
- ptr = tracer_sg_access(type_sg, ptr + type_sg->offset);
+ ptr = tracer_sg_access(access_mode, ptr + type_sg->u.side_array.offset);
+ orig_ptr = ptr;
+ print_attributes("attr", ":", type_sg->u.side_array.type.attr, type_sg->u.side_array.type.nr_attr);
+ printf("%s", type_sg->u.side_array.type.nr_attr ? ", " : "");
+ printf("elements: ");
+ printf("[ ");
+ for (i = 0; i < type_sg->u.side_array.type.length; i++) {
+ switch (type_sg->u.side_array.type.elem_type->type) {
+ case SIDE_TYPE_SG_VLA:
+ fprintf(stderr, "<scatter-gather VLA only supported within scatter-gather structures>\n");
+ abort();
+ default:
+ break;
+ }
+ printf("%s", i ? ", " : "");
+ ptr += tracer_print_sg_type(type_sg->u.side_array.type.elem_type, ptr);
+ }
+ printf(" ]");
+ return tracer_sg_size(access_mode, ptr - orig_ptr);
+}
+
+static
+uint32_t tracer_print_sg_vla(const struct side_type_sg *type_sg, const void *_ptr)
+{
+ enum side_type_sg_access_mode access_mode = type_sg->u.side_vla.access_mode;
+ const char *ptr = (const char *) _ptr, *orig_ptr;
+ uint32_t i, length;
+
+ /* Access length */
+ switch (type_sg->u.side_vla.length_type->type) {
+ case SIDE_TYPE_SG_UNSIGNED_INT:
+ case SIDE_TYPE_SG_SIGNED_INT:
+ break;
+ default:
+ fprintf(stderr, "<scatter-gather VLA expects integer scatter-gather length type>\n");
+ abort();
+ }
+ length = (uint32_t) tracer_load_sg_integer_type(&type_sg->u.side_vla.length_type->u.side_sg, ptr);
+ ptr = tracer_sg_access(access_mode, ptr + type_sg->u.side_vla.offset);
orig_ptr = 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 ? ", " : "");
+ print_attributes("attr", ":", type_sg->u.side_vla.type.attr, type_sg->u.side_vla.type.nr_attr);
+ printf("%s", type_sg->u.side_vla.type.nr_attr ? ", " : "");
printf("elements: ");
printf("[ ");
- for (i = 0; i < type_sg->u.side_array.length; i++) {
+ for (i = 0; i < length; i++) {
+ switch (type_sg->u.side_vla.type.elem_type->type) {
+ case SIDE_TYPE_SG_VLA:
+ fprintf(stderr, "<scatter-gather VLA only supported within scatter-gather structures>\n");
+ abort();
+ default:
+ break;
+ }
printf("%s", i ? ", " : "");
- ptr += tracer_print_sg_type(type_sg->u.side_array.elem_type, ptr);
+ ptr += tracer_print_sg_type(type_sg->u.side_vla.type.elem_type, ptr);
}
printf(" ]");
- return tracer_sg_size(type_sg, ptr - orig_ptr);
+ return tracer_sg_size(access_mode, ptr - orig_ptr);
}
struct tracer_visitor_priv {