Implement structure, compound array/sequence types
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 17 Mar 2016 16:16:09 +0000 (12:16 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 2 May 2016 16:37:33 +0000 (12:37 -0400)
Only supports structure, and compound array/sequences
containing structures at this point.

Only supported within event fields, not contexts yet.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lttng-context.c
lttng-events.c
lttng-events.h
lttng-filter.c

index 9f5cb249c984a94ea154f0cdc2ee8f3cbf82b069..933732266e9eb076ff26d0adefa1381a351b6399 100644 (file)
@@ -141,6 +141,9 @@ void lttng_context_update(struct lttng_ctx *ctx)
 
                        case atype_array:
                        case atype_sequence:
+                       case atype_struct:
+                       case atype_array_compound:
+                       case atype_sequence_compound:
                        default:
                                WARN_ON_ONCE(1);
                                break;
@@ -160,6 +163,9 @@ void lttng_context_update(struct lttng_ctx *ctx)
                        case atype_string:
                        case atype_array:
                        case atype_sequence:
+                       case atype_struct:
+                       case atype_array_compound:
+                       case atype_sequence_compound:
                        default:
                                WARN_ON_ONCE(1);
                                break;
@@ -178,6 +184,9 @@ void lttng_context_update(struct lttng_ctx *ctx)
 
                        case atype_array:
                        case atype_sequence:
+                       case atype_struct:
+                       case atype_array_compound:
+                       case atype_sequence_compound:
                        default:
                                WARN_ON_ONCE(1);
                                break;
@@ -187,6 +196,11 @@ void lttng_context_update(struct lttng_ctx *ctx)
                case atype_string:
                        break;
 
+               case atype_struct:
+               case atype_array_compound:
+               case atype_sequence_compound:
+                       break;
+
                case atype_enum:
                default:
                        WARN_ON_ONCE(1);
index 9c8cde8f976adbf38fbccfb360675dc8a73bca59..b748cce62c8f464f8743f5794d50ee927fa0c57e 100644 (file)
@@ -78,6 +78,10 @@ static
 int _lttng_session_metadata_statedump(struct lttng_session *session);
 static
 void _lttng_metadata_channel_hangup(struct lttng_metadata_stream *stream);
+static
+int _lttng_field_statedump(struct lttng_session *session,
+               const struct lttng_event_field *field,
+               size_t nesting);
 
 void synchronize_trace(void)
 {
@@ -1661,19 +1665,155 @@ err:
        return -ENOMEM;
 }
 
+static
+int print_tabs(struct lttng_session *session, size_t nesting)
+{
+       size_t i;
+
+       for (i = 0; i < nesting; i++) {
+               int ret;
+
+               ret = lttng_metadata_printf(session, "  ");
+               if (ret) {
+                       return ret;
+               }
+       }
+       return 0;
+}
+
+/*
+ * Must be called with sessions_mutex held.
+ */
+static
+int _lttng_struct_type_statedump(struct lttng_session *session,
+               const struct lttng_type *type,
+               size_t nesting)
+{
+       int ret;
+       uint32_t i, nr_fields;
+
+       ret = print_tabs(session, nesting);
+       if (ret)
+               return ret;
+       ret = lttng_metadata_printf(session,
+               "struct {\n");
+       if (ret)
+               return ret;
+       nr_fields = type->u._struct.nr_fields;
+       for (i = 0; i < nr_fields; i++) {
+               const struct lttng_event_field *iter_field;
+
+               iter_field = &type->u._struct.fields[i];
+               ret = _lttng_field_statedump(session, iter_field, nesting + 1);
+               if (ret)
+                       return ret;
+       }
+       ret = print_tabs(session, nesting);
+       if (ret)
+               return ret;
+       ret = lttng_metadata_printf(session,
+               "}");
+       return ret;
+}
+
+/*
+ * Must be called with sessions_mutex held.
+ */
+static
+int _lttng_struct_statedump(struct lttng_session *session,
+               const struct lttng_event_field *field,
+               size_t nesting)
+{
+       int ret;
+
+       ret = _lttng_struct_type_statedump(session,
+                       &field->type, nesting);
+       if (ret)
+               return ret;
+       ret = lttng_metadata_printf(session,
+               "_%s;\n",
+               field->name);
+       return ret;
+}
+
+/*
+ * Must be called with sessions_mutex held.
+ */
+static
+int _lttng_array_compound_statedump(struct lttng_session *session,
+               const struct lttng_event_field *field,
+               size_t nesting)
+{
+       int ret;
+       const struct lttng_type *elem_type;
+
+       /* Only array of structures are currently supported. */
+       elem_type = field->type.u.array_compound.elem_type;
+       switch (elem_type->atype) {
+       case atype_struct:
+               ret = _lttng_struct_type_statedump(session, elem_type, nesting);
+               if (ret)
+                       return ret;
+               break;
+       default:
+               return -EINVAL;
+       }
+       ret = lttng_metadata_printf(session,
+               " _%s[%u];\n",
+               field->name,
+               field->type.u.array_compound.length);
+       return ret;
+}
+
+/*
+ * Must be called with sessions_mutex held.
+ */
+static
+int _lttng_sequence_compound_statedump(struct lttng_session *session,
+               const struct lttng_event_field *field,
+               size_t nesting)
+{
+       int ret;
+       const char *length_name;
+       const struct lttng_type *elem_type;
+
+       length_name = field->type.u.sequence_compound.length_name;
+
+       /* Only array of structures are currently supported. */
+       elem_type = field->type.u.sequence_compound.elem_type;
+       switch (elem_type->atype) {
+       case atype_struct:
+               ret = _lttng_struct_type_statedump(session, elem_type, nesting);
+               if (ret)
+                       return ret;
+               break;
+       default:
+               return -EINVAL;
+       }
+       ret = lttng_metadata_printf(session,
+               " _%s[ _%s ];\n",
+               field->name,
+               length_name);
+       return ret;
+}
+
 /*
  * Must be called with sessions_mutex held.
  */
 static
 int _lttng_field_statedump(struct lttng_session *session,
-                        const struct lttng_event_field *field)
+               const struct lttng_event_field *field,
+               size_t nesting)
 {
        int ret = 0;
 
        switch (field->type.atype) {
        case atype_integer:
+               ret = print_tabs(session, nesting);
+               if (ret)
+                       return ret;
                ret = lttng_metadata_printf(session,
-                       "               integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s;\n",
+                       "integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s;\n",
                        field->type.u.basic.integer.size,
                        field->type.u.basic.integer.alignment,
                        field->type.u.basic.integer.signedness,
@@ -1691,8 +1831,11 @@ int _lttng_field_statedump(struct lttng_session *session,
                        field->name);
                break;
        case atype_enum:
+               ret = print_tabs(session, nesting);
+               if (ret)
+                       return ret;
                ret = lttng_metadata_printf(session,
-                       "               %s _%s;\n",
+                       "%s _%s;\n",
                        field->type.u.basic.enumeration.name,
                        field->name);
                break;
@@ -1702,15 +1845,21 @@ int _lttng_field_statedump(struct lttng_session *session,
 
                elem_type = &field->type.u.array.elem_type;
                if (field->type.u.array.elem_alignment) {
+                       ret = print_tabs(session, nesting);
+                       if (ret)
+                               return ret;
                        ret = lttng_metadata_printf(session,
-                       "               struct { } align(%u) _%s_padding;\n",
+                       "struct { } align(%u) _%s_padding;\n",
                                        field->type.u.array.elem_alignment * CHAR_BIT,
                                        field->name);
                        if (ret)
                                return ret;
                }
+               ret = print_tabs(session, nesting);
+               if (ret)
+                       return ret;
                ret = lttng_metadata_printf(session,
-                       "               integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[%u];\n",
+                       "integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[%u];\n",
                        elem_type->u.basic.integer.size,
                        elem_type->u.basic.integer.alignment,
                        elem_type->u.basic.integer.signedness,
@@ -1735,8 +1884,11 @@ int _lttng_field_statedump(struct lttng_session *session,
 
                elem_type = &field->type.u.sequence.elem_type;
                length_type = &field->type.u.sequence.length_type;
+               ret = print_tabs(session, nesting);
+               if (ret)
+                       return ret;
                ret = lttng_metadata_printf(session,
-                       "               integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } __%s_length;\n",
+                       "integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } __%s_length;\n",
                        length_type->u.basic.integer.size,
                        (unsigned int) length_type->u.basic.integer.alignment,
                        length_type->u.basic.integer.signedness,
@@ -1756,15 +1908,21 @@ int _lttng_field_statedump(struct lttng_session *session,
                        return ret;
 
                if (field->type.u.sequence.elem_alignment) {
+                       ret = print_tabs(session, nesting);
+                       if (ret)
+                               return ret;
                        ret = lttng_metadata_printf(session,
-                       "               struct { } align(%u) _%s_padding;\n",
+                       "struct { } align(%u) _%s_padding;\n",
                                        field->type.u.sequence.elem_alignment * CHAR_BIT,
                                        field->name);
                        if (ret)
                                return ret;
                }
+               ret = print_tabs(session, nesting);
+               if (ret)
+                       return ret;
                ret = lttng_metadata_printf(session,
-                       "               integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[ __%s_length ];\n",
+                       "integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[ __%s_length ];\n",
                        elem_type->u.basic.integer.size,
                        (unsigned int) elem_type->u.basic.integer.alignment,
                        elem_type->u.basic.integer.signedness,
@@ -1786,12 +1944,25 @@ int _lttng_field_statedump(struct lttng_session *session,
 
        case atype_string:
                /* Default encoding is UTF8 */
+               ret = print_tabs(session, nesting);
+               if (ret)
+                       return ret;
                ret = lttng_metadata_printf(session,
-                       "               string%s _%s;\n",
+                       "string%s _%s;\n",
                        field->type.u.basic.string.encoding == lttng_encode_ASCII ?
                                " { encoding = ASCII; }" : "",
                        field->name);
                break;
+       case atype_struct:
+               ret = _lttng_struct_statedump(session, field, nesting);
+               break;
+       case atype_array_compound:
+               ret = _lttng_array_compound_statedump(session, field, nesting);
+               break;
+       case atype_sequence_compound:
+               ret = _lttng_sequence_compound_statedump(session, field, nesting);
+               break;
+
        default:
                WARN_ON_ONCE(1);
                return -EINVAL;
@@ -1811,7 +1982,7 @@ int _lttng_context_metadata_statedump(struct lttng_session *session,
        for (i = 0; i < ctx->nr_fields; i++) {
                const struct lttng_ctx_field *field = &ctx->fields[i];
 
-               ret = _lttng_field_statedump(session, &field->event_field);
+               ret = _lttng_field_statedump(session, &field->event_field, 2);
                if (ret)
                        return ret;
        }
@@ -1829,7 +2000,7 @@ int _lttng_fields_metadata_statedump(struct lttng_session *session,
        for (i = 0; i < desc->nr_fields; i++) {
                const struct lttng_event_field *field = &desc->fields[i];
 
-               ret = _lttng_field_statedump(session, field);
+               ret = _lttng_field_statedump(session, field, 2);
                if (ret)
                        return ret;
        }
index c246860d87c4f2347037dced237fcbc8ed9bfecf..fe7628473c2afa7a7c55590379624160ebbbc0a9 100644 (file)
@@ -49,6 +49,9 @@ enum abstract_types {
        atype_array,
        atype_sequence,
        atype_string,
+       atype_struct,
+       atype_array_compound,           /* Array of compound types. */
+       atype_sequence_compound,        /* Sequence of compound types. */
        NR_ABSTRACT_TYPES,
 };
 
@@ -124,6 +127,18 @@ struct lttng_type {
                        struct lttng_basic_type elem_type;
                        unsigned int elem_alignment;    /* alignment override */
                } sequence;
+               struct {
+                       uint32_t nr_fields;
+                       struct lttng_event_field *fields; /* Array of fields. */
+               } _struct;
+               struct {
+                       struct lttng_type *elem_type;
+                       unsigned int length;            /* num. elems. */
+               } array_compound;
+               struct {
+                       struct lttng_type *elem_type;
+                       const char *length_name;
+               } sequence_compound;
        } u;
 };
 
index e96fcd30b2c03d505480824ed510331f04f3373d..96ba1d23fa497c9a51afc5ce0bad862691297d31 100644 (file)
@@ -183,6 +183,9 @@ int apply_field_reloc(struct lttng_event *event,
                case atype_string:
                        field_offset += sizeof(void *);
                        break;
+               case atype_struct:              /* Unsupported. */
+               case atype_array_compound:      /* Unsupported. */
+               case atype_sequence_compound:   /* Unsupported. */
                default:
                        return -EINVAL;
                }
@@ -215,6 +218,9 @@ int apply_field_reloc(struct lttng_event *event,
                else
                        op->op = FILTER_OP_LOAD_FIELD_REF_STRING;
                break;
+       case atype_struct:              /* Unsupported. */
+       case atype_array_compound:      /* Unsupported. */
+       case atype_sequence_compound:   /* Unsupported. */
        default:
                return -EINVAL;
        }
@@ -262,6 +268,9 @@ int apply_context_reloc(struct lttng_event *event,
                BUG_ON(ctx_field->event_field.user);
                op->op = FILTER_OP_GET_CONTEXT_REF_STRING;
                break;
+       case atype_struct:      /* Unsupported. */
+       case atype_array_compound:      /* Unsupported. */
+       case atype_sequence_compound:   /* Unsupported. */
        default:
                return -EINVAL;
        }
This page took 0.032359 seconds and 4 git commands to generate.