Extend sched_process_fork with scheduling fields
[deliverable/lttng-modules.git] / lttng-events.c
index b748cce62c8f464f8743f5794d50ee927fa0c57e..176908bf6d2a4587d1d341e0e9126311a4970a00 100644 (file)
@@ -52,6 +52,8 @@
 #include <lttng-abi-old.h>
 #include <lttng-endian.h>
 #include <wrapper/vzalloc.h>
+#include <wrapper/ringbuffer/backend.h>
+#include <wrapper/ringbuffer/frontend.h>
 
 #define METADATA_CACHE_DEFAULT_SIZE 4096
 
@@ -211,6 +213,16 @@ void lttng_session_destroy(struct lttng_session *session)
        kfree(session);
 }
 
+int lttng_session_statedump(struct lttng_session *session)
+{
+       int ret;
+
+       mutex_lock(&sessions_mutex);
+       ret = lttng_statedump_start(session);
+       mutex_unlock(&sessions_mutex);
+       return ret;
+}
+
 int lttng_session_enable(struct lttng_session *session)
 {
        int ret = 0;
@@ -241,6 +253,12 @@ int lttng_session_enable(struct lttng_session *session)
        /* We need to sync enablers with session before activation. */
        lttng_session_sync_enablers(session);
 
+       /* Clear each stream's quiescent state. */
+       list_for_each_entry(chan, &session->chan, list) {
+               if (chan->channel_type != METADATA_CHANNEL)
+                       lib_ring_buffer_clear_quiescent_channel(chan->chan);
+       }
+
        ACCESS_ONCE(session->active) = 1;
        ACCESS_ONCE(session->been_active) = 1;
        ret = _lttng_session_metadata_statedump(session);
@@ -259,6 +277,7 @@ end:
 int lttng_session_disable(struct lttng_session *session)
 {
        int ret = 0;
+       struct lttng_channel *chan;
 
        mutex_lock(&sessions_mutex);
        if (!session->active) {
@@ -270,6 +289,12 @@ int lttng_session_disable(struct lttng_session *session)
        /* Set transient enabler state to "disabled" */
        session->tstate = 0;
        lttng_session_sync_enablers(session);
+
+       /* Set each stream's quiescent state. */
+       list_for_each_entry(chan, &session->chan, list) {
+               if (chan->channel_type != METADATA_CHANNEL)
+                       lib_ring_buffer_set_quiescent_channel(chan->chan);
+       }
 end:
        mutex_unlock(&sessions_mutex);
        return ret;
@@ -1736,6 +1761,62 @@ int _lttng_struct_statedump(struct lttng_session *session,
        return ret;
 }
 
+/*
+ * Must be called with sessions_mutex held.
+ */
+static
+int _lttng_variant_type_statedump(struct lttng_session *session,
+               const struct lttng_type *type,
+               size_t nesting)
+{
+       int ret;
+       uint32_t i, nr_choices;
+
+       ret = print_tabs(session, nesting);
+       if (ret)
+               return ret;
+       ret = lttng_metadata_printf(session,
+               "variant <_%s> {\n",
+               type->u.variant.tag_name);
+       if (ret)
+               return ret;
+       nr_choices = type->u.variant.nr_choices;
+       for (i = 0; i < nr_choices; i++) {
+               const struct lttng_event_field *iter_field;
+
+               iter_field = &type->u.variant.choices[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_variant_statedump(struct lttng_session *session,
+               const struct lttng_event_field *field,
+               size_t nesting)
+{
+       int ret;
+
+       ret = _lttng_variant_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.
  */
@@ -1747,7 +1828,7 @@ int _lttng_array_compound_statedump(struct lttng_session *session,
        int ret;
        const struct lttng_type *elem_type;
 
-       /* Only array of structures are currently supported. */
+       /* Only array of structures and variants are currently supported. */
        elem_type = field->type.u.array_compound.elem_type;
        switch (elem_type->atype) {
        case atype_struct:
@@ -1755,6 +1836,11 @@ int _lttng_array_compound_statedump(struct lttng_session *session,
                if (ret)
                        return ret;
                break;
+       case atype_variant:
+               ret = _lttng_variant_type_statedump(session, elem_type, nesting);
+               if (ret)
+                       return ret;
+               break;
        default:
                return -EINVAL;
        }
@@ -1779,7 +1865,7 @@ int _lttng_sequence_compound_statedump(struct lttng_session *session,
 
        length_name = field->type.u.sequence_compound.length_name;
 
-       /* Only array of structures are currently supported. */
+       /* Only array of structures and variants are currently supported. */
        elem_type = field->type.u.sequence_compound.elem_type;
        switch (elem_type->atype) {
        case atype_struct:
@@ -1787,6 +1873,11 @@ int _lttng_sequence_compound_statedump(struct lttng_session *session,
                if (ret)
                        return ret;
                break;
+       case atype_variant:
+               ret = _lttng_variant_type_statedump(session, elem_type, nesting);
+               if (ret)
+                       return ret;
+               break;
        default:
                return -EINVAL;
        }
@@ -1797,6 +1888,129 @@ int _lttng_sequence_compound_statedump(struct lttng_session *session,
        return ret;
 }
 
+/*
+ * Must be called with sessions_mutex held.
+ */
+static
+int _lttng_enum_statedump(struct lttng_session *session,
+               const struct lttng_event_field *field,
+               size_t nesting)
+{
+       const struct lttng_enum_desc *enum_desc;
+       const struct lttng_integer_type *container_type;
+       int ret;
+       unsigned int i, nr_entries;
+
+       enum_desc = field->type.u.basic.enumeration.desc;
+       container_type = &field->type.u.basic.enumeration.container_type;
+       nr_entries = enum_desc->nr_entries;
+
+       ret = print_tabs(session, nesting);
+       if (ret)
+               goto end;
+       ret = lttng_metadata_printf(session,
+               "enum : integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } {\n",
+               container_type->size,
+               container_type->alignment,
+               container_type->signedness,
+               (container_type->encoding == lttng_encode_none)
+                       ? "none"
+                       : (container_type->encoding == lttng_encode_UTF8)
+                               ? "UTF8"
+                               : "ASCII",
+               container_type->base,
+#if __BYTE_ORDER == __BIG_ENDIAN
+               container_type->reverse_byte_order ? " byte_order = le;" : ""
+#else
+               container_type->reverse_byte_order ? " byte_order = be;" : ""
+#endif
+               );
+       if (ret)
+               goto end;
+       /* Dump all entries */
+       for (i = 0; i < nr_entries; i++) {
+               const struct lttng_enum_entry *entry = &enum_desc->entries[i];
+               int j, len;
+
+               ret = print_tabs(session, nesting + 1);
+               if (ret)
+                       goto end;
+               ret = lttng_metadata_printf(session,
+                               "\"");
+               if (ret)
+                       goto end;
+               len = strlen(entry->string);
+               /* Escape the character '"' */
+               for (j = 0; j < len; j++) {
+                       char c = entry->string[j];
+
+                       switch (c) {
+                       case '"':
+                               ret = lttng_metadata_printf(session,
+                                               "\\\"");
+                               break;
+                       case '\\':
+                               ret = lttng_metadata_printf(session,
+                                               "\\\\");
+                               break;
+                       default:
+                               ret = lttng_metadata_printf(session,
+                                               "%c", c);
+                               break;
+                       }
+                       if (ret)
+                               goto end;
+               }
+               ret = lttng_metadata_printf(session, "\"");
+               if (ret)
+                       goto end;
+
+               if (entry->options.is_auto) {
+                       ret = lttng_metadata_printf(session, ",\n");
+                       if (ret)
+                               goto end;
+               } else {
+                       ret = lttng_metadata_printf(session,
+                                       " = ");
+                       if (ret)
+                               goto end;
+                       if (entry->start.signedness)
+                               ret = lttng_metadata_printf(session,
+                                       "%lld", (long long) entry->start.value);
+                       else
+                               ret = lttng_metadata_printf(session,
+                                       "%llu", entry->start.value);
+                       if (ret)
+                               goto end;
+                       if (entry->start.signedness == entry->end.signedness &&
+                                       entry->start.value
+                                               == entry->end.value) {
+                               ret = lttng_metadata_printf(session,
+                                       ",\n");
+                       } else {
+                               if (entry->end.signedness) {
+                                       ret = lttng_metadata_printf(session,
+                                               " ... %lld,\n",
+                                               (long long) entry->end.value);
+                               } else {
+                                       ret = lttng_metadata_printf(session,
+                                               " ... %llu,\n",
+                                               entry->end.value);
+                               }
+                       }
+                       if (ret)
+                               goto end;
+               }
+       }
+       ret = print_tabs(session, nesting);
+       if (ret)
+               goto end;
+       ret = lttng_metadata_printf(session, "} _%s;\n",
+                       field->name);
+end:
+       return ret;
+}
+
 /*
  * Must be called with sessions_mutex held.
  */
@@ -1831,13 +2045,7 @@ 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",
-                       field->type.u.basic.enumeration.name,
-                       field->name);
+               ret = _lttng_enum_statedump(session, field, nesting);
                break;
        case atype_array:
        {
@@ -1962,6 +2170,9 @@ int _lttng_field_statedump(struct lttng_session *session,
        case atype_sequence_compound:
                ret = _lttng_sequence_compound_statedump(session, field, nesting);
                break;
+       case atype_variant:
+               ret = _lttng_variant_statedump(session, field, nesting);
+               break;
 
        default:
                WARN_ON_ONCE(1);
@@ -2210,7 +2421,7 @@ int64_t measure_clock_offset(void)
        /* Disable interrupts to increase correlation precision. */
        local_irq_save(flags);
        monotonic[0] = trace_clock_read64();
-       getnstimeofday(&rts);      
+       getnstimeofday(&rts);
        monotonic[1] = trace_clock_read64();
        local_irq_restore(flags);
 
@@ -2444,6 +2655,9 @@ static int __init lttng_events_init(void)
        if (ret)
                return ret;
        ret = wrapper_get_pageblock_flags_mask_init();
+       if (ret)
+               return ret;
+       ret = lttng_probes_init();
        if (ret)
                return ret;
        ret = lttng_context_init();
This page took 0.028605 seconds and 5 git commands to generate.