--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+ <attributes>
+ <attribute name="annotationpath" value="/org.lttng.scope.common.core/annotations"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
+ <attributes>
+ <attribute name="annotationpath" value="/org.lttng.scope.common.core/annotations"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.lttng.scope.lttng.kernel.core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
--- /dev/null
+eclipse.preferences.version=1
+line.separator=\n
--- /dev/null
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=f
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=info
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=error
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=error
+org.eclipse.jdt.core.compiler.problem.deadCode=error
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=error
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=error
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=error
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=error
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=error
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=enabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=error
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=info
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=error
+org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=error
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=error
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=error
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=error
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
+org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=error
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=disabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=disabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=error
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
+org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
+org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=false
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=250
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
--- /dev/null
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_tmf-style
+formatter_settings_version=12
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=true
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_functional_interfaces=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=false
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_type_arguments=false
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_lambda=true
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
--- /dev/null
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+API_USE_SCAN_FIELD_SEVERITY=Error
+API_USE_SCAN_METHOD_SEVERITY=Error
+API_USE_SCAN_TYPE_SEVERITY=Error
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
+ILLEGAL_EXTEND=Warning
+ILLEGAL_IMPLEMENT=Warning
+ILLEGAL_INSTANTIATE=Warning
+ILLEGAL_OVERRIDE=Warning
+ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_DEFAULT_METHOD=Ignore
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INVALID_ANNOTATION=Warning
+INVALID_JAVADOC_TAG=Warning
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Warning
+LEAK_EXTEND=Warning
+LEAK_FIELD_DECL=Warning
+LEAK_IMPLEMENT=Warning
+LEAK_METHOD_PARAM=Warning
+LEAK_METHOD_RETURN_TYPE=Warning
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+MISSING_EE_DESCRIPTIONS=Ignore
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+changed_execution_env=Error
+eclipse.preferences.version=1
+incompatible_api_component_version=Error
+incompatible_api_component_version_include_major_without_breaking_change=Disabled
+incompatible_api_component_version_include_minor_without_api_change=Disabled
+incompatible_api_component_version_report_major_without_breaking_change=Warning
+incompatible_api_component_version_report_minor_without_api_change=Warning
+invalid_since_tag_version=Error
+malformed_since_tag=Error
+missing_since_tag=Error
+report_api_breakage_when_major_version_incremented=Disabled
+report_resolution_errors_api_component=Warning
--- /dev/null
+compilers.f.unresolved-features=1
+compilers.f.unresolved-plugins=1
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.build.bin.includes=0
+compilers.p.build.encodings=2
+compilers.p.build.java.compiler=2
+compilers.p.build.java.compliance=1
+compilers.p.build.missing.output=2
+compilers.p.build.output.library=1
+compilers.p.build.source.library=0
+compilers.p.build.src.includes=0
+compilers.p.deprecated=1
+compilers.p.discouraged-class=1
+compilers.p.internal=1
+compilers.p.missing-packages=1
+compilers.p.missing-version-export-package=2
+compilers.p.missing-version-import-package=2
+compilers.p.missing-version-require-bundle=2
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=1
+compilers.p.unknown-attribute=1
+compilers.p.unknown-class=1
+compilers.p.unknown-element=1
+compilers.p.unknown-identifier=1
+compilers.p.unknown-resource=1
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.s.create-docs=false
+compilers.s.doc-folder=doc
+compilers.s.open-tags=1
+eclipse.preferences.version=1
--- /dev/null
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-Vendor: %Bundle-Vendor
+Bundle-Version: 0.2.0.qualifier
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.lttng.scope.lttng.kernel.core;singleton:=true
+Bundle-Activator: org.lttng.scope.lttng.kernel.core.activator.internal.Activator
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.tracecompass.tmf.core,
+ org.eclipse.tracecompass.ctf.tmf.core,
+ org.lttng.scope.common.core,
+ org.lttng.scope.lami.core,
+ ca.polymtl.dorsal.libdelorean,
+ org.lttng.scope.tmf2.views.core
+Export-Package: org.lttng.scope.lttng.kernel.core.activator.internal;x-internal:=true,
+ org.lttng.scope.lttng.kernel.core.analysis.os,
+ org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;x-internal:=true,
+ org.lttng.scope.lttng.kernel.core.analysis.os.internal;x-internal:=true,
+ org.lttng.scope.lttng.kernel.core.event.aspect,
+ org.lttng.scope.lttng.kernel.core.trace,
+ org.lttng.scope.lttng.kernel.core.trace.layout,
+ org.lttng.scope.lttng.kernel.core.trace.layout.internal;x-internal:=true,
+ org.lttng.scope.lttng.kernel.core.views.timegraph,
+ org.lttng.scope.lttng.kernel.core.views.timegraph.resources,
+ org.lttng.scope.lttng.kernel.core.views.timegraph.resources.elements,
+ org.lttng.scope.lttng.kernel.core.views.timegraph.threads
+Import-Package: com.google.common.annotations,
+ com.google.common.base,
+ com.google.common.cache,
+ com.google.common.collect,
+ com.google.common.hash,
+ com.google.common.primitives
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+###############################################################################
+# Copyright (C) 2017 EfficiOS Inc.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ about.html,\
+ plugin.properties,\
+ plugin.xml,\
+ lttng-analyses-configs/
+src.includes = about.html
+additional.bundles = org.eclipse.jdt.annotation
+jars.extra.classpath = platform:/plugin/org.eclipse.jdt.annotation
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: CPU Usage Top
+command = lttng-cputop-mi
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+analyses = cputop \
+ iolatencyfreq \
+ iolatencystats \
+ iolatencytop \
+ iolog \
+ iousagetop \
+ irqfreq \
+ irqlog \
+ irqstats \
+ memtop \
+ schedfreq \
+ schedlog \
+ schedstats \
+ schedtop \
+ syscallstats
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: I/O Latency Frequency Distribution
+command = lttng-iolatencyfreq-mi
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: I/O Latency Statistics
+command = lttng-iolatencystats-mi
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: I/O Latency Top
+command = lttng-iolatencytop-mi
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: I/O Usage Log
+command = lttng-iolog-mi
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: I/O Usage Top
+command = lttng-iousagetop-mi
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: Interrupt Frequency Distribution
+command = lttng-irqfreq-mi
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: Interrupt Log
+command = lttng-irqlog-mi
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: Interrupt Statistics
+command = lttng-irqstats-mi
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: Memory Usage Top
+command = lttng-memtop-mi
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: Scheduling Latency Frequency Distribution
+command = lttng-schedfreq-mi
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: Scheduling Latency Log
+command = lttng-schedlog-mi
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: Scheduling Latency Statistics
+command = lttng-schedstats-mi
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: Scheduling Latency Top
+command = lttng-schedtop-mi
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc. and others
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+name = LTTng-Analyses: System Call Statistics
+command = lttng-syscallstats-mi
--- /dev/null
+###############################################################################
+# Copyright (C) 2017 EfficiOS Inc.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+Bundle-Vendor = LTTng Scope
+Bundle-Name = LTTng Scope LTTng Kernel Analysis Core Plug-in
+
+tracetype.type.kernel = Linux Kernel Trace
+analysis.linuxkernel = Linux Kernel
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.linuxtools.tmf.core.analysis">
+ <module
+ analysis_module="org.lttng.scope.lttng.kernel.core.analysis.os.KernelAnalysisModule"
+ automatic="true"
+ id="org.eclipse.tracecompass.analysis.os.linux.kernel"
+ name="%analysis.linuxkernel">
+ <tracetype
+ applies="true"
+ class="org.lttng.scope.lttng.kernel.core.trace.IKernelTrace">
+ </tracetype>
+ </module>
+ </extension>
+ <extension
+ point="org.eclipse.linuxtools.tmf.core.tracetype">
+ <type
+ category="org.eclipse.linuxtools.ctf.tmf.core.category.ctf"
+ event_type="org.eclipse.tracecompass.ctf.tmf.core.event.CtfTmfEvent"
+ id="org.eclipse.linuxtools.lttng2.kernel.tracetype"
+ isDirectory="true"
+ name="%tracetype.type.kernel"
+ trace_type="org.lttng.scope.lttng.kernel.core.trace.LttngKernelTrace">
+ </type>
+ </extension>
+</plugin>
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.lttng.scope.lttng.kernel.core.activator.internal;
+
+import org.lttng.scope.common.core.ScopeCoreActivator;
+import org.lttng.scope.lttng.kernel.core.views.timegraph.resources.ResourcesCpuIrqModelProvider;
+import org.lttng.scope.lttng.kernel.core.views.timegraph.resources.ResourcesIrqModelProvider;
+import org.lttng.scope.lttng.kernel.core.views.timegraph.threads.ThreadsModelProvider;
+import org.lttng.scope.tmf2.views.core.timegraph.model.provider.TimeGraphModelProviderManager;
+
+/**
+ * Plugin activator
+ *
+ * @noreference This class should not be accessed outside of this plugin.
+ */
+public class Activator extends ScopeCoreActivator {
+
+ /**
+ * Return the singleton instance of this activator.
+ *
+ * @return The singleton instance
+ */
+ public static Activator instance() {
+ return ScopeCoreActivator.getInstance(Activator.class);
+ }
+
+ @Override
+ protected void startActions() {
+ /* Register the model providers shipped in this plugin */
+ TimeGraphModelProviderManager manager = TimeGraphModelProviderManager.instance();
+ manager.registerProviderFactory(() -> new ThreadsModelProvider());
+ manager.registerProviderFactory(() -> new ResourcesCpuIrqModelProvider());
+ manager.registerProviderFactory(() -> new ResourcesIrqModelProvider());
+
+ /* Register the built-in LTTng-Analyses descriptors */
+// try {
+// LttngAnalysesLoader.load();
+// } catch (LamiAnalysisFactoryException | IOException e) {
+// // Not the end of the world if the analyses are not available
+// logWarning("Cannot find LTTng analyses configuration files: " + e.getMessage()); //$NON-NLS-1$
+// }
+ }
+
+ @Override
+ protected void stopActions() {
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 EfficiOS Inc., Philippe Proulx
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.activator.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.eclipse.tracecompass.tmf.core.analysis.ondemand.OnDemandAnalysisManager;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.lttng.scope.lami.core.module.LamiAnalysis;
+import org.lttng.scope.lami.core.module.LamiAnalysisFactoryException;
+import org.lttng.scope.lami.core.module.LamiAnalysisFactoryFromConfigFile;
+import org.lttng.scope.lttng.kernel.core.trace.LttngKernelTrace;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+import org.lttng.scope.lttng.kernel.core.trace.layout.internal.Lttng27EventLayout;
+
+/**
+ * Loader of LTTng analyses.
+ *
+ * @author Philippe Proulx
+ */
+final class LttngAnalysesLoader {
+
+ private static final String CONFIG_DIR_NAME = "lttng-analyses-configs"; //$NON-NLS-1$
+
+ private LttngAnalysesLoader() {
+ }
+
+ private static boolean appliesTo(ITmfTrace trace) {
+ /* LTTng-Analysis is supported only on LTTng >= 2.7 kernel traces */
+ if (trace instanceof LttngKernelTrace) {
+ final LttngKernelTrace kernelTrace = (LttngKernelTrace) trace;
+ final ILttngKernelEventLayout layout = kernelTrace.getKernelEventLayout();
+
+ if (layout instanceof Lttng27EventLayout) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private static String[] getAnalysisNames() throws IOException {
+ final ClassLoader loader = LttngAnalysesLoader.class.getClassLoader();
+ final String path = "/" + CONFIG_DIR_NAME + "/index.properties"; //$NON-NLS-1$ //$NON-NLS-2$
+ final String[] names = new String[0];
+ final Properties indexProps = new Properties();
+
+ try (final InputStream in = loader.getResourceAsStream(path)) {
+ if (in == null) {
+ return names;
+ }
+
+ indexProps.load(in);
+ }
+
+ String analyses = indexProps.getProperty("analyses"); //$NON-NLS-1$
+
+ if (analyses == null) {
+ return names;
+ }
+
+ analyses = analyses.trim();
+ return analyses.split("\\s+"); //$NON-NLS-1$
+ }
+
+ public static void load() throws LamiAnalysisFactoryException, IOException {
+ final String[] names = getAnalysisNames();
+ final ClassLoader loader = LttngAnalysesLoader.class.getClassLoader();
+
+ for (final String name : names) {
+ final String path = String.format("/%s/%s.properties", CONFIG_DIR_NAME, name); //$NON-NLS-1$
+
+ try (final InputStream in = loader.getResourceAsStream(path)) {
+ if (in == null) {
+ continue;
+ }
+
+ final LamiAnalysis analysis = LamiAnalysisFactoryFromConfigFile.buildFromInputStream(in, false, LttngAnalysesLoader::appliesTo);
+ OnDemandAnalysisManager.getInstance().registerAnalysis(analysis);
+ }
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.lttng.scope.lttng.kernel.core.activator.internal;
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ ******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.tmf.core.util.Pair;
+
+/**
+ * This file defines all the attribute names used in the handler. Both the
+ * construction and query steps should use them.
+ *
+ * These should not be externalized! The values here are used as-is in the
+ * history file on disk, so they should be kept the same to keep the file format
+ * compatible. If a view shows attribute names directly, the localization should
+ * be done on the viewer side.
+ *
+ * @author Alexandre Montplaisir
+ */
+@SuppressWarnings({ "nls", "javadoc" })
+public interface Attributes {
+
+ /* First-level attributes */
+ String CPUS = "CPUs";
+ String THREADS = "Threads";
+
+ /* Sub-attributes of the CPU nodes */
+ String CURRENT_THREAD = "Current_thread";
+ String SOFT_IRQS = "Soft_IRQs";
+ String IRQS = "IRQs";
+
+ /* Sub-attributes of the Thread nodes */
+ String CURRENT_CPU_RQ = "Current_cpu_rq";
+ String PPID = "PPID";
+ String EXEC_NAME = "Exec_name";
+
+ String PRIO = "Prio";
+ String SYSTEM_CALL = "System_call";
+
+ /* Misc stuff */
+ String UNKNOWN = "Unknown";
+ String THREAD_0_PREFIX = "0_";
+ String THREAD_0_SEPARATOR = "_";
+
+ /**
+ * Build the thread attribute name.
+ *
+ * For all threads except "0" this is the string representation of the
+ * threadId. For thread "0" which is the idle thread and can be running
+ * concurrently on multiple CPUs, append "_cpuId".
+ *
+ * @param threadId
+ * the thread id
+ * @param cpuId
+ * the cpu id
+ * @return the thread attribute name null if the threadId is zero and the
+ * cpuId is null
+ */
+ public static @Nullable String buildThreadAttributeName(int threadId, @Nullable Integer cpuId) {
+ if (threadId == 0) {
+ if (cpuId == null) {
+ return null;
+ }
+ return Attributes.THREAD_0_PREFIX + String.valueOf(cpuId);
+ }
+
+ return String.valueOf(threadId);
+ }
+
+ /**
+ * Parse the thread id and CPU id from the thread attribute name string
+ *
+ * For thread "0" the attribute name is in the form "threadId_cpuId",
+ * extract both values from the string.
+ *
+ * For all other threads, the attribute name is the string representation of
+ * the threadId and there is no cpuId.
+ *
+ * @param threadAttributeName
+ * the thread attribute name
+ * @return the thread id and cpu id
+ */
+ public static Pair<Integer, Integer> parseThreadAttributeName(String threadAttributeName) {
+ Integer threadId = -1;
+ Integer cpuId = -1;
+
+ try {
+ if (threadAttributeName.startsWith(Attributes.THREAD_0_PREFIX)) {
+ threadId = 0;
+ String[] tokens = threadAttributeName.split(Attributes.THREAD_0_SEPARATOR);
+ cpuId = Integer.parseInt(tokens[1]);
+ } else {
+ threadId = Integer.parseInt(threadAttributeName);
+ }
+ } catch (NumberFormatException e1) {
+ // pass
+ }
+
+ return new Pair<>(threadId, cpuId);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2013, 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Geneviève Bastien - Initial API and implementation
+ * Mathieu Rail - Provide the requirements of the analysis
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os;
+
+import static java.util.Objects.requireNonNull;
+import static org.lttng.scope.common.core.NonNullUtils.nullToEmptyString;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
+import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.lttng.scope.lttng.kernel.core.analysis.os.internal.KernelStateProvider;
+import org.lttng.scope.lttng.kernel.core.trace.IKernelTrace;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+import org.lttng.scope.lttng.kernel.core.trace.layout.internal.LttngEventLayout;
+
+import com.google.common.primitives.Ints;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.aggregation.AttributePriorityAggregationRule;
+import ca.polymtl.dorsal.libdelorean.aggregation.IStateAggregationRule;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * State System Module for lttng kernel traces
+ *
+ * @author Geneviève Bastien
+ */
+public class KernelAnalysisModule extends TmfStateSystemAnalysisModule {
+
+ /** The ID of this analysis module */
+ public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.kernel"; //$NON-NLS-1$
+
+ @Override
+ protected @NonNull ITmfStateProvider createStateProvider() {
+ ITmfTrace trace = requireNonNull(getTrace());
+ ILttngKernelEventLayout layout;
+
+ if (trace instanceof IKernelTrace) {
+ layout = ((IKernelTrace) trace).getKernelEventLayout();
+ } else {
+ /* Fall-back to the base LttngEventLayout */
+ layout = LttngEventLayout.getInstance();
+ }
+
+ return new KernelStateProvider(trace, layout);
+ }
+
+ @Override
+ protected String getFullHelpText() {
+ return nullToEmptyString(Messages.LttngKernelAnalysisModule_Help);
+ }
+
+ @Override
+ protected void setupAggregationRules(ITmfStateSystemBuilder ss) {
+ /* Set up the virtual "IRQs" and "SoftIRQs" sub-trees */
+ final int cpusQuark = ss.getQuarkAbsoluteAndAdd(Attributes.CPUS);
+ final List<Integer> cpuQuarks = ss.getSubAttributes(cpusQuark, false);
+
+ Set<Integer> irqNumbers = cpuQuarks.stream()
+ .flatMap(quark -> {
+ int irqsQuark = ss.getQuarkRelative(quark, Attributes.IRQS);
+ List<Integer> irqQuarks = ss.getSubAttributes(irqsQuark, false);
+ return irqQuarks.stream()
+ .map(irqQuark -> ss.getAttributeName(irqQuark))
+ .map(name -> Ints.tryParse(name))
+ .filter(Objects::nonNull);
+ })
+ .collect(Collectors.toSet());
+
+ Set<Integer> softIrqNumbers = cpuQuarks.stream()
+ .flatMap(quark -> {
+ int irqsQuark = ss.getQuarkRelative(quark, Attributes.SOFT_IRQS);
+ List<Integer> irqQuarks = ss.getSubAttributes(irqsQuark, false);
+ return irqQuarks.stream()
+ .map(irqQuark -> ss.getAttributeName(irqQuark))
+ .map(name -> Ints.tryParse(name))
+ .filter(Objects::nonNull);
+ })
+ .collect(Collectors.toSet());
+
+ int irqsQuark = ss.getQuarkAbsoluteAndAdd(Attributes.IRQS);
+ if (irqsQuark == ss.getNbAttributes()) {
+ /*
+ * FIXME If we just created this attribute, make sure we put a null value into
+ * it so that upcoming queries return something. Should be fixed in the state
+ * system library.
+ */
+ ss.modifyAttribute(ss.getStartTime(), TmfStateValue.nullValue(), irqsQuark);
+ }
+ for (int irqNumber : irqNumbers) {
+ int irqQuark = ss.getQuarkRelativeAndAdd(irqsQuark, String.valueOf(irqNumber));
+ List<String[]> irqPaths = cpuQuarks.stream()
+ .map(quark -> {
+ String[] cpuQuarkPath = ss.getFullAttributePathArray(quark);
+ String[] irqAttributePath = new String[4];
+ irqAttributePath[0] = cpuQuarkPath[0];
+ irqAttributePath[1] = cpuQuarkPath[1];
+ irqAttributePath[2] = Attributes.IRQS;
+ irqAttributePath[3] = String.valueOf(irqNumber);
+ return irqAttributePath;
+ })
+ .collect(Collectors.toList());
+
+ IStateAggregationRule rule = new AttributePriorityAggregationRule(ss, irqQuark, irqPaths);
+ ss.addAggregationRule(rule);
+ }
+
+ int softIrqsQuark = ss.getQuarkAbsoluteAndAdd(Attributes.SOFT_IRQS);
+ if (softIrqsQuark == ss.getNbAttributes()) {
+ /*
+ * FIXME If we just created this attribute, make sure we put a null value into
+ * it so that upcoming queries return something. Should be fixed in the state
+ * system library.
+ */
+ ss.modifyAttribute(ss.getStartTime(), TmfStateValue.nullValue(), softIrqsQuark);
+ }
+ for (int softIrqNumber : softIrqNumbers) {
+ int softIrqQuark = ss.getQuarkRelativeAndAdd(softIrqsQuark, String.valueOf(softIrqNumber));
+ List<String[]> softIrqPaths = cpuQuarks.stream()
+ .map(quark -> {
+ String[] cpuQuarkPath = ss.getFullAttributePathArray(quark);
+ String[] irqAttributePath = new String[4];
+ irqAttributePath[0] = cpuQuarkPath[0];
+ irqAttributePath[1] = cpuQuarkPath[1];
+ irqAttributePath[2] = Attributes.SOFT_IRQS;
+ irqAttributePath[3] = String.valueOf(softIrqNumber);
+ return irqAttributePath;
+ })
+ .collect(Collectors.toList());
+
+ ss.addAggregationRule(new AttributePriorityAggregationRule(ss, softIrqQuark, softIrqPaths));
+ }
+
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014, 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystem;
+import ca.polymtl.dorsal.libdelorean.StateSystemUtils;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.exceptions.StateSystemDisposedException;
+import ca.polymtl.dorsal.libdelorean.exceptions.TimeRangeException;
+import ca.polymtl.dorsal.libdelorean.interval.ITmfStateInterval;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue.Type;
+
+/**
+ * Information provider utility class that retrieves thread-related information
+ * from a Linux Kernel Analysis
+ *
+ * @author Geneviève Bastien
+ */
+public final class KernelThreadInformationProvider {
+
+ private KernelThreadInformationProvider() {
+ }
+
+ /**
+ * Get the ID of the thread running on the CPU at time ts
+ *
+ * TODO: This method may later be replaced by an aspect, when the aspect can
+ * resolve to something that is not an event
+ *
+ * @param module
+ * The kernel analysis instance to run this method on
+ * @param cpuId
+ * The CPU number the process is running on
+ * @param ts
+ * The timestamp at which we want the running process
+ * @return The TID of the thread running on CPU cpuId at time ts or
+ * {@code null} if either no thread is running or we do not know.
+ */
+ public static @Nullable Integer getThreadOnCpu(KernelAnalysisModule module, long cpuId, long ts) {
+ ITmfStateSystem ss = module.getStateSystem();
+ if (ss == null) {
+ return null;
+ }
+ try {
+ int cpuQuark = ss.getQuarkAbsolute(Attributes.CPUS, Long.toString(cpuId), Attributes.CURRENT_THREAD);
+ ITmfStateInterval interval = ss.querySingleState(ts, cpuQuark);
+ ITmfStateValue val = interval.getStateValue();
+ if (val.getType().equals(Type.INTEGER)) {
+ return val.unboxInt();
+ }
+ } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
+ }
+ return null;
+ }
+
+ /**
+ * Get the TIDs of the threads from an analysis
+ *
+ * @param module
+ * The kernel analysis instance to run this method on
+ * @return The set of TIDs corresponding to the threads
+ */
+ public static Collection<Integer> getThreadIds(KernelAnalysisModule module) {
+ ITmfStateSystem ss = module.getStateSystem();
+ if (ss == null) {
+ return Collections.EMPTY_SET;
+ }
+ int threadQuark;
+ try {
+ threadQuark = ss.getQuarkAbsolute(Attributes.THREADS);
+ Set<@NonNull Integer> tids = new TreeSet<>();
+ for (Integer quark : ss.getSubAttributes(threadQuark, false)) {
+ final @NonNull String attributeName = ss.getAttributeName(quark);
+ tids.add(attributeName.startsWith(Attributes.THREAD_0_PREFIX) ? 0 : Integer.parseInt(attributeName));
+ }
+ return tids;
+ } catch (AttributeNotFoundException e) {
+ }
+ return Collections.EMPTY_SET;
+ }
+
+ /**
+ * Get the parent process ID of a thread
+ *
+ * @param module
+ * The kernel analysis instance to run this method on
+ * @param threadId
+ * The thread ID of the process for which to get the parent
+ * @param ts
+ * The timestamp at which to get the parent
+ * @return The parent PID or {@code null} if the PPID is not found.
+ */
+ public static @Nullable Integer getParentPid(KernelAnalysisModule module, Integer threadId, long ts) {
+ ITmfStateSystem ss = module.getStateSystem();
+ if (ss == null) {
+ return null;
+ }
+ Integer ppidNode;
+ try {
+ ppidNode = ss.getQuarkAbsolute(Attributes.THREADS, threadId.toString(), Attributes.PPID);
+ ITmfStateInterval ppidInterval = ss.querySingleState(ts, ppidNode);
+ ITmfStateValue ppidValue = ppidInterval.getStateValue();
+
+ if (ppidValue.getType().equals(Type.INTEGER)) {
+ return Integer.valueOf(ppidValue.unboxInt());
+ }
+ } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
+ }
+ return null;
+ }
+
+ /**
+ * Get the executable name of the thread ID. If the thread ID was used
+ * multiple time or the name changed in between, it will return the last
+ * name the thread has taken, or {@code null} if no name is found
+ *
+ * @param module
+ * The kernel analysis instance to run this method on
+ * @param threadId
+ * The thread ID of the process for which to get the name
+ * @return The last executable name of this process, or {@code null} if not
+ * found
+ */
+ public static @Nullable String getExecutableName(KernelAnalysisModule module, Integer threadId) {
+ ITmfStateSystem ss = module.getStateSystem();
+ if (ss == null) {
+ return null;
+ }
+ try {
+ Integer execNameNode = ss.getQuarkAbsolute(Attributes.THREADS, threadId.toString(), Attributes.EXEC_NAME);
+ List<ITmfStateInterval> execNameIntervals = StateSystemUtils.queryHistoryRange(ss, execNameNode, ss.getStartTime(), ss.getCurrentEndTime());
+
+ ITmfStateValue execNameValue;
+ String execName = null;
+ for (ITmfStateInterval interval : execNameIntervals) {
+ execNameValue = interval.getStateValue();
+ if (execNameValue.getType().equals(Type.STRING)) {
+ execName = execNameValue.unboxStr();
+ }
+ }
+ return execName;
+ } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
+ }
+ return null;
+ }
+
+ /**
+ * Get the priority of this thread at time ts
+ *
+ * @param module
+ * The kernel analysis instance to run this method on
+ * @param threadId
+ * The ID of the thread to query
+ * @param ts
+ * The timestamp at which to query
+ * @return The priority of the thread or <code>-1</code> if not available
+ */
+ public static int getThreadPriority(KernelAnalysisModule module, int threadId, long ts) {
+ ITmfStateSystem ss = module.getStateSystem();
+ if (ss == null) {
+ return -1;
+ }
+ try {
+ int prioQuark = ss.getQuarkAbsolute(Attributes.THREADS, String.valueOf(threadId), Attributes.PRIO);
+ return ss.querySingleState(ts, prioQuark).getStateValue().unboxInt();
+ } catch (AttributeNotFoundException | StateSystemDisposedException e) {
+ return -1;
+ }
+ }
+ /**
+ * Get the status intervals for a given thread with a resolution
+ *
+ * @param module
+ * The kernel analysis instance to run this method on
+ * @param threadId
+ * The ID of the thread to get the intervals for
+ * @param start
+ * The start time of the requested range
+ * @param end
+ * The end time of the requested range
+ * @param resolution
+ * The resolution or the minimal time between the requested
+ * intervals. If interval times are smaller than resolution, only
+ * the first interval is returned, the others are ignored.
+ * @param monitor
+ * A progress monitor for this task
+ * @return The list of status intervals for this thread, an empty list is
+ * returned if either the state system is {@code null} or the quark
+ * is not found
+ */
+ public static List<ITmfStateInterval> getStatusIntervalsForThread(KernelAnalysisModule module, Integer threadId, long start, long end, long resolution, IProgressMonitor monitor) {
+ ITmfStateSystem ss = module.getStateSystem();
+ if (ss == null) {
+ return Collections.EMPTY_LIST;
+ }
+
+ try {
+ int threadQuark = ss.getQuarkAbsolute(Attributes.THREADS, threadId.toString());
+ List<ITmfStateInterval> statusIntervals = StateSystemUtils.queryHistoryRange(ss, threadQuark,
+ Math.max(start, ss.getStartTime()), Math.min(end - 1, ss.getCurrentEndTime()), resolution, null);
+ return statusIntervals;
+ } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
+ }
+ return Collections.EMPTY_LIST;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 EfficiOS Inc., Alexandre Montplaisir
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os;
+
+/**
+ * Definitions of values used in the Linux kernel code.
+ *
+ * Instead of using "magic numbers" in state providers, the definitions should
+ * be added here first.
+ *
+ * @author Alexandre Montplaisir
+ */
+public interface LinuxValues {
+
+ /**
+ * Process states found in scheduler events.
+ *
+ * From include/linux/sched.h
+ *
+ * <pre>
+ * #define TASK_RUNNING 0
+ * #define TASK_INTERRUPTIBLE 1
+ * #define TASK_UNINTERRUPTIBLE 2
+ * #define __TASK_STOPPED 4
+ * #define __TASK_TRACED 8
+ * #define EXIT_DEAD 16
+ * #define EXIT_ZOMBIE 32
+ * #define EXIT_TRACE (EXIT_ZOMBIE | EXIT_DEAD)
+ * #define TASK_DEAD 64
+ * #define TASK_WAKEKILL 128
+ * #define TASK_WAKING 256
+ * #define TASK_PARKED 512
+ * #define TASK_NOLOAD 1024
+ * #define TASK_STATE_MAX 2048
+ * </pre>
+ */
+ /**
+ * The task is running normally, can be interrupted, in a syscall or user
+ * mode.
+ */
+ int TASK_STATE_RUNNING = 0;
+
+ /**
+ * The process is in an interruptible sleep, (waiting for an event to
+ * complete)
+ */
+ int TASK_INTERRUPTIBLE = 1;
+
+ /**
+ * The process is in an uninteruptible sleep, (usually waiting on IO)
+ */
+ int TASK_UNINTERRUPTIBLE = 2;
+
+ /**
+ * The process is stopped, it is waiting for a SIGCONT
+ */
+ int TASK_STOPPED__ = 4;
+
+ /**
+ * The process is being monitored by other processes like a debugger
+ */
+ int TASK_TRACED__ = 8;
+
+ /**
+ * The task is terminated. It is lingering waiting for a parent to reap it.
+ */
+ int EXIT_ZOMBIE = 16;
+
+ /**
+ * The final state, the process reaches this state when being reaped. This
+ * state should not be seen.
+ */
+ int EXIT_DEAD = 32;
+
+ /**
+ * The task is dead, that means the PID can be re-used.
+ */
+ int TASK_DEAD = 64;
+
+ /**
+ * The task will wake up only on kill signals
+ */
+ int TASK_WAKEKILL = 128;
+
+ /**
+ * A task is being woken up, should not appear in sched switch, but if we
+ * poll.
+ */
+ int TASK_WAKING = 256;
+
+ /**
+ * A very deep sleep that can only be woken by an unpark wakeup
+ */
+ int TASK_PARK = 512;
+
+ /**
+ * Task that do not contribute to load average (since Linux 4.1)
+ */
+ int TASK_NOLOAD = 1024;
+
+ /**
+ * This is the maximum value + 1 that the task state can be. TASK_STATE_MAX
+ * - 1 is useful to mask the task state.
+ */
+ int TASK_STATE_MAX = 2048;
+
+ /**
+ * Process statuses, used in LTTng statedump events.
+ *
+ * This is LTTng-specific, but the statedump are handled at this level, so
+ * it makes sense to add those definitions here.
+ *
+ * Taken from lttng-module's lttng-statedump-impl.c:
+ *
+ * <pre>
+ * enum lttng_process_status {
+ * LTTNG_UNNAMED = 0,
+ * LTTNG_WAIT_FORK = 1,
+ * LTTNG_WAIT_CPU = 2,
+ * LTTNG_EXIT = 3,
+ * LTTNG_ZOMBIE = 4,
+ * LTTNG_WAIT = 5,
+ * LTTNG_RUN = 6,
+ * LTTNG_DEAD = 7,
+ * };
+ * </pre>
+ */
+
+ /** Task is initially preempted */
+ int STATEDUMP_PROCESS_STATUS_WAIT_CPU = 2;
+
+ /** Task is initially blocked */
+ int STATEDUMP_PROCESS_STATUS_WAIT = 5;
+
+ /**
+ * SoftIRQ definitions
+ *
+ * From linux/interrupt.h
+ *
+ * <pre>
+ * enum
+ * {
+ * HI_SOFTIRQ=0,
+ * TIMER_SOFTIRQ,
+ * NET_TX_SOFTIRQ,
+ * NET_RX_SOFTIRQ,
+ * BLOCK_SOFTIRQ,
+ * BLOCK_IOPOLL_SOFTIRQ,
+ * TASKLET_SOFTIRQ,
+ * SCHED_SOFTIRQ,
+ * HRTIMER_SOFTIRQ,
+ * RCU_SOFTIRQ,
+ * NR_SOFTIRQS // not used as this is the NUMBER of softirqs
+ * };
+ * </pre>
+ */
+
+ /** High-priority tasklet */
+ int SOFTIRQ_HI = 0;
+
+ /** Interrupted because of timer */
+ int SOFTIRQ_TIMER = 1;
+
+ /** Interrupted because of network transmission */
+ int SOFTIRQ_NET_TX = 2;
+
+ /** Interrupted because of network reception */
+ int SOFTIRQ_NET_RX = 3;
+
+ /** Interrupted because of block operation */
+ int SOFTIRQ_BLOCK = 4;
+
+ /** Interrupted because of block IO */
+ int SOFTIRQ_BLOCK_IOPOLL = 5;
+
+ /** Tasklet (differed device interrupt) */
+ int SOFTIRQ_TASKLET = 6;
+
+ /** Interrupted because of the scheduler */
+ int SOFTIRQ_SCHED = 7;
+
+ /** Interrupted because of HR timer */
+ int SOFTIRQ_HRTIMER = 8;
+
+ /** Interrupted because of RCU */
+ int SOFTIRQ_RCU = 9;
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014, 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Externalized message strings from the LTTng Kernel Analysis
+ *
+ * @author Geneviève Bastien
+ * @noreference Messages class
+ */
+@NonNullByDefault({})
+@SuppressWarnings("javadoc")
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+
+ public static String LttngKernelAnalysisModule_Help;
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ ******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os;
+
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * State values that are used in the kernel event handler. It's much better to
+ * use integer values whenever possible, since those take much less space in the
+ * history file.
+ *
+ * @author Alexandre Montplaisir
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+@SuppressWarnings("javadoc")
+public interface StateValues {
+
+ /* Process status */
+ int PROCESS_STATUS_UNKNOWN = 0;
+ int PROCESS_STATUS_WAIT_BLOCKED = 1;
+ int PROCESS_STATUS_RUN_USERMODE = 2;
+ int PROCESS_STATUS_RUN_SYSCALL = 3;
+ int PROCESS_STATUS_INTERRUPTED = 4;
+ int PROCESS_STATUS_WAIT_FOR_CPU = 5;
+ int PROCESS_STATUS_WAIT_UNKNOWN = 6;
+
+ ITmfStateValue PROCESS_STATUS_UNKNOWN_VALUE = TmfStateValue.newValueInt(PROCESS_STATUS_UNKNOWN);
+ ITmfStateValue PROCESS_STATUS_WAIT_UNKNOWN_VALUE = TmfStateValue.newValueInt(PROCESS_STATUS_WAIT_UNKNOWN);
+ ITmfStateValue PROCESS_STATUS_WAIT_BLOCKED_VALUE = TmfStateValue.newValueInt(PROCESS_STATUS_WAIT_BLOCKED);
+ ITmfStateValue PROCESS_STATUS_RUN_USERMODE_VALUE = TmfStateValue.newValueInt(PROCESS_STATUS_RUN_USERMODE);
+ ITmfStateValue PROCESS_STATUS_RUN_SYSCALL_VALUE = TmfStateValue.newValueInt(PROCESS_STATUS_RUN_SYSCALL);
+ ITmfStateValue PROCESS_STATUS_INTERRUPTED_VALUE = TmfStateValue.newValueInt(PROCESS_STATUS_INTERRUPTED);
+ ITmfStateValue PROCESS_STATUS_WAIT_FOR_CPU_VALUE = TmfStateValue.newValueInt(PROCESS_STATUS_WAIT_FOR_CPU);
+
+ /* CPU Status */
+ int CPU_STATUS_IDLE = 0;
+ /**
+ * Soft IRQ raised, could happen in the CPU attribute but should not since
+ * this means that the CPU went idle when a softirq was raised.
+ */
+ int CPU_STATUS_SOFT_IRQ_RAISED = (1 << 0);
+ int CPU_STATUS_RUN_USERMODE = (1 << 1);
+ int CPU_STATUS_RUN_SYSCALL = (1 << 2);
+ int CPU_STATUS_SOFTIRQ = (1 << 3);
+ int CPU_STATUS_IRQ = (1 << 4);
+
+ ITmfStateValue CPU_STATUS_IDLE_VALUE = TmfStateValue.newValueInt(CPU_STATUS_IDLE);
+ ITmfStateValue CPU_STATUS_RUN_USERMODE_VALUE = TmfStateValue.newValueInt(CPU_STATUS_RUN_USERMODE);
+ ITmfStateValue CPU_STATUS_RUN_SYSCALL_VALUE = TmfStateValue.newValueInt(CPU_STATUS_RUN_SYSCALL);
+ ITmfStateValue CPU_STATUS_IRQ_VALUE = TmfStateValue.newValueInt(CPU_STATUS_IRQ);
+ ITmfStateValue CPU_STATUS_SOFTIRQ_VALUE = TmfStateValue.newValueInt(CPU_STATUS_SOFTIRQ);
+
+ /** Soft IRQ is raised, CPU is in user mode */
+ ITmfStateValue SOFT_IRQ_RAISED_VALUE = TmfStateValue.newValueInt(CPU_STATUS_SOFT_IRQ_RAISED);
+
+ /** If the softirq is running and another is raised at the same time. */
+ ITmfStateValue SOFT_IRQ_RAISED_RUNNING_VALUE = TmfStateValue.newValueInt(CPU_STATUS_SOFT_IRQ_RAISED | CPU_STATUS_SOFTIRQ);
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * IPI Entry Handler
+ *
+ * @author Matthew Khouzam
+ */
+public class IPIEntryHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * event layout
+ */
+ public IPIEntryHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+
+ Integer cpu = KernelEventHandlerUtils.getCpu(event);
+ if (cpu == null) {
+ return;
+ }
+ Integer irqId = ((Long) event.getContent().getField(getLayout().fieldIPIVector()).getValue()).intValue();
+
+ /*
+ * Mark this IRQ as active in the resource tree. The state value = the
+ * CPU on which this IRQ is sitting
+ */
+ int quark = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeIRQs(cpu, ss), irqId.toString());
+
+ ITmfStateValue value = TmfStateValue.newValueInt(cpu.intValue());
+ long timestamp = KernelEventHandlerUtils.getTimestamp(event);
+ ss.modifyAttribute(timestamp, value, quark);
+
+ /* Change the status of the running process to interrupted */
+ quark = KernelEventHandlerUtils.getCurrentThreadNode(cpu, ss);
+ value = StateValues.PROCESS_STATUS_INTERRUPTED_VALUE;
+ ss.modifyAttribute(timestamp, value, quark);
+
+ /* Change the status of the CPU to interrupted */
+ quark = KernelEventHandlerUtils.getCurrentCPUNode(cpu, ss);
+ value = StateValues.CPU_STATUS_IRQ_VALUE;
+ ss.modifyAttribute(timestamp, value, quark);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * IPI Exit Handler
+ *
+ * @author Matthew Khouzam
+ */
+public class IPIExitHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * event layout
+ */
+ public IPIExitHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+ Integer cpu = KernelEventHandlerUtils.getCpu(event);
+ if (cpu == null) {
+ return;
+ }
+ int currentThreadNode = KernelEventHandlerUtils.getCurrentThreadNode(cpu, ss);
+ Integer irqId = ((Long) event.getContent().getField(getLayout().fieldIPIVector()).getValue()).intValue();
+ /* Put this IRQ back to inactive in the resource tree */
+ int quark = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeIRQs(cpu, ss), irqId.toString());
+ TmfStateValue value = TmfStateValue.nullValue();
+ long timestamp = KernelEventHandlerUtils.getTimestamp(event);
+ ss.modifyAttribute(timestamp, value, quark);
+
+ /* Set the previous process back to running */
+ KernelEventHandlerUtils.setProcessToRunning(timestamp, currentThreadNode, ss);
+
+ /* Set the CPU status back to running or "idle" */
+ KernelEventHandlerUtils.cpuExitInterrupt(timestamp, cpu, ss);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * Irq Entry Handler
+ */
+public class IrqEntryHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * event layout
+ */
+ public IrqEntryHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+
+ Integer cpu = KernelEventHandlerUtils.getCpu(event);
+ if (cpu == null) {
+ return;
+ }
+ Integer irqId = ((Long) event.getContent().getField(getLayout().fieldIrq()).getValue()).intValue();
+
+ /*
+ * Mark this IRQ as active in the resource tree.
+ */
+ int quark = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeIRQs(cpu, ss), irqId.toString());
+
+ ITmfStateValue value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IRQ);
+ long timestamp = KernelEventHandlerUtils.getTimestamp(event);
+ ss.modifyAttribute(timestamp, value, quark);
+
+ /* Change the status of the running process to interrupted */
+ quark = KernelEventHandlerUtils.getCurrentThreadNode(cpu, ss);
+ value = StateValues.PROCESS_STATUS_INTERRUPTED_VALUE;
+ ss.modifyAttribute(timestamp, value, quark);
+
+ /* Change the status of the CPU to interrupted */
+ quark = KernelEventHandlerUtils.getCurrentCPUNode(cpu, ss);
+ value = StateValues.CPU_STATUS_IRQ_VALUE;
+ ss.modifyAttribute(timestamp, value, quark);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * Irq Exit handler
+ */
+public class IrqExitHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * event layout
+ */
+ public IrqExitHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+ Integer cpu = KernelEventHandlerUtils.getCpu(event);
+ if (cpu == null) {
+ return;
+ }
+ int currentThreadNode = KernelEventHandlerUtils.getCurrentThreadNode(cpu, ss);
+ Integer irqId = ((Long) event.getContent().getField(getLayout().fieldIrq()).getValue()).intValue();
+ /* Put this IRQ back to inactive in the resource tree */
+ int quark = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeIRQs(cpu, ss), irqId.toString());
+ TmfStateValue value = TmfStateValue.nullValue();
+ long timestamp = KernelEventHandlerUtils.getTimestamp(event);
+ ss.modifyAttribute(timestamp, value, quark);
+
+ /* Set the previous process back to running */
+ KernelEventHandlerUtils.setProcessToRunning(timestamp, currentThreadNode, ss);
+
+ /* Set the CPU status back to running or "idle" */
+ KernelEventHandlerUtils.cpuExitInterrupt(timestamp, cpu, ss);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+
+/**
+ * Base class for all kernel event handlers.
+ */
+public abstract class KernelEventHandler {
+
+ private final ILttngKernelEventLayout fLayout;
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * the analysis layout
+ */
+ public KernelEventHandler(ILttngKernelEventLayout layout) {
+ fLayout = layout;
+ }
+
+ /**
+ * Get the analysis layout
+ *
+ * @return the analysis layout
+ */
+ protected ILttngKernelEventLayout getLayout() {
+ return fLayout;
+ }
+
+ /**
+ * Handle a specific kernel event.
+ *
+ * @param ss
+ * the state system to write to
+ * @param event
+ * the event
+ * @throws AttributeNotFoundException
+ * if the attribute is not yet create
+ */
+ public abstract void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException;
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import java.util.List;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.event.aspect.TmfCpuAspect;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.exceptions.StateValueTypeException;
+import ca.polymtl.dorsal.libdelorean.exceptions.TimeRangeException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * Kernel Event Handler Utils is a collection of static methods to be used in
+ * subclasses of IKernelEventHandler.
+ *
+ * @author Matthew Khouzam
+ * @author Francis Giraldeau
+ */
+public final class KernelEventHandlerUtils {
+
+ private KernelEventHandlerUtils() {
+ }
+
+ /**
+ * Get CPU
+ *
+ * @param event
+ * The event containing the cpu
+ *
+ * @return the CPU number (null for not set)
+ */
+ public static @Nullable Integer getCpu(ITmfEvent event) {
+ Integer cpuObj = TmfTraceUtils.resolveIntEventAspectOfClassForEvent(event.getTrace(), TmfCpuAspect.class, event);
+ if (cpuObj == null) {
+ /* We couldn't find any CPU information, ignore this event */
+ return null;
+ }
+ return cpuObj;
+ }
+
+ /**
+ * Gets the current CPU quark
+ *
+ * @param cpuNumber
+ * The cpu number
+ * @param ss
+ * the state system
+ *
+ * @return the current CPU quark -1 for not set
+ */
+ public static int getCurrentCPUNode(Integer cpuNumber, ITmfStateSystemBuilder ss) {
+ return ss.getQuarkRelativeAndAdd(getNodeCPUs(ss), cpuNumber.toString());
+ }
+
+ /**
+ * Get the timestamp of the event
+ *
+ * @param event
+ * the event containing the timestamp
+ *
+ * @return the timestamp in long format
+ */
+ public static long getTimestamp(ITmfEvent event) {
+ return event.getTimestamp().toNanos();
+ }
+
+ /**
+ * Get the current thread node
+ *
+ * @param cpuNumber
+ * The cpu number
+ * @param ss
+ * the state system
+ *
+ * @return the current thread node quark
+ */
+ public static int getCurrentThreadNode(Integer cpuNumber, ITmfStateSystemBuilder ss) {
+ /*
+ * Shortcut for the "current thread" attribute node. It requires
+ * querying the current CPU's current thread.
+ */
+ int quark = ss.getQuarkRelativeAndAdd(getCurrentCPUNode(cpuNumber, ss), Attributes.CURRENT_THREAD);
+ ITmfStateValue value = ss.queryOngoingState(quark);
+ int thread = value.isNull() ? -1 : value.unboxInt();
+ return ss.getQuarkRelativeAndAdd(getNodeThreads(ss), Attributes.buildThreadAttributeName(thread, cpuNumber));
+ }
+
+ /**
+ * When we want to set a process back to a "running" state, first check its
+ * current System_call attribute. If there is a system call active, we put
+ * the process back in the syscall state. If not, we put it back in user
+ * mode state.
+ *
+ * @param timestamp
+ * the time in the state system of the change
+ * @param currentThreadNode
+ * The current thread node
+ * @param ssb
+ * the state system
+ * @throws TimeRangeException
+ * the time is out of range
+ * @throws StateValueTypeException
+ * the attribute was not set with int values
+ * @throws AttributeNotFoundException
+ * If the attribute is invalid
+ */
+ public static void setProcessToRunning(long timestamp, int currentThreadNode, ITmfStateSystemBuilder ssb)
+ throws TimeRangeException, StateValueTypeException, AttributeNotFoundException {
+ int quark;
+ ITmfStateValue value;
+
+ quark = ssb.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
+ if (ssb.queryOngoingState(quark).isNull()) {
+ /* We were in user mode before the interruption */
+ value = StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE;
+ } else {
+ /* We were previously in kernel mode */
+ value = StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE;
+ }
+ ssb.modifyAttribute(timestamp, value, currentThreadNode);
+ }
+
+ /**
+ * Get the IRQs node
+ *
+ * @param cpuNumber
+ * the cpu core
+ * @param ss
+ * the state system
+ * @return the IRQ node quark
+ */
+ public static int getNodeIRQs(int cpuNumber, ITmfStateSystemBuilder ss) {
+ return ss.getQuarkAbsoluteAndAdd(Attributes.CPUS, Integer.toString(cpuNumber), Attributes.IRQS);
+ }
+
+ /**
+ * Get the CPUs node
+ *
+ * @param ss
+ * the state system
+ * @return the CPU node quark
+ */
+ public static int getNodeCPUs(ITmfStateSystemBuilder ss) {
+ return ss.getQuarkAbsoluteAndAdd(Attributes.CPUS);
+ }
+
+ /**
+ * Get the Soft IRQs node
+ *
+ * @param cpuNumber
+ * the cpu core
+ * @param ss
+ * the state system
+ * @return the Soft IRQ node quark
+ */
+ public static int getNodeSoftIRQs(int cpuNumber, ITmfStateSystemBuilder ss) {
+ return ss.getQuarkAbsoluteAndAdd(Attributes.CPUS, Integer.toString(cpuNumber), Attributes.SOFT_IRQS);
+ }
+
+ /**
+ * Get the threads node
+ *
+ * @param ss
+ * the state system
+ * @return the threads quark
+ */
+ public static int getNodeThreads(ITmfStateSystemBuilder ss) {
+ return ss.getQuarkAbsoluteAndAdd(Attributes.THREADS);
+ }
+
+ /**
+ * Reset the CPU's status when it's coming out of an interruption.
+ *
+ * @param timestamp
+ * the time when the status of the cpu is "leaving irq"
+ * @param cpuNumber
+ * the cpu returning to its previous state
+ *
+ * @param ssb
+ * State system
+ * @throws StateValueTypeException
+ * the attribute is not set as an int
+ * @throws TimeRangeException
+ * the time is out of range
+ * @throws AttributeNotFoundException
+ * If the attribute is invalid
+ */
+ public static void cpuExitInterrupt(long timestamp, Integer cpuNumber, ITmfStateSystemBuilder ssb)
+ throws StateValueTypeException, TimeRangeException, AttributeNotFoundException {
+ int currentCPUNode = getCurrentCPUNode(cpuNumber, ssb);
+
+ ITmfStateValue value = getCpuStatus(ssb, currentCPUNode);
+ ssb.modifyAttribute(timestamp, value, currentCPUNode);
+ }
+
+ /**
+ * Get the ongoing Status state of a CPU.
+ *
+ * This will look through the states of the
+ *
+ * <ul>
+ * <li>IRQ</li>
+ * <li>Soft IRQ</li>
+ * <li>Process</li>
+ * </ul>
+ *
+ * under the CPU, giving priority to states higher in the list. If the state
+ * is a null value, we continue looking down the list.
+ *
+ * @param ssb
+ * The state system
+ * @param cpuQuark
+ * The *quark* of the CPU we are looking for. Careful, this is
+ * NOT the CPU number (or attribute name)!
+ * @return The state value that represents the status of the given CPU
+ * @throws AttributeNotFoundException
+ */
+ private static ITmfStateValue getCpuStatus(ITmfStateSystemBuilder ssb, int cpuQuark)
+ throws AttributeNotFoundException {
+
+ /* Check if there is a IRQ running */
+ int irqQuarks = ssb.getQuarkRelativeAndAdd(cpuQuark, Attributes.IRQS);
+ List<Integer> irqs = ssb.getSubAttributes(irqQuarks, false);
+ for (Integer quark : irqs) {
+ final ITmfStateValue irqState = ssb.queryOngoingState(quark.intValue());
+ if (!irqState.isNull()) {
+ return irqState;
+ }
+ }
+
+ /* Check if there is a soft IRQ running */
+ int softIrqQuarks = ssb.getQuarkRelativeAndAdd(cpuQuark, Attributes.SOFT_IRQS);
+ List<Integer> softIrqs = ssb.getSubAttributes(softIrqQuarks, false);
+ for (Integer quark : softIrqs) {
+ final ITmfStateValue softIrqState = ssb.queryOngoingState(quark.intValue());
+ if (!softIrqState.isNull()) {
+ return softIrqState;
+ }
+ }
+
+ /*
+ * Check if there is a thread running. If not, report IDLE. If there is,
+ * report the running state of the thread (usermode or system call).
+ */
+ int currentThreadQuark = ssb.getQuarkRelativeAndAdd(cpuQuark, Attributes.CURRENT_THREAD);
+ ITmfStateValue currentThreadState = ssb.queryOngoingState(currentThreadQuark);
+ if (currentThreadState.isNull()) {
+ return TmfStateValue.nullValue();
+ }
+ int tid = currentThreadState.unboxInt();
+ if (tid == 0) {
+ return StateValues.CPU_STATUS_IDLE_VALUE;
+ }
+ int threadSystemCallQuark = ssb.getQuarkAbsoluteAndAdd(Attributes.THREADS, Integer.toString(tid), Attributes.SYSTEM_CALL);
+ return (ssb.queryOngoingState(threadSystemCallQuark).isNull() ? StateValues.CPU_STATUS_RUN_USERMODE_VALUE : StateValues.CPU_STATUS_RUN_SYSCALL_VALUE);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * Set Prio handler
+ */
+public class PiSetprioHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ * @param layout event layout
+ */
+ public PiSetprioHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+ ITmfEventField content = event.getContent();
+ Integer cpu = KernelEventHandlerUtils.getCpu(event);
+ Integer tid = ((Long) content.getField(getLayout().fieldTid()).getValue()).intValue();
+ Integer prio = ((Long) content.getField(getLayout().fieldNewPrio()).getValue()).intValue();
+
+ String threadAttributeName = Attributes.buildThreadAttributeName(tid, cpu);
+ if (threadAttributeName == null) {
+ return;
+ }
+
+ Integer updateThreadNode = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeThreads(ss), threadAttributeName);
+
+ /* Set the current prio for the new process */
+ int quark = ss.getQuarkRelativeAndAdd(updateThreadNode, Attributes.PRIO);
+ ITmfStateValue value = TmfStateValue.newValueInt(prio);
+ ss.modifyAttribute(KernelEventHandlerUtils.getTimestamp(event), value, quark);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+
+/**
+ * Process Exit handler
+ */
+public class ProcessExitHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * event layout
+ */
+ public ProcessExitHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+ /* No state modifications tracked atm */
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * Fork Handler
+ */
+public class ProcessForkHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * event layout
+ */
+ public ProcessForkHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+ ITmfEventField content = event.getContent();
+ Integer cpu = KernelEventHandlerUtils.getCpu(event);
+ String childProcessName = (String) content.getField(getLayout().fieldChildComm()).getValue();
+
+ Integer parentTid = ((Long) content.getField(getLayout().fieldParentTid()).getValue()).intValue();
+ Integer childTid = ((Long) content.getField(getLayout().fieldChildTid()).getValue()).intValue();
+
+ String parentThreadAttributeName = Attributes.buildThreadAttributeName(parentTid, cpu);
+ if (parentThreadAttributeName == null) {
+ return;
+ }
+
+ String childThreadAttributeName = Attributes.buildThreadAttributeName(childTid, cpu);
+ if (childThreadAttributeName == null) {
+ return;
+ }
+
+ final int threadsNode = KernelEventHandlerUtils.getNodeThreads(ss);
+ Integer parentTidNode = ss.getQuarkRelativeAndAdd(threadsNode, parentThreadAttributeName);
+ Integer childTidNode = ss.getQuarkRelativeAndAdd(threadsNode, childThreadAttributeName);
+
+
+ /* Assign the PPID to the new process */
+ int quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.PPID);
+ ITmfStateValue value = TmfStateValue.newValueInt(parentTid);
+ long timestamp = KernelEventHandlerUtils.getTimestamp(event);
+ ss.modifyAttribute(timestamp, value, quark);
+
+ /* Set the new process' exec_name */
+ quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.EXEC_NAME);
+ value = TmfStateValue.newValueString(childProcessName);
+ ss.modifyAttribute(timestamp, value, quark);
+
+ /*
+ * Set the new process' status, it is initially in a blocked state. A
+ * subsequent sched_wakeup_new will schedule it.
+ */
+ value = StateValues.PROCESS_STATUS_WAIT_BLOCKED_VALUE;
+ ss.modifyAttribute(timestamp, value, childTidNode);
+
+ /* Set the process' syscall name, to be the same as the parent's */
+ quark = ss.getQuarkRelativeAndAdd(parentTidNode, Attributes.SYSTEM_CALL);
+ value = ss.queryOngoingState(quark);
+ if (!value.isNull()) {
+ quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.SYSTEM_CALL);
+ ss.modifyAttribute(timestamp, value, quark);
+ }
+
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+
+/**
+ * Process free event handler
+ */
+public class ProcessFreeHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * event layout
+ */
+ public ProcessFreeHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+
+ Integer cpu = KernelEventHandlerUtils.getCpu(event);
+ Integer tid = ((Long) event.getContent().getField(getLayout().fieldTid()).getValue()).intValue();
+
+ String threadAttributeName = Attributes.buildThreadAttributeName(tid, cpu);
+ if (threadAttributeName == null) {
+ return;
+ }
+
+ /*
+ * Remove the process and all its sub-attributes from the current state
+ */
+ int quark = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeThreads(ss), threadAttributeName);
+ ss.removeAttribute(KernelEventHandlerUtils.getTimestamp(event), quark);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * Handler for task migration events. Normally moves a (non-running) process
+ * from one run queue to another.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class SchedMigrateTaskHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * The event layout to use
+ */
+ public SchedMigrateTaskHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+ Long tid = event.getContent().getFieldValue(Long.class, getLayout().fieldTid());
+ Long destCpu = event.getContent().getFieldValue(Long.class, getLayout().fieldDestCpu());
+
+ if (tid == null || destCpu == null) {
+ return;
+ }
+
+ long t = event.getTimestamp().toNanos();
+
+ String threadAttributeName = Attributes.buildThreadAttributeName(tid.intValue(), null);
+ if (threadAttributeName == null) {
+ /* Swapper threads do not get migrated */
+ return;
+ }
+ int threadNode = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeThreads(ss), threadAttributeName);
+
+ /*
+ * Put the thread in the "wait for cpu" state. Some older versions of
+ * the kernel/tracers may not have the corresponding sched_waking events
+ * that also does so, so we can set it at the migrate, if applicable.
+ */
+ ITmfStateValue value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE;
+ ss.modifyAttribute(t, value, threadNode);
+
+ /* Update the thread's running queue to the new one indicated by the event */
+ int quark = ss.getQuarkRelativeAndAdd(threadNode, Attributes.CURRENT_CPU_RQ);
+ value = TmfStateValue.newValueInt(destCpu.intValue());
+ ss.modifyAttribute(t, value, quark);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import static java.util.Objects.requireNonNull;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.analysis.os.LinuxValues;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.exceptions.StateValueTypeException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * Scheduler switch event handler
+ */
+public class SchedSwitchHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * event layout
+ */
+ public SchedSwitchHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+ Integer cpu = KernelEventHandlerUtils.getCpu(event);
+ if (cpu == null) {
+ return;
+ }
+
+ ITmfEventField content = event.getContent();
+ String prevProcessName = requireNonNull((String) content.getField(getLayout().fieldPrevComm()).getValue());
+ Integer prevTid = ((Long) content.getField(getLayout().fieldPrevTid()).getValue()).intValue();
+ Long prevState = requireNonNull((Long) content.getField(getLayout().fieldPrevState()).getValue());
+ Integer prevPrio = ((Long) content.getField(getLayout().fieldPrevPrio()).getValue()).intValue();
+ String nextProcessName = requireNonNull((String) content.getField(getLayout().fieldNextComm()).getValue());
+ Integer nextTid = ((Long) content.getField(getLayout().fieldNextTid()).getValue()).intValue();
+ Integer nextPrio = ((Long) content.getField(getLayout().fieldNextPrio()).getValue()).intValue();
+
+ /* Will never return null since "cpu" is null checked */
+ String formerThreadAttributeName = Attributes.buildThreadAttributeName(prevTid, cpu);
+ String currenThreadAttributeName = Attributes.buildThreadAttributeName(nextTid, cpu);
+
+ int nodeThreads = KernelEventHandlerUtils.getNodeThreads(ss);
+ int formerThreadNode = ss.getQuarkRelativeAndAdd(nodeThreads, formerThreadAttributeName);
+ int newCurrentThreadNode = ss.getQuarkRelativeAndAdd(nodeThreads, currenThreadAttributeName);
+
+ long timestamp = KernelEventHandlerUtils.getTimestamp(event);
+ /*
+ * Set the status of the process that got scheduled out. This will also
+ * set it's current CPU run queue accordingly.
+ */
+ setOldProcessStatus(ss, prevState, formerThreadNode, cpu, timestamp);
+
+ /* Set the status of the new scheduled process */
+ KernelEventHandlerUtils.setProcessToRunning(timestamp, newCurrentThreadNode, ss);
+
+ /*
+ * Set the current CPU run queue of the new process. Should be already
+ * set if we've seen the previous sched_wakeup, but doesn't hurt to set
+ * it here too.
+ */
+ int quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.CURRENT_CPU_RQ);
+ ITmfStateValue value = TmfStateValue.newValueInt(cpu);
+ ss.modifyAttribute(timestamp, value, quark);
+
+ /* Set the exec name of the former process */
+ setProcessExecName(ss, prevProcessName, formerThreadNode, timestamp);
+
+ /* Set the exec name of the new process */
+ setProcessExecName(ss, nextProcessName, newCurrentThreadNode, timestamp);
+
+ /* Set the current prio for the former process */
+ setProcessPrio(ss, prevPrio, formerThreadNode, timestamp);
+
+ /* Set the current prio for the new process */
+ setProcessPrio(ss, nextPrio, newCurrentThreadNode, timestamp);
+
+ /* Set the current scheduled process on the relevant CPU */
+ int currentCPUNode = KernelEventHandlerUtils.getCurrentCPUNode(cpu, ss);
+ setCpuProcess(ss, nextTid, timestamp, currentCPUNode);
+
+ /* Set the status of the CPU itself */
+ setCpuStatus(ss, nextTid, newCurrentThreadNode, timestamp, currentCPUNode);
+ }
+
+ private static void setOldProcessStatus(ITmfStateSystemBuilder ss,
+ long prevState, int formerThreadNode, int cpu, long timestamp) {
+ ITmfStateValue value;
+ boolean staysOnRunQueue = false;
+ /*
+ * Empirical observations and look into the linux code have
+ * shown that the TASK_STATE_MAX flag is used internally and
+ * |'ed with other states, most often the running state, so it
+ * is ignored from the prevState value.
+ *
+ * Since Linux 4.1, the TASK_NOLOAD state was created and
+ * TASK_STATE_MAX is now 2048. We use TASK_NOLOAD as the new max
+ * because it does not modify the displayed state value.
+ */
+ int state = (int) (prevState & (LinuxValues.TASK_NOLOAD - 1));
+
+ if (isRunning(state)) {
+ value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE;
+ staysOnRunQueue = true;
+ } else if (isWaiting(state)) {
+ value = StateValues.PROCESS_STATUS_WAIT_BLOCKED_VALUE;
+ } else if (isDead(state)) {
+ value = TmfStateValue.nullValue();
+ } else {
+ value = StateValues.PROCESS_STATUS_WAIT_UNKNOWN_VALUE;
+ }
+ ss.modifyAttribute(timestamp, value, formerThreadNode);
+
+ int quark = ss.getQuarkRelativeAndAdd(formerThreadNode, Attributes.CURRENT_CPU_RQ);
+ if (staysOnRunQueue) {
+ /*
+ * Set the thread's run queue. This will often be redundant with
+ * previous events, but it may be the first time we see the
+ * information too.
+ */
+ value = TmfStateValue.newValueInt(cpu);
+ } else {
+ value = TmfStateValue.nullValue();
+ }
+ ss.modifyAttribute(timestamp, value, quark);
+ }
+
+ private static boolean isDead(int state) {
+ return (state & LinuxValues.TASK_DEAD) != 0;
+ }
+
+ private static boolean isWaiting(int state) {
+ return (state & (LinuxValues.TASK_INTERRUPTIBLE | LinuxValues.TASK_UNINTERRUPTIBLE)) != 0;
+ }
+
+ private static boolean isRunning(int state) {
+ // special case, this means ALL STATES ARE 0
+ // this is effectively an anti-state
+ return state == 0;
+ }
+
+ private static void setCpuStatus(ITmfStateSystemBuilder ss, Integer nextTid, Integer newCurrentThreadNode, long timestamp, int currentCPUNode)
+ throws StateValueTypeException, AttributeNotFoundException {
+ int quark;
+ ITmfStateValue value;
+ if (nextTid > 0) {
+ /* Check if the entering process is in kernel or user mode */
+ quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL);
+ ITmfStateValue queryOngoingState = ss.queryOngoingState(quark);
+ if (queryOngoingState.isNull()) {
+ value = StateValues.CPU_STATUS_RUN_USERMODE_VALUE;
+ } else {
+ value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE;
+ }
+ } else {
+ value = StateValues.CPU_STATUS_IDLE_VALUE;
+ }
+ ss.modifyAttribute(timestamp, value, currentCPUNode);
+ }
+
+ private static void setCpuProcess(ITmfStateSystemBuilder ss, Integer nextTid, long timestamp, int currentCPUNode)
+ throws StateValueTypeException, AttributeNotFoundException {
+ int quark;
+ ITmfStateValue value;
+ quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD);
+ value = TmfStateValue.newValueInt(nextTid);
+ ss.modifyAttribute(timestamp, value, quark);
+ }
+
+ private static void setProcessPrio(ITmfStateSystemBuilder ss, Integer prio, Integer threadNode, long timestamp)
+ throws StateValueTypeException, AttributeNotFoundException {
+ int quark;
+ ITmfStateValue value;
+ quark = ss.getQuarkRelativeAndAdd(threadNode, Attributes.PRIO);
+ value = TmfStateValue.newValueInt(prio);
+ ss.modifyAttribute(timestamp, value, quark);
+ }
+
+ private static void setProcessExecName(ITmfStateSystemBuilder ss, String processName, Integer threadNode, long timestamp)
+ throws StateValueTypeException, AttributeNotFoundException {
+ int quark;
+ ITmfStateValue value;
+ quark = ss.getQuarkRelativeAndAdd(threadNode, Attributes.EXEC_NAME);
+ value = TmfStateValue.newValueString(processName);
+ ss.modifyAttribute(timestamp, value, quark);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * Waking/wakeup handler.
+ *
+ * "sched_waking" and "sched_wakeup" tracepoints contain the same fields, and
+ * apply the same state transitions in our model, so they can both use this
+ * handler.
+ */
+public class SchedWakeupHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ * @param layout event layout
+ */
+ public SchedWakeupHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+ Integer cpu = KernelEventHandlerUtils.getCpu(event);
+ final int tid = ((Long) event.getContent().getField(getLayout().fieldTid()).getValue()).intValue();
+ final int prio = ((Long) event.getContent().getField(getLayout().fieldPrio()).getValue()).intValue();
+ Long targetCpu = event.getContent().getFieldValue(Long.class, getLayout().fieldTargetCpu());
+
+ String threadAttributeName = Attributes.buildThreadAttributeName(tid, cpu);
+ if (cpu == null || targetCpu == null || threadAttributeName == null) {
+ return;
+ }
+
+ final int threadNode = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeThreads(ss), threadAttributeName);
+
+ /*
+ * The process indicated in the event's payload is now ready to run.
+ * Assign it to the "wait for cpu" state, but only if it was not already
+ * running.
+ */
+ int status = ss.queryOngoingState(threadNode).unboxInt();
+ ITmfStateValue value = null;
+ long timestamp = KernelEventHandlerUtils.getTimestamp(event);
+ if (status != StateValues.PROCESS_STATUS_RUN_SYSCALL &&
+ status != StateValues.PROCESS_STATUS_RUN_USERMODE) {
+ value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE;
+ ss.modifyAttribute(timestamp, value, threadNode);
+ }
+
+ /* Set the thread's target run queue */
+ int quark = ss.getQuarkRelativeAndAdd(threadNode, Attributes.CURRENT_CPU_RQ);
+ value = TmfStateValue.newValueInt(targetCpu.intValue());
+ ss.modifyAttribute(timestamp, value, quark);
+
+ /*
+ * When a user changes a threads prio (e.g. with pthread_setschedparam),
+ * it shows in ftrace with a sched_wakeup.
+ */
+ quark = ss.getQuarkRelativeAndAdd(threadNode, Attributes.PRIO);
+ value = TmfStateValue.newValueInt(prio);
+ ss.modifyAttribute(timestamp, value, quark);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+
+/**
+ * Soft Irq Entry handler
+ */
+public class SoftIrqEntryHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * event layout
+ */
+ public SoftIrqEntryHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+ Integer cpu = KernelEventHandlerUtils.getCpu(event);
+ if (cpu == null) {
+ return;
+ }
+
+ long timestamp = KernelEventHandlerUtils.getTimestamp(event);
+ Integer softIrqId = ((Long) event.getContent().getField(getLayout().fieldVec()).getValue()).intValue();
+ int currentCPUNode = KernelEventHandlerUtils.getCurrentCPUNode(cpu, ss);
+ int currentThreadNode = KernelEventHandlerUtils.getCurrentThreadNode(cpu, ss);
+
+ /*
+ * Mark this SoftIRQ as active in the resource tree.
+ */
+ int quark = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeSoftIRQs(cpu, ss), softIrqId.toString());
+ ITmfStateValue value = StateValues.CPU_STATUS_SOFTIRQ_VALUE;
+ ss.modifyAttribute(timestamp, value, quark);
+
+ /* Change the status of the running process to interrupted */
+ value = StateValues.PROCESS_STATUS_INTERRUPTED_VALUE;
+ ss.modifyAttribute(timestamp, value, currentThreadNode);
+
+ /* Change the status of the CPU to interrupted */
+ value = StateValues.CPU_STATUS_SOFTIRQ_VALUE;
+ ss.modifyAttribute(timestamp, value, currentCPUNode);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import java.util.List;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * Soft Irq exit handler
+ */
+public class SoftIrqExitHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * event layout
+ */
+ public SoftIrqExitHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+ Integer cpu = KernelEventHandlerUtils.getCpu(event);
+ if (cpu == null) {
+ return;
+ }
+
+ Integer softIrqId = ((Long) event.getContent().getField(getLayout().fieldVec()).getValue()).intValue();
+ int currentThreadNode = KernelEventHandlerUtils.getCurrentThreadNode(cpu, ss);
+ /* Put this SoftIRQ back to inactive (= -1) in the resource tree */
+ int quark = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeSoftIRQs(cpu, ss), softIrqId.toString());
+ long timestamp = KernelEventHandlerUtils.getTimestamp(event);
+ if (isSoftIrqRaised(ss.queryOngoingState(quark))) {
+ ss.modifyAttribute(timestamp, StateValues.SOFT_IRQ_RAISED_VALUE, quark);
+ } else {
+ ss.modifyAttribute(timestamp, TmfStateValue.nullValue(), quark);
+ }
+ List<Integer> softIrqs = ss.getSubAttributes(ss.getParentAttributeQuark(quark), false);
+ /* Only set status to running and no exit if ALL softirqs are exited. */
+ for (Integer softIrq : softIrqs) {
+ if (!ss.queryOngoingState(softIrq).isNull()) {
+ return;
+ }
+ }
+ /* Set the previous process back to running */
+ KernelEventHandlerUtils.setProcessToRunning(timestamp, currentThreadNode, ss);
+
+ /* Set the CPU status back to "busy" or "idle" */
+ KernelEventHandlerUtils.cpuExitInterrupt(timestamp, cpu, ss);
+ }
+
+ /**
+ * This checks if the running <stong>bit</strong> is set
+ *
+ * @param state
+ * the state to check
+ * @return true if in a softirq. The softirq may be pre-empted by an irq
+ */
+ private static boolean isSoftIrqRaised(@Nullable ITmfStateValue state) {
+ return (state != null &&
+ !state.isNull() &&
+ (state.unboxInt() & StateValues.CPU_STATUS_SOFT_IRQ_RAISED) == StateValues.CPU_STATUS_SOFT_IRQ_RAISED);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+
+/**
+ * Raise a soft irq event
+ */
+public class SoftIrqRaiseHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * event layout
+ */
+ public SoftIrqRaiseHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+ Integer softIrqId = ((Long) event.getContent().getField(getLayout().fieldVec()).getValue()).intValue();
+ Integer cpu = KernelEventHandlerUtils.getCpu(event);
+ if (cpu == null) {
+ return;
+ }
+ /*
+ * Mark this SoftIRQ as *raised* in the resource tree.
+ */
+ int quark = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeSoftIRQs(cpu, ss), softIrqId.toString());
+
+ ITmfStateValue value = (isInSoftirq(ss.queryOngoingState(quark)) ?
+ StateValues.SOFT_IRQ_RAISED_RUNNING_VALUE :
+ StateValues.SOFT_IRQ_RAISED_VALUE);
+ ss.modifyAttribute(KernelEventHandlerUtils.getTimestamp(event), value, quark);
+
+ }
+
+ private static boolean isInSoftirq(@Nullable ITmfStateValue state) {
+ return (state != null &&
+ !state.isNull() &&
+ (state.unboxInt() & StateValues.CPU_STATUS_SOFTIRQ) == StateValues.CPU_STATUS_SOFTIRQ);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import static java.util.Objects.requireNonNull;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.analysis.os.LinuxValues;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.exceptions.StateValueTypeException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * LTTng Specific state dump event handler
+ */
+public class StateDumpHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * event layout
+ */
+ public StateDumpHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+ ITmfEventField content = event.getContent();
+ Integer eventCpu = KernelEventHandlerUtils.getCpu(event);
+ int tid = ((Long) content.getField("tid").getValue()).intValue(); //$NON-NLS-1$
+ int pid = ((Long) content.getField("pid").getValue()).intValue(); //$NON-NLS-1$
+ int ppid = ((Long) content.getField("ppid").getValue()).intValue(); //$NON-NLS-1$
+ int status = ((Long) content.getField("status").getValue()).intValue(); //$NON-NLS-1$
+ String name = requireNonNull((String) content.getField("name").getValue()); //$NON-NLS-1$
+ /* Only present in LTTng 2.10+ */
+ @Nullable Long cpuField = content.getFieldValue(Long.class, "cpu"); //$NON-NLS-1$
+ /*
+ * "mode" could be interesting too, but it doesn't seem to be populated
+ * with anything relevant for now.
+ */
+
+ String threadAttributeName = Attributes.buildThreadAttributeName(tid, eventCpu);
+ if (threadAttributeName == null) {
+ return;
+ }
+
+ int curThreadNode = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeThreads(ss), threadAttributeName);
+ long timestamp = KernelEventHandlerUtils.getTimestamp(event);
+ /* Set the process' name */
+ setProcessName(ss, name, curThreadNode, timestamp);
+
+ /* Set the process' PPID */
+ setPpid(ss, tid, pid, ppid, curThreadNode, timestamp);
+
+ /* Set the process' status */
+ setStatus(ss, status, curThreadNode, cpuField, timestamp);
+ }
+
+ private static void setStatus(ITmfStateSystemBuilder ss, int status, int curThreadNode, @Nullable Long cpu, long timestamp) {
+ ITmfStateValue value;
+ if (ss.queryOngoingState(curThreadNode).isNull()) {
+ switch (status) {
+ case LinuxValues.STATEDUMP_PROCESS_STATUS_WAIT_CPU:
+ value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE;
+ setRunQueue(ss, curThreadNode, cpu, timestamp);
+ break;
+ case LinuxValues.STATEDUMP_PROCESS_STATUS_WAIT:
+ /*
+ * We have no information on what the process is waiting on
+ * (unlike a sched_switch for example), so we will use the
+ * WAIT_UNKNOWN state instead of the "normal" WAIT_BLOCKED
+ * state.
+ */
+ value = StateValues.PROCESS_STATUS_WAIT_UNKNOWN_VALUE;
+ break;
+ default:
+ value = StateValues.PROCESS_STATUS_UNKNOWN_VALUE;
+ }
+ ss.modifyAttribute(timestamp, value, curThreadNode);
+ }
+ }
+
+ private static void setRunQueue(ITmfStateSystemBuilder ss, int curThreadNode, @Nullable Long cpu, long timestamp) {
+ if (cpu != null) {
+ int quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.CURRENT_CPU_RQ);
+ ITmfStateValue value = TmfStateValue.newValueInt(cpu.intValue());
+ ss.modifyAttribute(timestamp, value, quark);
+ }
+ }
+
+ private static void setPpid(ITmfStateSystemBuilder ss, int tid, int pid, int ppid, int curThreadNode, long timestamp)
+ throws StateValueTypeException, AttributeNotFoundException {
+ ITmfStateValue value;
+ int quark;
+ quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.PPID);
+ if (ss.queryOngoingState(quark).isNull()) {
+ if (pid == tid) {
+ /* We have a process. Use the 'PPID' field. */
+ value = TmfStateValue.newValueInt(ppid);
+ } else {
+ /* We have a thread, use the 'PID' field for the parent. */
+ value = TmfStateValue.newValueInt(pid);
+ }
+ ss.modifyAttribute(timestamp, value, quark);
+ }
+ }
+
+ private static void setProcessName(ITmfStateSystemBuilder ss, String name, int curThreadNode, long timestamp)
+ throws StateValueTypeException, AttributeNotFoundException {
+ ITmfStateValue value;
+ int quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.EXEC_NAME);
+ if (ss.queryOngoingState(quark).isNull()) {
+ /* If the value didn't exist previously, set it */
+ value = TmfStateValue.newValueString(name);
+ ss.modifyAttribute(timestamp, value, quark);
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * System call entry handler
+ */
+public class SysEntryHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * event layout
+ */
+ public SysEntryHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+ Integer cpu = KernelEventHandlerUtils.getCpu(event);
+ if (cpu == null) {
+ return;
+ }
+ /* Assign the new system call to the process */
+ int currentThreadNode = KernelEventHandlerUtils.getCurrentThreadNode(cpu, ss);
+ int quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
+ ITmfStateValue value = TmfStateValue.newValueString(event.getName());
+ long timestamp = KernelEventHandlerUtils.getTimestamp(event);
+ ss.modifyAttribute(timestamp, value, quark);
+
+ /* Put the process in system call mode */
+ value = StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE;
+ ss.modifyAttribute(timestamp, value, currentThreadNode);
+
+ /* Put the CPU in system call (kernel) mode */
+ int currentCPUNode = KernelEventHandlerUtils.getCurrentCPUNode(cpu, ss);
+ value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE;
+ ss.modifyAttribute(timestamp, value, currentCPUNode);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
+
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+import ca.polymtl.dorsal.libdelorean.statevalue.TmfStateValue;
+
+/**
+ * System call exit handler
+ */
+public class SysExitHandler extends KernelEventHandler {
+
+ /**
+ * Constructor
+ *
+ * @param layout
+ * event layout
+ */
+ public SysExitHandler(ILttngKernelEventLayout layout) {
+ super(layout);
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event) throws AttributeNotFoundException {
+ Integer cpu = KernelEventHandlerUtils.getCpu(event);
+ if (cpu == null) {
+ return;
+ }
+ /* Assign the new system call to the process */
+ int currentThreadNode = KernelEventHandlerUtils.getCurrentThreadNode(cpu, ss);
+ int quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
+ ITmfStateValue value = TmfStateValue.nullValue();
+ long timestamp = KernelEventHandlerUtils.getTimestamp(event);
+ ss.modifyAttribute(timestamp, value, quark);
+
+ /* Put the process in system call mode */
+ value = StateValues.PROCESS_STATUS_RUN_USERMODE_VALUE;
+ ss.modifyAttribute(timestamp, value, currentThreadNode);
+
+ /* Put the CPU in system call (kernel) mode */
+ int currentCPUNode = KernelEventHandlerUtils.getCurrentCPUNode(cpu, ss);
+ value = StateValues.CPU_STATUS_RUN_USERMODE_VALUE;
+ ss.modifyAttribute(timestamp, value, currentCPUNode);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ericsson - Initial API and implementation
+ *******************************************************************************/
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal;
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.analysis.os.internal;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.lttng.scope.lttng.kernel.core.activator.internal.Activator;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.IPIEntryHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.IPIExitHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.IrqEntryHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.IrqExitHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.KernelEventHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.PiSetprioHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.ProcessExitHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.ProcessForkHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.ProcessFreeHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SchedMigrateTaskHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SchedSwitchHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SchedWakeupHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SoftIrqEntryHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SoftIrqExitHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SoftIrqRaiseHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.StateDumpHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SysEntryHandler;
+import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SysExitHandler;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import com.google.common.collect.ImmutableMap;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.exceptions.StateValueTypeException;
+import ca.polymtl.dorsal.libdelorean.exceptions.TimeRangeException;
+
+/**
+ * This is the state change input plugin for the state system which handles the
+ * kernel traces.
+ *
+ * Attribute tree:
+ *
+ * <pre>
+ * |- CPUs
+ * | |- <CPU number> -> CPU Status
+ * | | |- CURRENT_THREAD
+ * | | |- SOFT_IRQS
+ * | | | |- <Soft IRQ number> -> Soft IRQ Status
+ * | | |- IRQS
+ * | | | |- <IRQ number> -> IRQ Status
+ * |- THREADS
+ * | |- <Thread number> -> Thread Status
+ * | | |- PPID
+ * | | |- EXEC_NAME
+ * | | |- PRIO
+ * | | |- SYSTEM_CALL
+ * | | |- CURRENT_CPU_RQ
+ * </pre>
+ *
+ * @author Alexandre Montplaisir
+ */
+public class KernelStateProvider extends AbstractTmfStateProvider {
+
+ // ------------------------------------------------------------------------
+ // Static fields
+ // ------------------------------------------------------------------------
+
+ /**
+ * Version number of this state provider. Please bump this if you modify the
+ * contents of the generated state history in some way.
+ */
+ private static final int VERSION = 27;
+
+ // ------------------------------------------------------------------------
+ // Fields
+ // ------------------------------------------------------------------------
+
+ private final Map<String, KernelEventHandler> fEventNames;
+ private final ILttngKernelEventLayout fLayout;
+
+ private final KernelEventHandler fSysEntryHandler;
+ private final KernelEventHandler fSysExitHandler;
+
+ // ------------------------------------------------------------------------
+ // Constructor
+ // ------------------------------------------------------------------------
+
+ /**
+ * Instantiate a new state provider plugin.
+ *
+ * @param trace
+ * The LTTng 2.0 kernel trace directory
+ * @param layout
+ * The event layout to use for this state provider. Usually
+ * depending on the tracer implementation.
+ */
+ public KernelStateProvider(ITmfTrace trace, ILttngKernelEventLayout layout) {
+ super(trace, "Kernel"); //$NON-NLS-1$
+ fLayout = layout;
+ fEventNames = buildEventNames(layout);
+
+ fSysEntryHandler = new SysEntryHandler(fLayout);
+ fSysExitHandler = new SysExitHandler(fLayout);
+ }
+
+ // ------------------------------------------------------------------------
+ // Event names management
+ // ------------------------------------------------------------------------
+
+ private static Map<String, KernelEventHandler> buildEventNames(ILttngKernelEventLayout layout) {
+ ImmutableMap.Builder<String, KernelEventHandler> builder = ImmutableMap.builder();
+
+ builder.put(layout.eventIrqHandlerEntry(), new IrqEntryHandler(layout));
+ builder.put(layout.eventIrqHandlerExit(), new IrqExitHandler(layout));
+ builder.put(layout.eventSoftIrqEntry(), new SoftIrqEntryHandler(layout));
+ builder.put(layout.eventSoftIrqExit(), new SoftIrqExitHandler(layout));
+ builder.put(layout.eventSoftIrqRaise(), new SoftIrqRaiseHandler(layout));
+ builder.put(layout.eventSchedSwitch(), new SchedSwitchHandler(layout));
+ builder.put(layout.eventSchedPiSetprio(), new PiSetprioHandler(layout));
+ builder.put(layout.eventSchedProcessFork(), new ProcessForkHandler(layout));
+ builder.put(layout.eventSchedProcessExit(), new ProcessExitHandler(layout));
+ builder.put(layout.eventSchedProcessFree(), new ProcessFreeHandler(layout));
+ builder.put(layout.eventSchedProcessWaking(), new SchedWakeupHandler(layout));
+ builder.put(layout.eventSchedMigrateTask(), new SchedMigrateTaskHandler(layout));
+
+ for (String s : layout.getIPIIrqVectorsEntries()) {
+ builder.put(s, new IPIEntryHandler(layout));
+ }
+ for (String s : layout.getIPIIrqVectorsExits()) {
+ builder.put(s, new IPIExitHandler(layout));
+ }
+
+ final String eventStatedumpProcessState = layout.eventStatedumpProcessState();
+ if (eventStatedumpProcessState != null) {
+ builder.put(eventStatedumpProcessState, new StateDumpHandler(layout));
+ }
+
+ for (String eventSchedWakeup : layout.eventsSchedWakeup()) {
+ builder.put(eventSchedWakeup, new SchedWakeupHandler(layout));
+ }
+
+ return builder.build();
+ }
+
+ // ------------------------------------------------------------------------
+ // IStateChangeInput
+ // ------------------------------------------------------------------------
+
+ @Override
+ public int getVersion() {
+ return VERSION;
+ }
+
+ @Override
+ public KernelStateProvider getNewInstance() {
+ return new KernelStateProvider(this.getTrace(), fLayout);
+ }
+
+ @Override
+ protected void eventHandle(@Nullable ITmfEvent event) {
+ if (event == null) {
+ return;
+ }
+
+ final String eventName = event.getName();
+
+ try {
+ final ITmfStateSystemBuilder ss = requireNonNull(getStateSystemBuilder());
+ /*
+ * Feed event to the history system if it's known to cause a state
+ * transition.
+ */
+ KernelEventHandler handler = fEventNames.get(eventName);
+ if (handler == null) {
+ if (isSyscallExit(eventName)) {
+ handler = fSysExitHandler;
+ } else if (isSyscallEntry(eventName)) {
+ handler = fSysEntryHandler;
+ }
+ }
+ if (handler != null) {
+ handler.handleEvent(ss, event);
+ }
+
+ } catch (AttributeNotFoundException ae) {
+ /*
+ * This would indicate a problem with the logic of the manager here,
+ * so it shouldn't happen.
+ */
+ Activator.instance().logError("Attribute not found: " + ae.getMessage(), ae); //$NON-NLS-1$
+
+ } catch (TimeRangeException tre) {
+ /*
+ * This would happen if the events in the trace aren't ordered
+ * chronologically, which should never be the case ...
+ */
+ Activator.instance().logError("TimeRangeExcpetion caught in the state system's event manager.\n" + //$NON-NLS-1$
+ "Are the events in the trace correctly ordered?\n" + tre.getMessage(), tre); //$NON-NLS-1$
+
+ } catch (StateValueTypeException sve) {
+ /*
+ * This would happen if we were trying to push/pop attributes not of
+ * type integer. Which, once again, should never happen.
+ */
+ Activator.instance().logError("State value error: " + sve.getMessage(), sve); //$NON-NLS-1$
+ }
+ }
+
+ private boolean isSyscallEntry(String eventName) {
+ return (eventName.startsWith(fLayout.eventSyscallEntryPrefix())
+ || eventName.startsWith(fLayout.eventCompatSyscallEntryPrefix()));
+ }
+
+ private boolean isSyscallExit(String eventName) {
+ return (eventName.startsWith(fLayout.eventSyscallExitPrefix()) ||
+ eventName.startsWith(fLayout.eventCompatSyscallExitPrefix()));
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ericsson - Initial API and implementation
+ *******************************************************************************/
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.lttng.scope.lttng.kernel.core.analysis.os.internal;
--- /dev/null
+###############################################################################
+# Copyright (c) 2014, 2015 École Polytechnique de Montréal
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Geneviève Bastien - Initial API and implementation
+###############################################################################
+
+LttngKernelAnalysisModule_Help=Builds the LTTng2 kernel state system to populate the Control Flow view and the Resources View
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ericsson - Initial API and implementation
+ *******************************************************************************/
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.lttng.scope.lttng.kernel.core.analysis.os;
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.event.aspect;
+
+import static org.lttng.scope.common.core.NonNullUtils.nullToEmptyString;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
+import org.eclipse.tracecompass.tmf.core.event.aspect.TmfCpuAspect;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+import org.lttng.scope.lttng.kernel.core.analysis.os.KernelAnalysisModule;
+import org.lttng.scope.lttng.kernel.core.analysis.os.KernelThreadInformationProvider;
+
+/**
+ * This aspect finds the ID of the thread running from this event using the
+ * {@link KernelAnalysisModule}.
+ *
+ * @author Geneviève Bastien
+ */
+public final class KernelTidAspect implements ITmfEventAspect<Integer> {
+
+ /** The singleton instance */
+ public static final KernelTidAspect INSTANCE = new KernelTidAspect();
+
+ private static final IProgressMonitor NULL_MONITOR = new NullProgressMonitor();
+
+ private KernelTidAspect() {
+ }
+
+ @Override
+ public String getName() {
+ return nullToEmptyString(Messages.KernelTidAspect_Name);
+ }
+
+ @Override
+ public String getHelpText() {
+ return nullToEmptyString(Messages.KernelTidAspect_HelpText);
+ }
+
+ @Override
+ public @Nullable Integer resolve(ITmfEvent event) {
+ return resolve(event, false, NULL_MONITOR);
+ }
+
+ @Override
+ public @Nullable Integer resolve(@NonNull ITmfEvent event, boolean block, final IProgressMonitor monitor) {
+ /* Find the CPU this event is run on */
+ Integer cpu = TmfTraceUtils.resolveIntEventAspectOfClassForEvent(event.getTrace(),
+ TmfCpuAspect.class, event);
+ if (cpu == null) {
+ return null;
+ }
+
+ /* Find the analysis module for the trace */
+ KernelAnalysisModule analysis = TmfTraceUtils.getAnalysisModuleOfClass(event.getTrace(),
+ KernelAnalysisModule.class, KernelAnalysisModule.ID);
+ if (analysis == null) {
+ return null;
+ }
+ long ts = event.getTimestamp().toNanos();
+ while (block && !analysis.isQueryable(ts) && !monitor.isCanceled()) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ return KernelThreadInformationProvider.getThreadOnCpu(analysis, cpu, ts);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.event.aspect;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @noreference Messages class
+ */
+@NonNullByDefault({})
+@SuppressWarnings("javadoc")
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+
+ public static String ThreadPriorityAspect_Name;
+ public static String ThreadPriorityAspect_HelpText;
+
+ public static String KernelTidAspect_Name;
+ public static String KernelTidAspect_HelpText;
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Keba AG
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian Mansky - Initial implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.event.aspect;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
+import org.eclipse.tracecompass.tmf.core.event.aspect.TmfCpuAspect;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+import org.lttng.scope.common.core.NonNullUtils;
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.analysis.os.KernelAnalysisModule;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystem;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.exceptions.StateSystemDisposedException;
+import ca.polymtl.dorsal.libdelorean.exceptions.TimeRangeException;
+import ca.polymtl.dorsal.libdelorean.interval.ITmfStateInterval;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+
+/**
+ * This aspect finds the priority of the thread running from this event using
+ * the {@link KernelAnalysisModule}.
+ *
+ * @author Christian Mansky
+ */
+public final class ThreadPriorityAspect implements ITmfEventAspect<Integer> {
+
+ /** The singleton instance */
+ public static final ThreadPriorityAspect INSTANCE = new ThreadPriorityAspect();
+
+ private ThreadPriorityAspect() {
+ }
+
+ @Override
+ public final String getName() {
+ return NonNullUtils.nullToEmptyString(Messages.ThreadPriorityAspect_Name);
+ }
+
+ @Override
+ public final String getHelpText() {
+ return NonNullUtils.nullToEmptyString(Messages.ThreadPriorityAspect_HelpText);
+ }
+
+ @Override
+ public @Nullable Integer resolve(ITmfEvent event) {
+ final @NonNull ITmfTrace trace = event.getTrace();
+ KernelAnalysisModule kernelAnalysis = TmfTraceUtils.getAnalysisModuleOfClass(trace, KernelAnalysisModule.class, KernelAnalysisModule.ID);
+ if (kernelAnalysis == null) {
+ return null;
+ }
+
+ ITmfStateSystem ss = kernelAnalysis.getStateSystem();
+ if (ss == null) {
+ return null;
+ }
+
+ Integer tid = KernelTidAspect.INSTANCE.resolve(event);
+ if (tid == null) {
+ return null;
+ }
+
+ final long ts = event.getTimestamp().getValue();
+ Integer execPrio = null;
+ try {
+ Integer cpu = 0;
+ if (tid == 0) {
+ /* Find the CPU this event is run on */
+ cpu = TmfTraceUtils.resolveIntEventAspectOfClassForEvent(trace, TmfCpuAspect.class, event);
+ }
+ int execPrioQuark = ss.getQuarkAbsolute(Attributes.THREADS, Attributes.buildThreadAttributeName(tid, cpu), Attributes.PRIO);
+ ITmfStateInterval interval = ss.querySingleState(ts, execPrioQuark);
+ ITmfStateValue prioValue = interval.getStateValue();
+ /* We know the prio must be an Integer */
+ execPrio = prioValue.unboxInt();
+ } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
+ }
+ return execPrio;
+ }
+}
--- /dev/null
+###############################################################################
+# Copyright (c) 2015 École Polytechnique de Montréal
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# École Polytechnique de Montréal - Initial API and implementation
+###############################################################################
+
+ThreadPriorityAspect_Name = Prio
+ThreadPriorityAspect_HelpText = The priority of the thread this event belongs to
+
+KernelTidAspect_Name = TID
+KernelTidAspect_HelpText = The TID of the thread this event belongs to
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * École Polytechnique de Montréal - Initial API and implementation
+ *******************************************************************************/
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.lttng.scope.lttng.kernel.core.event.aspect;
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ ******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.trace;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+/**
+ * Trace type that represents a Linux kernel trace.
+ *
+ * Any trace implementing the interface should be able to run the different
+ * Linux kernel analyses in this plugin.
+ *
+ * @author Alexandre Montplaisir
+ */
+@NonNullByDefault
+public interface IKernelTrace extends ITmfTrace {
+
+ /**
+ * Get the event layout of this trace. Many known concepts from the Linux
+ * kernel may be exported under different names, depending on the tracer.
+ *
+ * @return The event layout
+ */
+ ILttngKernelEventLayout getKernelEventLayout();
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Matthew Khouzam - Improved validation
+ ******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.trace;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.ctf.tmf.core.event.CtfTmfEventType;
+import org.eclipse.tracecompass.ctf.tmf.core.trace.CtfTmfTrace;
+import org.eclipse.tracecompass.ctf.tmf.core.trace.CtfTraceValidationStatus;
+import org.eclipse.tracecompass.ctf.tmf.core.trace.CtfUtils;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
+import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus;
+import org.lttng.scope.lttng.kernel.core.activator.internal.Activator;
+import org.lttng.scope.lttng.kernel.core.event.aspect.KernelTidAspect;
+import org.lttng.scope.lttng.kernel.core.event.aspect.ThreadPriorityAspect;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+import org.lttng.scope.lttng.kernel.core.trace.layout.internal.Lttng26EventLayout;
+import org.lttng.scope.lttng.kernel.core.trace.layout.internal.Lttng27EventLayout;
+import org.lttng.scope.lttng.kernel.core.trace.layout.internal.Lttng28EventLayout;
+import org.lttng.scope.lttng.kernel.core.trace.layout.internal.Lttng29EventLayout;
+import org.lttng.scope.lttng.kernel.core.trace.layout.internal.LttngEventLayout;
+import org.lttng.scope.lttng.kernel.core.trace.layout.internal.PerfEventLayout;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This is the specification of CtfTmfTrace for use with LTTng 2.x kernel
+ * traces.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class LttngKernelTrace extends CtfTmfTrace implements IKernelTrace {
+
+ /**
+ * Supported Linux kernel tracers
+ */
+ private enum OriginTracer {
+ LTTNG(LttngEventLayout.getInstance()),
+ LTTNG26(Lttng26EventLayout.getInstance()),
+ LTTNG27(Lttng27EventLayout.getInstance()),
+ LTTNG28(Lttng28EventLayout.getInstance()),
+ LTTNG29(Lttng29EventLayout.getInstance()),
+ PERF(PerfEventLayout.getInstance());
+
+ private final @NonNull ILttngKernelEventLayout fLayout;
+
+ private OriginTracer(@NonNull ILttngKernelEventLayout layout) {
+ fLayout = layout;
+ }
+ }
+
+ /**
+ * Event aspects available for all Lttng Kernel traces
+ */
+ private static final @NonNull Collection<ITmfEventAspect<?>> LTTNG_KERNEL_ASPECTS;
+
+ static {
+ ImmutableSet.Builder<ITmfEventAspect<?>> builder = ImmutableSet.builder();
+ builder.addAll(CtfTmfTrace.CTF_ASPECTS);
+ builder.add(KernelTidAspect.INSTANCE);
+ builder.add(ThreadPriorityAspect.INSTANCE);
+ LTTNG_KERNEL_ASPECTS = builder.build();
+ }
+
+ /**
+ * CTF metadata identifies trace type and tracer version pretty well, we are
+ * quite confident in the inferred trace type.
+ */
+ private static final int CONFIDENCE = 100;
+
+ /** The tracer which originated this trace */
+ private OriginTracer fOriginTracer = null;
+
+ /**
+ * Default constructor
+ */
+ public LttngKernelTrace() {
+ super();
+ }
+
+ @Override
+ public @NonNull ILttngKernelEventLayout getKernelEventLayout() {
+ OriginTracer tracer = fOriginTracer;
+ if (tracer == null) {
+ throw new IllegalStateException("Cannot get the layout of a non-initialized trace!"); //$NON-NLS-1$
+ }
+ return tracer.fLayout;
+ }
+
+ @Override
+ public void initTrace(IResource resource, String path,
+ Class<? extends ITmfEvent> eventType) throws TmfTraceException {
+ super.initTrace(resource, path, eventType);
+ fOriginTracer = getTracerFromEnv();
+ }
+
+ /**
+ * Identify which tracer generated a trace from its metadata.
+ */
+ private OriginTracer getTracerFromEnv() {
+ String tracerName = CtfUtils.getTracerName(this);
+ int tracerMajor = CtfUtils.getTracerMajorVersion(this);
+ int tracerMinor = CtfUtils.getTracerMinorVersion(this);
+
+ if ("perf".equals(tracerName)) { //$NON-NLS-1$
+ return OriginTracer.PERF;
+
+ } else if ("lttng-modules".equals(tracerName)) { //$NON-NLS-1$
+ /* Look for specific versions of LTTng */
+ if (tracerMajor >= 2) {
+ if (tracerMinor >= 9) {
+ return OriginTracer.LTTNG29;
+ } else if (tracerMinor >= 8) {
+ return OriginTracer.LTTNG28;
+ } else if (tracerMinor >= 7) {
+ return OriginTracer.LTTNG27;
+ } else if (tracerMinor >= 6) {
+ return OriginTracer.LTTNG26;
+ }
+ }
+ }
+
+ /* Use base LTTng layout as default */
+ return OriginTracer.LTTNG;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This implementation sets the confidence to 100 if the trace is a valid
+ * CTF trace in the "kernel" domain.
+ */
+ @Override
+ public IStatus validate(final IProject project, final String path) {
+ IStatus status = super.validate(project, path);
+ if (status instanceof CtfTraceValidationStatus) {
+ Map<String, String> environment = ((CtfTraceValidationStatus) status).getEnvironment();
+ /* Make sure the domain is "kernel" in the trace's env vars */
+ String domain = environment.get("domain"); //$NON-NLS-1$
+ if (domain == null || !domain.equals("\"kernel\"")) { //$NON-NLS-1$
+ return new Status(IStatus.ERROR, Activator.instance().getPluginId(), Messages.LttngKernelTrace_DomainError);
+ }
+ return new TraceValidationStatus(CONFIDENCE, Activator.instance().getPluginId());
+ }
+ return status;
+ }
+
+ @Override
+ public Iterable<ITmfEventAspect<?>> getEventAspects() {
+ return LTTNG_KERNEL_ASPECTS;
+ }
+
+ /*
+ * Needs explicit @NonNull generic type annotation. Can be removed once this
+ * class becomes @NonNullByDefault.
+ */
+ @Override
+ public @NonNull Set<@NonNull CtfTmfEventType> getContainedEventTypes() {
+ return super.getContainedEventTypes();
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2013, 2014 Ericsson.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.trace;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Message bundle for lttng2.kernel.core.trace
+ *
+ * @author Matthew Khouzam
+ * @noreference Messages class
+ */
+@SuppressWarnings("javadoc")
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+
+ public static String LttngKernelTrace_DomainError;
+ public static String LttngKernelTrace_MalformedTrace;
+ public static String LttngKernelTrace_TraceReadError;
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014, 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ ******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.trace.layout;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Interface to define "concepts" present in the Linux kernel (represented by
+ * its tracepoints), that can then be exposed by different tracers under
+ * different names.
+ *
+ * @author Alexandre Montplaisir
+ * @author Matthew Khouzam - Javadoc
+ */
+public interface ILttngKernelEventLayout {
+
+ // ------------------------------------------------------------------------
+ // Common definitions
+ // ------------------------------------------------------------------------
+
+ /**
+ * Whenever a process appears for the first time in a trace, we assume it
+ * starts inside this system call. (The syscall prefix is defined by the
+ * implementer of this interface.)
+ *
+ * TODO Change to a default method with Java 8?
+ */
+ String INITIAL_SYSCALL_NAME = "clone"; //$NON-NLS-1$
+
+ // ------------------------------------------------------------------------
+ // Event names
+ // ------------------------------------------------------------------------
+
+ /**
+ * The system has just entered an interrupt handler or interrupt service
+ * routine. On some systems, this is known as the first level interrupt
+ * handler.
+ *
+ * @return the event name
+ */
+ String eventIrqHandlerEntry();
+
+ /**
+ * The system will soon return from an interrupt handler or interrupt
+ * service routine.
+ *
+ * @return the event name
+ */
+ String eventIrqHandlerExit();
+
+ /**
+ * Whenever a system call is about to return to userspace, or a hardware
+ * interrupt handler exits, any 'software interrupts' which are marked
+ * pending (usually by hardware interrupts) are run. Much of the real
+ * interrupt handling work is done here. The soft IRQ is also known as a
+ * deferred IRQ in windows. An event identifying as this needs to occur as
+ * the system is beginning to process the interrupt.
+ *
+ * @return the event name
+ */
+ String eventSoftIrqEntry();
+
+ /**
+ * Whenever a system call is about to return to userspace, or a hardware
+ * interrupt handler exits, any 'software interrupts' which are marked
+ * pending (usually by hardware interrupts) are run Much of the real
+ * interrupt handling work is done here. The soft IRQ is also known as a
+ * deferred IRQ in windows. An event identifying as this needs to occur as
+ * the system is returning from the interrupt.
+ *
+ * @return the event name
+ */
+ String eventSoftIrqExit();
+
+ /**
+ * Whenever a system call is about to return to userspace, or a hardware
+ * interrupt handler exits, any 'software interrupts' which are marked
+ * pending (usually by hardware interrupts) are run Much of the real
+ * interrupt handling work is done here. The soft IRQ is also known as a
+ * deferred IRQ in windows. An event identifying as this needs to occur as
+ * the system is signaling the need to enter the interrupt.
+ *
+ * @return the event name
+ */
+ String eventSoftIrqRaise();
+
+ /**
+ * The scheduler will call a scheduler switch event when it is removing a
+ * task from a cpu and placing another one in its place. Which task and when
+ * depend on the scheduling strategy and the task priorities. This is a
+ * context switch.
+ *
+ * @return the event name
+ */
+ String eventSchedSwitch();
+
+ /**
+ * sched_PI_setprio is a tracepoint called often when the schedulder
+ * priorities for a given task changes.
+ *
+ * @return the event name
+ */
+ String eventSchedPiSetprio();
+
+ /**
+ * Scheduler is waking up a task. this happens before it is executed, and
+ * the data is loaded in memory if needed.
+ *
+ * @return the event names, as there are often several different ways to
+ * wake up
+ */
+ Collection<String> eventsSchedWakeup();
+
+ /**
+ * Scheduler just forked a process, that means it has duplicated the program
+ * and assigned it a different process ID. This event is often followed by
+ * an {@link #eventSchedProcessExec()}. In windows, this is part of the
+ * "spawn" process.
+ *
+ * @return the event name
+ */
+ String eventSchedProcessFork();
+
+ /**
+ * The process has finished running and the scheduler takes its TID back.
+ *
+ * @return the event name
+ */
+ String eventSchedProcessExit();
+
+ /**
+ * The process free tracepoint is called when a process has finished running
+ * and the scheduler retrieves it's process ID.
+ *
+ * @return the event name
+ */
+ String eventSchedProcessFree();
+
+ /**
+ * Optional event used by some tracers to deliver an initial state.
+ *
+ * @return the event name
+ */
+ @Nullable String eventStatedumpProcessState();
+
+ /**
+ * System call entry prefix, something like "sys_open" or just "sys".
+ *
+ * @return the event name
+ */
+ String eventSyscallEntryPrefix();
+
+ /**
+ * System call compatibility layer entry prefix, something like
+ * "compat_sys".
+ *
+ * @return the event name
+ */
+ String eventCompatSyscallEntryPrefix();
+
+ /**
+ * System call exit prefix, something like "sys_exit".
+ *
+ * @return the event name
+ */
+ String eventSyscallExitPrefix();
+
+ /**
+ * System call compatibility layer exit prefix, something like
+ * "compat_syscall_exit".
+ *
+ * @return the event name
+ */
+ String eventCompatSyscallExitPrefix();
+
+ /**
+ * The scheduler replaced the current process image with a new one. The
+ * process should also be renamed at this point. In windows, this is part of
+ * the spawn process as well as fork.
+ *
+ * @return the event name
+ */
+ String eventSchedProcessExec();
+
+ /**
+ * The scheduler calls wakeup on a sleeping process. The process will
+ * probably soon be scheduled in.
+ *
+ * @return the event name
+ */
+ String eventSchedProcessWakeup();
+
+ /**
+ * The scheduler calls wakeup on a sleeping process. The process will
+ * probably soon be scheduled in. The new wakeup knows who triggered the
+ * wakeup.
+ *
+ * @return the event name
+ */
+ String eventSchedProcessWakeupNew();
+
+ /**
+ * Event called when waking a task; this event is guaranteed to be called
+ * from the waking context.
+ *
+ * @return The name of the event
+ */
+ default String eventSchedProcessWaking() {
+ return "sched_waking"; //$NON-NLS-1$
+ }
+
+ /**
+ * Migration event, moving a non-running thread from one CPU's run queue to
+ * another.
+ *
+ * @return The event name
+ */
+ String eventSchedMigrateTask();
+
+ /**
+ * Starting the high resolution timer
+ * <p>
+ * In Linux, High resolution timers are used in the following:
+ * <ul>
+ * <li>nanosleep</li>
+ * <li>itimers</li>
+ * <li>posix timers</li>
+ * </ul>
+ *
+ * @return the event name
+ */
+ String eventHRTimerStart();
+
+ /**
+ * Canceling the high resolution timer
+ * <p>
+ * In Linux, High resolution timers are used in the following:
+ * <ul>
+ * <li>nanosleep</li>
+ * <li>itimers</li>
+ * <li>posix timers</li>
+ * </ul>
+ *
+ * @return the event name
+ */
+ String eventHRTimerCancel();
+
+ /**
+ * Entering the high resolution timer expired handler.
+ * <p>
+ * In Linux, High resolution timers are used in the following:
+ * <ul>
+ * <li>nanosleep</li>
+ * <li>itimers</li>
+ * <li>posix timers</li>
+ * </ul>
+ *
+ * @return the event name
+ */
+ String eventHRTimerExpireEntry();
+
+ /**
+ * Exiting the high resolution timer expired handler.
+ * <p>
+ * In Linux, High resolution timers are used in the following:
+ * <ul>
+ * <li>nanosleep</li>
+ * <li>itimers</li>
+ * <li>posix timers</li>
+ * </ul>
+ *
+ * @return the event name
+ */
+ String eventHRTimerExpireExit();
+
+ /**
+ * The kernel just allocated a page of memory.
+ * <p>
+ * In Linux, this typically means a user space application just got a page
+ * of ram.
+ *
+ * @return the event name
+ */
+ String eventKmemPageAlloc();
+
+ /**
+ * The kernel just deallocated a page of memory.
+ * <p>
+ * In Linux, this typically means a page of ram was just freed
+ *
+ * @return the event name
+ */
+ String eventKmemPageFree();
+
+ /**
+ * <em>Interprocessor interrupts</em> (IPIs) are special types of interrupts by which
+ * one processor will interrupt another in a multi-core and multi-cpu system. They are
+ * typically used for
+ * <ol>
+ * <li>cache flushes</li>
+ * <li>shutdowns</li>
+ * <ol>
+ * They are not logged with standard events, but rather events looking like
+ * "x86_irq_vectors_thermal_apic_exit".
+ * <p>
+ * This event describes the entries into IPIs.
+ *
+ * @return the IPI list
+ */
+ default Collection<String> getIPIIrqVectorsEntries() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * <em>Interprocessor interrupts</em> (IPIs) are special types of interrupts by which
+ * one processor will interrupt another in a multi-core and multi-cpu system. They are
+ * typically used for
+ * <ol>
+ * <li>cache flushes</li>
+ * <li>shutdowns</li>
+ * <ol>
+ * They are not logged with standard events, but rather events looking like
+ * "x86_irq_vectors_thermal_apic_exit".
+ * <p>
+ * This event describes the exits into IPIs.
+ *
+ * @return the IPI list
+ */
+ default Collection<String> getIPIIrqVectorsExits() {
+ return Collections.emptyList();
+ }
+
+ // ------------------------------------------------------------------------
+ // Event field names
+ // ------------------------------------------------------------------------
+
+ /**
+ * The field with the IRQ number. This is used in irq_handlers (entry and
+ * exit). For soft IRQs see {@link #fieldVec}.
+ *
+ * @return the name of the field with the IRQ number
+ */
+ String fieldIrq();
+
+ /**
+ * The field with the vector. This is the soft IRQ vector field used in soft
+ * IRQ raise, entry and exit. For hardware IRQs see {@link #fieldIrq}.
+ *
+ * @return the name of the field with the soft IRQ vector name
+ */
+ String fieldVec();
+
+ /**
+ * The field with the thread ID. This is often used in scheduler calls to
+ * know which thread is being affected. (normally not in switch, but in
+ * priority and wakeup calls).
+ *
+ * @return the name of the field with the thread ID
+ */
+ String fieldTid();
+
+ /**
+ * The field with the previous thread id. This is used in switching
+ * operations of a scheduler, when a thread is scheduled out for another,
+ * this field shows the thread id being scheduled out.
+ *
+ * @return The name of the field with the ID of the previous thread
+ */
+ String fieldPrevTid();
+
+ /**
+ * The field with the state of the previous thread. This is used in
+ * switching operations of a scheduler, when a thread is scheduled out for
+ * another, this field shows the state of the thread being scheduled out.
+ *
+ * @return the name of the field of the previous thread's state
+ */
+ String fieldPrevState();
+
+ /**
+ * The field with the next command to be run. This is used in switching
+ * operations of a scheduler, when a thread is scheduled out for another,
+ * this field shows the command being scheduled in. A command's value is
+ * often a String like "ls" or "hl3.exe".
+ *
+ * @return the name of the field with the next command to be run
+ */
+ String fieldNextComm();
+
+ /**
+ * The field with the next thread ID. This is used in switching operations
+ * of a scheduler, when a thread is scheduled out for another, this field
+ * shows the thread being scheduled in.
+ *
+ * @return the name of the field with the next thread ID
+ */
+ String fieldNextTid();
+
+ /**
+ * The field with the child command. This field is used in clone and spawn
+ * activities, to know which executable the clone is running.
+ *
+ * @return the name of the field with the child command
+ */
+ String fieldChildComm();
+
+ /**
+ * The field with the parent thread ID. This field is used in clone and
+ * spawn activities, to know which thread triggered the clone.
+ *
+ * @return the name of the field with the parent thread ID
+ */
+ String fieldParentTid();
+
+ /**
+ * The field with the child thread ID. This field is used in clone and spawn
+ * activities, to know which thread is the clone.
+ *
+ * @return the name of the field with the child thread ID
+ */
+ String fieldChildTid();
+
+ /**
+ * The field with the command. This is used in scheduling tracepoints that
+ * are not switches, and show the current process name. It is often a string
+ * like "zsh" or "cmd.exe".
+ *
+ * @return the name of the command field
+ */
+ String fieldComm();
+
+ /**
+ * The field with the name. The name field is used in several disjoint
+ * events.
+ * <p>
+ * Examples include:
+ * <ul>
+ * <li>writeback_* - the name of the io device, often "(unknown)"</li>
+ * <li>module_* - the name of the module such as "binfmt_misc"</li>
+ * <li>irq_handler_entry - the field describes the name of the handler such
+ * as "i915"</li>
+ * <ul>
+ *
+ * @return the name of the field with a name
+ */
+ String fieldName();
+
+ /**
+ * The field with the status. Often functions like a return value before we
+ * hit an exit.
+ * <p>
+ * Examples include:
+ * <ul>
+ * <li>ext4* - status</li>
+ * <li>asoc_snd_soc_cache_sync</li>
+ * <li>rpc_*</li>
+ * <li>state dumps</li>
+ * </ul>
+ *
+ * @return The name of the field with a status
+ */
+ String fieldStatus();
+
+ /**
+ * The field with the last command to be run. This is often a string
+ * representing the command of the thread being scheduled out from a
+ * scheduler switch operation.
+ *
+ * @return the name of the field with the last command to be run
+ */
+ String fieldPrevComm();
+
+ /**
+ * The field with the file name field. This is a string used mostly with
+ * file operations. These operations are often wrapped in system calls and
+ * can be:
+ * <ul>
+ * <li>open</li>
+ * <li>change mode</li>
+ * <li>change directory</li>
+ * <li>stat</li>
+ * </ul>
+ * It can also be used in exec commands to see what the command name should
+ * be.
+ * <p>
+ * Please note that file read and write often do not use the file name, they
+ * just use the file handle.
+ *
+ * @return the name of the field with the file name
+ */
+ String fieldFilename();
+
+ /**
+ * The field with the priority. The priority of a given process is used by
+ * most scheduler events. The major exception is the switching operation as
+ * it has two processes so it has a previous and next priority.
+ *
+ * @return the name of the field with the thread or process' priority
+ */
+ String fieldPrio();
+
+ /**
+ * The field with the new priority. This is used in the scheduler's
+ * pi_setprio event event to show the new priority of the thread or process.
+ *
+ * @return the name of the field with the thread or process' new priority
+ */
+ String fieldNewPrio();
+
+ /**
+ * The field with the prev priority. This is used in the scheduler's switch
+ * event to show the priority of the thread being scheduled out.
+ *
+ * @return the name of the field with the priority of the previous thread
+ */
+ String fieldPrevPrio();
+
+ /**
+ * The field with the next priority. This is used in the scheduler's switch
+ * event to show the priority of the next thread or process.
+ *
+ * @return the name of the field with the thread or process' next priority
+ */
+ String fieldNextPrio();
+
+ /**
+ * The field with the hrtimer. The hrtimer holds the timer instance.
+ *
+ * @return the name of the hrTimer field
+ */
+ String fieldHRtimer();
+
+ /**
+ * The field with the expires value. The expires field holds the expiry
+ * time. of the hrtimer.
+ *
+ * @return the name of the expires field
+ */
+ String fieldHRtimerExpires();
+
+ /**
+ * Gets the field name with the softexpires value. The softexpire value is
+ * the absolute earliest expiry time of the hrtimer.
+ *
+ * @return the name of the softexpires field
+ */
+ String fieldHRtimerSoftexpires();
+
+ /**
+ * The field of the function address value. The function field holds timer
+ * expiry callback function.
+ *
+ * @return the name of the function field
+ */
+ String fieldHRtimerFunction();
+
+ /**
+ * The field of the now value. The now field holds the current time.
+ *
+ * @return the name of the now field (hrtimer)
+ */
+ String fieldHRtimerNow();
+
+ /**
+ * The field containing the return value of a system call exit.
+ *
+ * @return The name of return field
+ */
+ default String fieldSyscallRet() {
+ return "ret"; //$NON-NLS-1$
+ }
+
+ /**
+ * Field indicating the upcoming CPU of sched_wakeup and sched_waking
+ * events.
+ *
+ * @return The field name
+ */
+ default String fieldTargetCpu() {
+ return "target_cpu"; //$NON-NLS-1$
+ }
+
+ /**
+ * Field of scheduler migration events, indicating the destination CPU of a
+ * thread being migrated.
+ *
+ * @return The field name
+ */
+ default String fieldDestCpu() {
+ return "dest_cpu"; //$NON-NLS-1$
+ }
+
+ // ------------------------------------------------------------------------
+ // I/O events and fields
+ // ------------------------------------------------------------------------
+
+ /**
+ * A request to a block IO has just been inserted in the waiting queue.
+ *
+ * @return The name of the event
+ */
+ default String eventBlockRqInsert() {
+ return "block_rq_insert"; //$NON-NLS-1$
+ }
+
+ /**
+ * A request to a block IO has just been issued and passed from the waiting
+ * queue to the driver queue. It is being served.
+ *
+ * @return The name of the event
+ */
+ default String eventBlockRqIssue() {
+ return "block_rq_issue"; //$NON-NLS-1$
+ }
+
+ /**
+ * A request to a block IO has just been completed.
+ *
+ * @return The name of the event
+ */
+ default String eventBlockRqComplete() {
+ return "block_rq_complete"; //$NON-NLS-1$
+ }
+
+ /**
+ * A BIO operation is being merged at the front of a waiting request
+ *
+ * @return The name of the event
+ */
+ default String eventBlockBioFrontmerge() {
+ return "block_bio_frontmerge"; //$NON-NLS-1$
+ }
+
+ /**
+ * A BIO operation is being merged at the back of a waiting request
+ *
+ * @return The name of the event
+ */
+ default String eventBlockBioBackmerge() {
+ return "block_bio_backmerge"; //$NON-NLS-1$
+ }
+
+ /**
+ * 2 requests previously inserted in the waiting queue are being merged
+ *
+ * @return The name of the event
+ */
+ default String eventBlockRqMerge() {
+ return "block_rq_merge"; //$NON-NLS-1$
+ }
+
+ /**
+ * Optional event used by some tracers to associate the name of the block
+ * device to a device ID
+ *
+ * @return The name of the event
+ */
+ default @Nullable String eventStatedumpBlockDevice() {
+ return null;
+ }
+
+ /**
+ * The field containing the device ID
+ *
+ * @return The name of the field
+ */
+ default String fieldBlockDeviceId() {
+ return "dev"; //$NON-NLS-1$
+ }
+
+ /**
+ * The field with the first sector of a block operation
+ *
+ * @return The name of the field
+ */
+ default String fieldBlockSector() {
+ return "sector"; //$NON-NLS-1$
+ }
+
+ /**
+ * The field with the number of sectors involved in a block operation
+ *
+ * @return The name of the field
+ */
+ default String fieldBlockNrSector() {
+ return "nr_sector"; //$NON-NLS-1$
+ }
+
+ /**
+ * The field containing the read/write flag of a block operation
+ *
+ * @return The name of the field
+ */
+ default String fieldBlockRwbs() {
+ return "rwbs"; //$NON-NLS-1$
+ }
+
+ /**
+ * The field with the first sector of a request in which another block
+ * operation is being merged
+ *
+ * @return The name of the field
+ */
+ default String fieldBlockRqSector() {
+ return "rq_sector"; //$NON-NLS-1$
+ }
+
+ /**
+ * The field with the sector of the request being merged in another one
+ *
+ * @return The name of the field
+ */
+ default String fieldBlockNextRqSector() {
+ return "nextrq_sector"; //$NON-NLS-1$
+ }
+
+ /**
+ * The field containing the name of the disk
+ *
+ * @return The name of the field
+ */
+ default String fieldDiskname() {
+ return "diskname"; //$NON-NLS-1$
+ }
+
+ /**
+ * The field with the IRQ number. This is used in IPI handlers (entry and
+ * exit).
+ *
+ * @return the name of the field with the IRQ number
+ */
+ default String fieldIPIVector() {
+ return "vector"; //$NON-NLS-1$
+ }
+
+
+ /**
+ * Get the name of the 'order' field from memory page allocation events.
+ *
+ * The 'order' of a page allocation is it's logarithm to the base 2, and the
+ * size of the allocation is 2^order, an integral power-of-2 number of
+ * pages. 'Order' ranges from from 0 to MAX_ORDER-1.
+ *
+ * The smallest - and most frequent - page allocation is 2^0 or 1 page. The
+ * maximum allocation possible is 2^(MAX_ORDER-1) pages. MAX_ORDER is
+ * assigned a default value of 11 - resulting in a maximum allocation of
+ * 2^10 or 1024 pages. However it may be redefined at kernel configuration
+ * time with the option CONFIG_FORCE_MAX_ZONEORDER.
+ *
+ * @return the name of the order field
+ */
+ default @Nullable String fieldOrder() {
+ return null;
+ }
+
+ // ------------------------------------------------------------------------
+ // Network events and fields
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get the list of events indicating that a packet is sent on the network
+ *
+ * @return The name of the packet send event
+ */
+ default Collection<String> eventsNetworkSend() {
+ return Collections.EMPTY_SET;
+ }
+
+ /**
+ * Get the list of events indicating that a packet is received from the
+ * network
+ *
+ * @return The collection of names of the packet receive event
+ */
+ default Collection<String> eventsNetworkReceive() {
+ return Collections.EMPTY_SET;
+ }
+
+ /**
+ * The path of the field corresponding to the sequence number field of a TCP
+ * header
+ *
+ * @return The path of the sequence number field in the TCP header of a
+ * network packet
+ */
+ default String[] fieldPathTcpSeq() {
+ return new String[] { "seq" }; //$NON-NLS-1$
+ }
+
+ /**
+ * The path of the field corresponding to the acknowledgment number field of
+ * a TCP header
+ *
+ * @return The name of the acknowledgment number field in the TCP header of
+ * a network packet
+ */
+ default String[] fieldPathTcpAckSeq() {
+ return new String[] { "ack_seq" }; //$NON-NLS-1$
+ }
+
+ /**
+ * The path of the field corresponding to the flags field of a TCP header
+ *
+ * @return The path of the flags field in the TCP header of a network packet
+ */
+ default String[] fieldPathTcpFlags() {
+ return new String[] { "flags" }; //$NON-NLS-1$
+ }
+
+ // ------------------------------------------------------------------------
+ // VirtualMachine events : kvm entry/exit events
+ // ------------------------------------------------------------------------
+
+ /**
+ * KVM kernel event indicating that virtual machine code is being run
+ *
+ * @return The name of the kvm entry event
+ */
+ default Collection<String> eventsKVMEntry() {
+ return Collections.EMPTY_SET;
+ }
+
+ /**
+ * KVM kernel event indicating that virtual machine code is not run anymore,
+ * but rather hypervisor-specific code
+ *
+ * @return The name of the kvm exit event
+ */
+ default Collection<String> eventsKVMExit() {
+ return Collections.EMPTY_SET;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ ******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.trace.layout.internal;
+
+/**
+ * This file defines all the known event and field names for LTTng kernel
+ * traces, for versions of lttng-modules 2.6 and above.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class Lttng26EventLayout extends LttngEventLayout {
+
+ /**
+ * Constructor
+ */
+ protected Lttng26EventLayout() {}
+
+ private static final Lttng26EventLayout INSTANCE = new Lttng26EventLayout();
+
+ public static Lttng26EventLayout getInstance() {
+ return INSTANCE;
+ }
+
+ // ------------------------------------------------------------------------
+ // New event names in these versions
+ // ------------------------------------------------------------------------
+
+ @Override
+ public String eventSyscallEntryPrefix() {
+ return "syscall_entry_"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventCompatSyscallEntryPrefix() {
+ return "compat_syscall_entry_"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSyscallExitPrefix() {
+ return "syscall_exit_"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventCompatSyscallExitPrefix() {
+ return "compat_syscall_exit_"; //$NON-NLS-1$
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson, École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sebastien Lorrain - Initial API and implementation
+ ******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.trace.layout.internal;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.eclipse.jdt.annotation.NonNull;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This file defines all the known event and field names for LTTng kernel
+ * traces, for versions of lttng-modules 2.7 and above.
+ *
+ * @author Sebastien Lorrain
+ */
+@SuppressWarnings("javadoc")
+public class Lttng27EventLayout extends Lttng26EventLayout {
+
+ private static final String X86_IRQ_VECTORS_LOCAL_TIMER_ENTRY = "x86_irq_vectors_local_timer_entry"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_LOCAL_TIMER_EXIT = "x86_irq_vectors_local_timer_exit"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_RESCHEDULE_ENTRY = "x86_irq_vectors_reschedule_entry"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_RESCHEDULE_EXIT = "x86_irq_vectors_reschedule_exit"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_SPURIOUS_ENTRY = "x86_irq_vectors_spurious_apic_entry"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_SPURIOUS_EXIT = "x86_irq_vectors_spurious_apic_exit"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_ERROR_APIC_ENTRY = "x86_irq_vectors_error_apic_entry"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_ERROR_APIC_EXIT = "x86_irq_vectors_error_apic_exit"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_IPI_ENTRY = "x86_irq_vectors_ipi_entry"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_IPI_EXIT = "x86_irq_vectors_ipi_exit"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_IRQ_WORK_ENTRY = "x86_irq_vectors_irq_work_entry"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_IRQ_WORK_EXIT = "x86_irq_vectors_irq_work_exit"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_CALL_FUNCTION_ENTRY = "x86_irq_vectors_call_function_entry"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_CALL_FUNCTION_EXIT = "x86_irq_vectors_call_function_exit"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_CALL_FUNCTION_SINGLE_ENTRY = "x86_irq_vectors_call_function_single_entry"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_CALL_FUNCTION_SINGLE_EXIT = "x86_irq_vectors_call_function_single_exit"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_THRESHOLD_APIC_ENTRY = "x86_irq_vectors_threshold_apic_entry"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_THRESHOLD_APIC_EXIT = "x86_irq_vectors_threshold_apic_exit"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_DEFERRED_ERROR_APIC_ENTRY = "x86_irq_vectors_deferred_error_apic_entry"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_DEFERRED_ERROR_APIC_EXIT = "x86_irq_vectors_deferred_error_apic_exit"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_THERMAL_APIC_ENTRY = "x86_irq_vectors_thermal_apic_entry"; //$NON-NLS-1$
+ private static final String X86_IRQ_VECTORS_THERMAL_APIC_EXIT = "x86_irq_vectors_thermal_apic_exit"; //$NON-NLS-1$
+ /* Network event */
+ private static final Collection<String> EVENTS_NETWORK_RECEIVE = Collections.singleton("net_if_receive_skb"); //$NON-NLS-1$
+ /* KVM events */
+ private static final Collection<String> KVM_ENTRY_EVENTS = Collections.singleton("kvm_x86_entry"); //$NON-NLS-1$
+ private static final Collection<String> KVM_EXIT_EVENTS = Collections.singleton("kvm_x86_exit"); //$NON-NLS-1$
+
+ private static final Collection<String> IPI_ENTRY_SET = ImmutableSet.of(
+ X86_IRQ_VECTORS_LOCAL_TIMER_ENTRY,
+ X86_IRQ_VECTORS_RESCHEDULE_ENTRY,
+ X86_IRQ_VECTORS_SPURIOUS_ENTRY,
+ X86_IRQ_VECTORS_ERROR_APIC_ENTRY,
+ X86_IRQ_VECTORS_IPI_ENTRY,
+ X86_IRQ_VECTORS_IRQ_WORK_ENTRY,
+ X86_IRQ_VECTORS_CALL_FUNCTION_ENTRY,
+ X86_IRQ_VECTORS_CALL_FUNCTION_SINGLE_ENTRY,
+ X86_IRQ_VECTORS_THRESHOLD_APIC_ENTRY,
+ X86_IRQ_VECTORS_DEFERRED_ERROR_APIC_ENTRY,
+ X86_IRQ_VECTORS_THERMAL_APIC_ENTRY);
+
+ private static final Collection<String> IPI_EXIT_SET = ImmutableSet.of(
+ X86_IRQ_VECTORS_LOCAL_TIMER_EXIT,
+ X86_IRQ_VECTORS_RESCHEDULE_EXIT,
+ X86_IRQ_VECTORS_SPURIOUS_EXIT,
+ X86_IRQ_VECTORS_ERROR_APIC_EXIT,
+ X86_IRQ_VECTORS_IPI_EXIT,
+ X86_IRQ_VECTORS_IRQ_WORK_EXIT,
+ X86_IRQ_VECTORS_CALL_FUNCTION_EXIT,
+ X86_IRQ_VECTORS_CALL_FUNCTION_SINGLE_EXIT,
+ X86_IRQ_VECTORS_THRESHOLD_APIC_EXIT,
+ X86_IRQ_VECTORS_DEFERRED_ERROR_APIC_EXIT,
+ X86_IRQ_VECTORS_THERMAL_APIC_EXIT);
+
+ /**
+ * Constructor
+ */
+ protected Lttng27EventLayout() {}
+
+ private static final Lttng27EventLayout INSTANCE = new Lttng27EventLayout();
+
+ public static Lttng27EventLayout getInstance() {
+ return INSTANCE;
+ }
+
+ // ------------------------------------------------------------------------
+ // New event definition in LTTng 2.7
+ // ------------------------------------------------------------------------
+
+ @Override
+ public String eventHRTimerStart() {
+ return "timer_hrtimer_start"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventHRTimerCancel() {
+ return "timer_hrtimer_cancel"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventHRTimerExpireEntry() {
+ return "timer_hrtimer_expire_entry"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventHRTimerExpireExit() {
+ return "timer_hrtimer_expire_exit"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSoftIrqRaise() {
+ return "irq_softirq_raise"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSoftIrqEntry() {
+ return "irq_softirq_entry"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSoftIrqExit() {
+ return "irq_softirq_exit"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventKmemPageAlloc() {
+ return "kmem_mm_page_alloc"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventKmemPageFree() {
+ return "kmem_mm_page_free"; //$NON-NLS-1$
+ }
+
+ public String x86IrqVectorsLocalTimerEntry() {
+ return X86_IRQ_VECTORS_LOCAL_TIMER_ENTRY;
+ }
+
+ public String x86IrqVectorsLocalTimerExit() {
+ return X86_IRQ_VECTORS_LOCAL_TIMER_EXIT;
+ }
+
+ public String x86IrqVectorsRescheduleEntry() {
+ return X86_IRQ_VECTORS_RESCHEDULE_ENTRY;
+ }
+
+ public String x86IrqVectorsRescheduleExit() {
+ return X86_IRQ_VECTORS_RESCHEDULE_EXIT;
+ }
+
+ public String x86IrqVectorsSpuriousApicEntry() {
+ return X86_IRQ_VECTORS_SPURIOUS_ENTRY;
+ }
+
+ public String x86IrqVectorsSpuriousApicExit() {
+ return X86_IRQ_VECTORS_SPURIOUS_EXIT;
+ }
+
+ public String x86IrqVectorsErrorApicEntry() {
+ return X86_IRQ_VECTORS_ERROR_APIC_ENTRY;
+ }
+
+ public String x86IrqVectorsErrorApicExit() {
+ return X86_IRQ_VECTORS_ERROR_APIC_EXIT;
+ }
+
+ public String x86IrqVectorsIpiEntry() {
+ return X86_IRQ_VECTORS_IPI_ENTRY;
+ }
+
+ public String x86IrqVectorsIpiExit() {
+ return X86_IRQ_VECTORS_IPI_EXIT;
+ }
+
+ public String x86IrqVectorsIrqWorkEntry() {
+ return X86_IRQ_VECTORS_IRQ_WORK_ENTRY;
+ }
+
+ public String x86IrqVectorsIrqWorkExit() {
+ return X86_IRQ_VECTORS_IRQ_WORK_EXIT;
+ }
+
+ public String x86IrqVectorsCallFunctionEntry() {
+ return X86_IRQ_VECTORS_CALL_FUNCTION_ENTRY;
+ }
+
+ public String x86IrqVectorsCallFunctionExit() {
+ return X86_IRQ_VECTORS_CALL_FUNCTION_EXIT;
+ }
+
+ public String x86IrqVectorsCallFunctionSingleEntry() {
+ return X86_IRQ_VECTORS_CALL_FUNCTION_SINGLE_ENTRY;
+ }
+
+ public String x86IrqVectorsCallFunctionSingleExit() {
+ return X86_IRQ_VECTORS_CALL_FUNCTION_SINGLE_EXIT;
+ }
+
+ public String x86IrqVectorsThresholdApicEntry() {
+ return X86_IRQ_VECTORS_THRESHOLD_APIC_ENTRY;
+ }
+
+ public String x86IrqVectorsThresholdApicExit() {
+ return X86_IRQ_VECTORS_THRESHOLD_APIC_EXIT;
+ }
+
+ public String x86IrqVectorsDeferredErrorApicEntry() {
+ return X86_IRQ_VECTORS_DEFERRED_ERROR_APIC_ENTRY;
+ }
+
+ public String x86IrqVectorsDeferredErrorApicExit() {
+ return X86_IRQ_VECTORS_DEFERRED_ERROR_APIC_EXIT;
+ }
+
+ public String x86IrqVectorsThermalApicEntry() {
+ return X86_IRQ_VECTORS_THERMAL_APIC_ENTRY;
+ }
+
+ public String x86IrqVectorsThermalApicExit() {
+ return X86_IRQ_VECTORS_THERMAL_APIC_EXIT;
+ }
+
+ @Override
+ public @NonNull Collection<@NonNull String> eventsKVMEntry() {
+ return KVM_ENTRY_EVENTS;
+ }
+
+ @Override
+ public @NonNull Collection<@NonNull String> eventsKVMExit() {
+ return KVM_EXIT_EVENTS;
+ }
+
+ @Override
+ public @NonNull Collection<@NonNull String> getIPIIrqVectorsEntries() {
+ return IPI_ENTRY_SET;
+ }
+
+ @Override
+ public @NonNull Collection<@NonNull String> getIPIIrqVectorsExits() {
+ return IPI_EXIT_SET;
+ }
+
+ // ------------------------------------------------------------------------
+ // New field definitions in LTTng 2.7
+ // ------------------------------------------------------------------------
+
+ public String fieldParentNSInum() {
+ return "parent_ns_inum"; //$NON-NLS-1$
+ }
+
+ public String fieldChildNSInum() {
+ return "child_ns_inum"; //$NON-NLS-1$
+ }
+
+ public String fieldChildVTids() {
+ return "vtids"; //$NON-NLS-1$
+ }
+
+ public String fieldNSInum() {
+ return "ns_inum"; //$NON-NLS-1$
+ }
+
+ public String fieldVTid() {
+ return "vtid"; //$NON-NLS-1$
+ }
+
+ public String fieldPPid() {
+ return "ppid"; //$NON-NLS-1$
+ }
+
+ public String fieldNSLevel() {
+ return "ns_level"; //$NON-NLS-1$
+ }
+
+ @Override
+ public Collection<String> eventsNetworkReceive() {
+ return EVENTS_NETWORK_RECEIVE;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson, École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ ******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.trace.layout.internal;
+
+/**
+ * This file defines all the known event and field names for LTTng kernel
+ * traces, for versions of lttng-modules 2.8 and above.
+ *
+ * @author Francis Giraldeau
+ */
+public class Lttng28EventLayout extends Lttng27EventLayout {
+
+ /**
+ * Constructor
+ */
+ protected Lttng28EventLayout() {
+ }
+
+ private static final Lttng28EventLayout INSTANCE = new Lttng28EventLayout();
+
+ public static Lttng28EventLayout getInstance() {
+ return INSTANCE;
+ }
+
+ // ------------------------------------------------------------------------
+ // New definitions in LTTng 2.8
+ // ------------------------------------------------------------------------
+
+ @Override
+ public String eventSchedProcessWaking() {
+ return "sched_waking"; //$NON-NLS-1$
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.trace.layout.internal;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.ctf.tmf.core.event.CtfTmfEventField;
+
+/**
+ * This file defines all the known event and field names for LTTng kernel
+ * traces, for versions of lttng-modules 2.9 and above.
+ *
+ * @author Geneviève Bastien
+ */
+public class Lttng29EventLayout extends Lttng28EventLayout {
+
+ private static final String[] TCP_SEQ_FIELD = { "network_header", CtfTmfEventField.FIELD_VARIANT_SELECTED, "transport_header", "tcp", "seq" }; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ private static final String[] TCP_ACK_FIELD = { "network_header", CtfTmfEventField.FIELD_VARIANT_SELECTED, "transport_header", "tcp", "ack_seq" }; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ private static final String[] TCP_FLAGS_FIELD = { "network_header", CtfTmfEventField.FIELD_VARIANT_SELECTED, "transport_header", "tcp", "flags" }; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+ /**
+ * Constructor
+ */
+ protected Lttng29EventLayout() {
+ }
+
+ private static final Lttng29EventLayout INSTANCE = new Lttng29EventLayout();
+
+ public static Lttng29EventLayout getInstance() {
+ return INSTANCE;
+ }
+
+ @Override
+ public String @NonNull [] fieldPathTcpSeq() {
+ return TCP_SEQ_FIELD;
+ }
+
+ @Override
+ public String @NonNull [] fieldPathTcpAckSeq() {
+ return TCP_ACK_FIELD;
+ }
+
+ @Override
+ public String @NonNull [] fieldPathTcpFlags() {
+ return TCP_FLAGS_FIELD;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ ******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.trace.layout.internal;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * This file defines all the known event and field names for LTTng kernel
+ * traces, for versions of lttng-modules up to 2.5.
+ *
+ * These should not be externalized, since they need to match exactly what the
+ * tracer outputs. If you want to localize them in a view, you should do a
+ * mapping in the view itself.
+ *
+ * @author Alexandre Montplaisir
+ */
+@SuppressWarnings("nls")
+public class LttngEventLayout implements ILttngKernelEventLayout {
+
+ /* Event names */
+ private static final String IRQ_HANDLER_ENTRY = "irq_handler_entry";
+ private static final String IRQ_HANDLER_EXIT = "irq_handler_exit";
+ private static final String SOFTIRQ_ENTRY = "softirq_entry";
+ private static final String SOFTIRQ_EXIT = "softirq_exit";
+ private static final String SOFTIRQ_RAISE = "softirq_raise";
+ private static final String HRTIMER_START = "hrtimer_start";
+ private static final String HRTIMER_CANCEL = "hrtimer_cancel";
+ private static final String HRTIMER_EXPIRE_ENTRY = "hrtimer_expire_entry";
+ private static final String HRTIMER_EXPIRE_EXIT = "hrtimer_expire_exit";
+ private static final String SCHED_SWITCH = "sched_switch";
+ private static final String SCHED_PI_SETPRIO = "sched_pi_setprio";
+
+ private static final String SCHED_TTWU = "sched_ttwu";
+ private static final String SCHED_WAKEUP = "sched_wakeup";
+ private static final String SCHED_WAKEUP_NEW = "sched_wakeup_new";
+ private static final Collection<String> SCHED_WAKEUP_EVENTS =
+ ImmutableList.of(SCHED_WAKEUP, SCHED_WAKEUP_NEW);
+
+ private static final String SCHED_PROCESS_FORK = "sched_process_fork";
+ private static final String SCHED_PROCESS_EXIT = "sched_process_exit";
+ private static final String SCHED_PROCESS_FREE = "sched_process_free";
+ private static final String SCHED_PROCESS_EXEC = "sched_process_exec";
+ private static final String STATEDUMP_PROCESS_STATE = "lttng_statedump_process_state";
+
+ private static final String SYSCALL_ENTRY_PREFIX = "sys_";
+ private static final String COMPAT_SYSCALL_ENTRY_PREFIX = "compat_sys_";
+ private static final String SYSCALL_EXIT_PREFIX = "exit_syscall";
+
+ private static final String BLOCK_RQ_INSERT= "block_rq_insert";
+ private static final String BLOCK_RQ_ISSUE= "block_rq_issue";
+ private static final String ELV_MERGE_REQUESTS= "addons_elv_merge_requests";
+ private static final String BLOCK_RQ_COMPLETE= "block_rq_complete";
+ private static final String LTTNG_STATEDUMP_BLOCK_DEVICE= "lttng_statedump_block_device";
+ private static final String BLOCK_BIO_FRONTMERGE = "block_bio_frontmerge";
+ private static final String BLOCK_BIO_BACKMERGE = "block_bio_backmerge";
+
+ /* Field names */
+ private static final String IRQ = "irq";
+ private static final String TID = "tid";
+ private static final String VEC = "vec";
+ private static final String PREV_TID = "prev_tid";
+ private static final String PREV_STATE = "prev_state";
+ private static final String NEXT_COMM = "next_comm";
+ private static final String NEXT_TID = "next_tid";
+ private static final String PARENT_TID = "parent_tid";
+ private static final String CHILD_COMM = "child_comm";
+ private static final String CHILD_TID = "child_tid";
+ private static final String PRIO = "prio";
+ private static final String PREV_PRIO = "prev_prio";
+ private static final String NEXT_PRIO = "next_prio";
+ private static final String NEW_PRIO = "newprio";
+ private static final String COMM = "comm";
+ private static final String NAME = "name";
+ private static final String STATUS = "status";
+ private static final String PREV_COMM = "prev_comm";
+ private static final String FILENAME = "filename";
+ private static final String HRTIMER = "hrtimer";
+ private static final String HRTIMER_FUNCTION = "function";
+ private static final String HRTIMER_EXPIRES = "expires";
+ private static final String HRTIMER_NOW = "now";
+ private static final String HRTIMER_SOFT_EXPIRES = "softexpires";
+ private static final String KMEM_ALLOC = "mm_page_alloc";
+ private static final String KMEM_FREE = "mm_page_free";
+ private static final String SYSCALL_RET = "ret";
+ private static final String RWBS="rwbs";
+ private static final String DISKNAME="diskname";
+ private static final String BLOCK_DEV="dev";
+ private static final String SECTOR="sector";
+ private static final String NR_SECTOR="nr_sector";
+ private static final String RQ_SECTOR= "rq_sector";
+ private static final String NEXTRQ_SECTOR= "nextrq_sector";
+ private static final String ORDER = "order";
+
+ /* Network events and field names */
+ private static final Collection<String> EVENTS_NETWORK_SEND = Collections.singleton("net_dev_queue");
+ private static final Collection<String> EVENTS_NETWORK_RECEIVE = Collections.singleton("netif_receive_skb");
+ private static final String[] TCP_SEQ_FIELD = { "transport_fields", "thtype_tcp", "seq" };
+ private static final String[] TCP_ACK_FIELD = { "transport_fields", "thtype_tcp", "ack_seq" };
+ private static final String[] TCP_FLAGS_FIELD = { "transport_fields", "thtype_tcp", "flags" };
+
+ /* KVM events */
+ private static final Collection<String> KVM_ENTRY_EVENTS = Collections.singleton("kvm_entry");
+ private static final Collection<String> KVM_EXIT_EVENTS = Collections.singleton("kvm_exit");
+
+ /** All instances are the same. Only provide a static instance getter */
+ protected LttngEventLayout() {
+ }
+
+ private static final ILttngKernelEventLayout INSTANCE = new LttngEventLayout();
+
+ /**
+ * Get an instance of this event layout
+ *
+ * This object is completely immutable, so no need to create additional
+ * instances via the constructor.
+ *
+ * @return The instance
+ */
+ public static ILttngKernelEventLayout getInstance() {
+ return INSTANCE;
+ }
+
+ // ------------------------------------------------------------------------
+ // Event names
+ // ------------------------------------------------------------------------
+
+ @Override
+ public String eventIrqHandlerEntry() {
+ return IRQ_HANDLER_ENTRY;
+ }
+
+ @Override
+ public String eventIrqHandlerExit() {
+ return IRQ_HANDLER_EXIT;
+ }
+
+ @Override
+ public String eventSoftIrqEntry() {
+ return SOFTIRQ_ENTRY;
+ }
+
+ @Override
+ public String eventSoftIrqExit() {
+ return SOFTIRQ_EXIT;
+ }
+
+ @Override
+ public String eventSoftIrqRaise() {
+ return SOFTIRQ_RAISE;
+ }
+
+ @Override
+ public String eventSchedSwitch() {
+ return SCHED_SWITCH;
+ }
+
+ @Override
+ public String eventSchedPiSetprio() {
+ return SCHED_PI_SETPRIO;
+ }
+
+ @Override
+ public Collection<String> eventsSchedWakeup() {
+ return SCHED_WAKEUP_EVENTS;
+ }
+
+ @Override
+ public String eventSchedProcessFork() {
+ return SCHED_PROCESS_FORK;
+ }
+
+ @Override
+ public String eventSchedProcessExit() {
+ return SCHED_PROCESS_EXIT;
+ }
+
+ @Override
+ public String eventSchedProcessFree() {
+ return SCHED_PROCESS_FREE;
+ }
+
+ @Override
+ public @NonNull String eventStatedumpProcessState() {
+ return STATEDUMP_PROCESS_STATE;
+ }
+
+ @Override
+ public String eventSyscallEntryPrefix() {
+ return SYSCALL_ENTRY_PREFIX;
+ }
+
+ @Override
+ public String eventCompatSyscallEntryPrefix() {
+ return COMPAT_SYSCALL_ENTRY_PREFIX;
+ }
+
+ @Override
+ public String eventSyscallExitPrefix() {
+ return SYSCALL_EXIT_PREFIX;
+ }
+
+ @Override
+ public String eventCompatSyscallExitPrefix() {
+ /*
+ * In LTTng < 2.6, the same generic event name is used for both standard
+ * and compat syscalls.
+ */
+ return SYSCALL_EXIT_PREFIX;
+ }
+
+ @Override
+ public String eventKmemPageAlloc() {
+ return KMEM_ALLOC;
+ }
+
+ @Override
+ public String eventKmemPageFree() {
+ return KMEM_FREE;
+ }
+
+ // ------------------------------------------------------------------------
+ // Event field names
+ // ------------------------------------------------------------------------
+
+ @Override
+ public String fieldIrq() {
+ return IRQ;
+ }
+
+ @Override
+ public String fieldVec() {
+ return VEC;
+ }
+
+ @Override
+ public String fieldTid() {
+ return TID;
+ }
+
+ @Override
+ public String fieldPrevTid() {
+ return PREV_TID;
+ }
+
+ @Override
+ public String fieldPrevState() {
+ return PREV_STATE;
+ }
+
+ @Override
+ public String fieldNextComm() {
+ return NEXT_COMM;
+ }
+
+ @Override
+ public String fieldNextTid() {
+ return NEXT_TID;
+ }
+
+ @Override
+ public String fieldChildComm() {
+ return CHILD_COMM;
+ }
+
+ @Override
+ public String fieldParentTid() {
+ return PARENT_TID;
+ }
+
+ @Override
+ public String fieldChildTid() {
+ return CHILD_TID;
+ }
+
+ @Override
+ public String fieldPrio() {
+ return PRIO;
+ }
+
+ @Override
+ public String fieldNewPrio() {
+ return NEW_PRIO;
+ }
+
+ @Override
+ public String fieldPrevPrio() {
+ return PREV_PRIO;
+ }
+
+ @Override
+ public String fieldNextPrio() {
+ return NEXT_PRIO;
+ }
+
+ @Override
+ public String fieldComm() {
+ return COMM;
+ }
+
+ @Override
+ public String fieldName() {
+ return NAME;
+ }
+
+ @Override
+ public String fieldStatus() {
+ return STATUS;
+ }
+
+ @Override
+ public String fieldPrevComm() {
+ return PREV_COMM;
+ }
+
+ @Override
+ public String fieldFilename() {
+ return FILENAME;
+ }
+
+ @Override
+ public String eventSchedProcessExec() {
+ return SCHED_PROCESS_EXEC;
+ }
+
+ @Override
+ public String eventSchedProcessWakeup() {
+ return SCHED_WAKEUP;
+ }
+
+ @Override
+ public String eventSchedProcessWakeupNew() {
+ return SCHED_WAKEUP_NEW;
+ }
+
+ @Override
+ public String eventSchedMigrateTask() {
+ return "sched_migrate_task"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventHRTimerStart() {
+ return HRTIMER_START;
+ }
+
+ @Override
+ public String eventHRTimerCancel() {
+ return HRTIMER_CANCEL;
+ }
+
+ @Override
+ public String eventHRTimerExpireEntry() {
+ return HRTIMER_EXPIRE_ENTRY;
+ }
+
+ @Override
+ public String eventHRTimerExpireExit() {
+ return HRTIMER_EXPIRE_EXIT;
+ }
+
+ /**
+ * Event indicating the source of the wakeup signal.
+ *
+ * @return The name of the event
+ */
+ public String eventSchedProcessTTWU() {
+ return SCHED_TTWU;
+ }
+
+ @Override
+ public String fieldHRtimer() {
+ return HRTIMER;
+ }
+ @Override
+ public String fieldHRtimerFunction() {
+ return HRTIMER_FUNCTION;
+ }
+
+ @Override
+ public String fieldHRtimerExpires() {
+ return HRTIMER_EXPIRES;
+ }
+
+ @Override
+ public String fieldHRtimerSoftexpires() {
+ return HRTIMER_SOFT_EXPIRES;
+ }
+ @Override
+ public String fieldHRtimerNow() {
+ return HRTIMER_NOW;
+ }
+
+ @Override
+ public String fieldSyscallRet() {
+ return SYSCALL_RET;
+ }
+
+ // ------------------------------------------------------------------------
+ // I/O events and fields
+ // ------------------------------------------------------------------------
+
+ @Override
+ public String eventBlockRqInsert() {
+ return BLOCK_RQ_INSERT;
+ }
+
+ @Override
+ public String eventBlockRqIssue() {
+ return BLOCK_RQ_ISSUE;
+ }
+
+ @Override
+ public String eventBlockRqComplete() {
+ return BLOCK_RQ_COMPLETE;
+ }
+
+ @Override
+ public String eventBlockBioFrontmerge() {
+ return BLOCK_BIO_FRONTMERGE;
+ }
+
+ @Override
+ public String eventBlockBioBackmerge() {
+ return BLOCK_BIO_BACKMERGE;
+ }
+
+ @Override
+ public String eventBlockRqMerge() {
+ return ELV_MERGE_REQUESTS;
+ }
+
+ @Override
+ public @NonNull String eventStatedumpBlockDevice() {
+ return LTTNG_STATEDUMP_BLOCK_DEVICE;
+ }
+
+ @Override
+ public String fieldBlockDeviceId() {
+ return BLOCK_DEV;
+ }
+
+ @Override
+ public String fieldBlockSector() {
+ return SECTOR;
+ }
+
+ @Override
+ public String fieldBlockNrSector() {
+ return NR_SECTOR;
+ }
+
+ @Override
+ public String fieldBlockRwbs() {
+ return RWBS;
+ }
+
+ @Override
+ public String fieldBlockRqSector() {
+ return RQ_SECTOR;
+ }
+
+ @Override
+ public String fieldBlockNextRqSector() {
+ return NEXTRQ_SECTOR;
+ }
+
+ @Override
+ public String fieldDiskname() {
+ return DISKNAME;
+ }
+
+ @Override
+ public Collection<String> eventsNetworkSend() {
+ return EVENTS_NETWORK_SEND;
+ }
+
+ @Override
+ public Collection<String> eventsNetworkReceive() {
+ return EVENTS_NETWORK_RECEIVE;
+ }
+
+ @Override
+ public String @NonNull [] fieldPathTcpSeq() {
+ return TCP_SEQ_FIELD;
+ }
+
+ @Override
+ public String @NonNull [] fieldPathTcpAckSeq() {
+ return TCP_ACK_FIELD;
+ }
+
+ @Override
+ public String @NonNull [] fieldPathTcpFlags() {
+ return TCP_FLAGS_FIELD;
+ }
+
+ @Override
+ public @NonNull String fieldOrder() {
+ return ORDER;
+ }
+
+ // ------------------------------------------------------------------------
+ // VirtualMachine events : kvm entry/exit events
+ // ------------------------------------------------------------------------
+
+ @Override
+ public @NonNull Collection<@NonNull String> eventsKVMEntry() {
+ return KVM_ENTRY_EVENTS;
+ }
+
+ @Override
+ public @NonNull Collection<@NonNull String> eventsKVMExit() {
+ return KVM_EXIT_EVENTS;
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ ******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.trace.layout.internal;
+
+import java.util.Collection;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Event and field definitions for perf traces in CTF format.
+ *
+ * @author Alexandre Montplaisir
+ */
+public final class PerfEventLayout implements ILttngKernelEventLayout {
+
+ private PerfEventLayout() {
+ }
+
+ private static final PerfEventLayout INSTANCE = new PerfEventLayout();
+
+ /**
+ * Get the singleton instance of this event layout object.
+ *
+ * @return The instance
+ */
+ public static PerfEventLayout getInstance() {
+ return INSTANCE;
+ }
+
+ // ------------------------------------------------------------------------
+ // Event names
+ // ------------------------------------------------------------------------
+
+ @Override
+ public String eventIrqHandlerEntry() {
+ return "irq:irq_handler_entry"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventIrqHandlerExit() {
+ return "irq:irq_handler_exit"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSoftIrqEntry() {
+ return "irq:softirq_entry"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSoftIrqExit() {
+ return "irq:softirq_exit"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSoftIrqRaise() {
+ return "irq:softirq_raise"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSchedSwitch() {
+ return "sched:sched_switch"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSchedPiSetprio() {
+ return "sched:sched_pi_setprio"; //$NON-NLS-1$
+ }
+
+ private static final Collection<String> WAKEUP_EVENTS = ImmutableList.of("sched:sched_wakeup", "sched:sched_wakeup_new"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ @Override
+ public Collection<String> eventsSchedWakeup() {
+ return WAKEUP_EVENTS;
+ }
+
+ @Override
+ public String eventSchedProcessFork() {
+ return "sched:sched_process_fork"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSchedProcessExit() {
+ return "sched:sched_process_exit"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSchedProcessFree() {
+ return "sched:sched_process_free"; //$NON-NLS-1$
+ }
+
+ @Override
+ public @Nullable String eventStatedumpProcessState() {
+ /* Not present in perf traces */
+ return null;
+ }
+
+ @Override
+ public String eventSyscallEntryPrefix() {
+ return "raw_syscalls:sys_enter"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventCompatSyscallEntryPrefix() {
+ return eventSyscallEntryPrefix();
+ }
+
+ @Override
+ public String eventSyscallExitPrefix() {
+ return "raw_syscalls:sys_exit"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventCompatSyscallExitPrefix() {
+ return eventSyscallExitPrefix();
+ }
+
+ @Override
+ public String eventSchedProcessExec() {
+ return "sched:sched_process_exec"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSchedProcessWakeup() {
+ return "sched:sched_process_wakeup"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSchedProcessWakeupNew() {
+ return "sched:process_wakeup_new"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSchedProcessWaking() {
+ return "sched:sched_waking"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventSchedMigrateTask() {
+ return "sched:sched_migrate_task"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventHRTimerStart() {
+ return "timer:hrtimer_start"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventHRTimerCancel() {
+ return "timer:hrtimer_cancel"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventHRTimerExpireEntry() {
+ return "timer:hrtimer_expire_entry"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventHRTimerExpireExit() {
+ return "timer:hrtimer_expire_exit"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventKmemPageAlloc() {
+ return "kmem:page_alloc"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventKmemPageFree() {
+ return "kmem:page_free"; //$NON-NLS-1$
+ }
+
+ // ------------------------------------------------------------------------
+ // Field names
+ // ------------------------------------------------------------------------
+
+ @Override
+ public String fieldIrq() {
+ return "irq"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldVec() {
+ return "vec"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldTid() {
+ return "pid"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldPrevTid() {
+ return "prev_pid"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldPrevState() {
+ return "prev_state"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldNextComm() {
+ return "next_comm"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldNextTid() {
+ return "next_pid"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldChildComm() {
+ return "child_comm"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldParentTid() {
+ return "parent_pid"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldChildTid() {
+ return "child_pid"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldPrio() {
+ return "prio"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldNewPrio() {
+ return "newprio"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldPrevPrio() {
+ return "prev_prio"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldNextPrio() {
+ return "next_prio"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldComm() {
+ return "comm"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldName() {
+ return "name"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldStatus() {
+ return "status"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldPrevComm() {
+ return "prev_comm"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldFilename() {
+ return "filename"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldHRtimer() {
+ return "hrtimer"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldHRtimerFunction() {
+ return "function"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldHRtimerExpires() {
+ return "expires"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldHRtimerSoftexpires() {
+ return "softexpires"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String fieldHRtimerNow() {
+ return "now"; //$NON-NLS-1$
+ }
+
+ @Override
+ public @NonNull String fieldOrder() {
+ return "order"; //$NON-NLS-1$
+ }
+
+ // ------------------------------------------------------------------------
+ // I/O events and fields
+ // ------------------------------------------------------------------------
+
+ @Override
+ public String eventBlockRqInsert() {
+ return "block:block_rq_insert"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventBlockRqIssue() {
+ return "block:block_rq_issue"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventBlockRqComplete() {
+ return "block:block_rq_complete"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventBlockBioFrontmerge() {
+ return "block:block_bio_frontmerge"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String eventBlockBioBackmerge() {
+ return "block:block_bio_backmerge"; //$NON-NLS-1$
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ericsson - Initial API and implementation
+ *******************************************************************************/
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.lttng.scope.lttng.kernel.core.trace.layout.internal;
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.lttng.scope.lttng.kernel.core.trace.layout;
--- /dev/null
+###############################################################################
+# Copyright (c) 2013, 2014 Ericsson
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Ericsson - Initial API and implementation
+###############################################################################
+
+LttngKernelTrace_DomainError=Domain mismatch, the environment should be 'kernel'.
+LttngKernelTrace_MalformedTrace=Buffer overflow exception, trace is malformed
+LttngKernelTrace_TraceReadError=Lttng trace read error
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph;
+
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.ColorDefinition;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.FlatUIColors;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.LineThickness;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.StateDefinition;
+
+/**
+ * State definitions used in the views of the kernel analysis.
+ *
+ * @author Alexandre Montplaisir
+ */
+@SuppressWarnings("javadoc")
+public final class KernelAnalysisStateDefinitions {
+
+ private KernelAnalysisStateDefinitions() {}
+
+ public static final StateDefinition NO_STATE = new StateDefinition(Messages.noState, new ColorDefinition(0, 0, 0, 0), LineThickness.NORMAL);
+
+ public static final StateDefinition THREAD_STATE_UNKNOWN = new StateDefinition(Messages.threadStateUnknown, FlatUIColors.DARK_GRAY, LineThickness.TINY);
+ public static final StateDefinition THREAD_STATE_WAIT_UNKNOWN = new StateDefinition(Messages.threadStateWaitUnknown, FlatUIColors.LIGHT_GRAY, LineThickness.TINY);
+ public static final StateDefinition THREAD_STATE_WAIT_BLOCKED = new StateDefinition(Messages.threadStateWaitBlocked, FlatUIColors.YELLOW, LineThickness.TINY);
+ public static final StateDefinition THREAD_STATE_WAIT_FOR_CPU = new StateDefinition(Messages.threadStateWaitForCpu, FlatUIColors.ORANGE, LineThickness.NORMAL);
+ public static final StateDefinition THREAD_STATE_USERMODE = new StateDefinition(Messages.threadSateUsermode, FlatUIColors.DARK_GREEN, LineThickness.NORMAL);
+ public static final StateDefinition THREAD_STATE_SYSCALL = new StateDefinition(Messages.threadStateSyscall, FlatUIColors.DARK_BLUE, LineThickness.NORMAL);
+ public static final StateDefinition THREAD_STATE_INTERRUPTED = new StateDefinition(Messages.threadStateInterrupted, FlatUIColors.PURPLE, LineThickness.NORMAL);
+
+ public static final StateDefinition CPU_STATE_UNKNOWN = new StateDefinition(Messages.cpuStateUnknown, FlatUIColors.DARK_GRAY, LineThickness.NORMAL);
+ public static final StateDefinition CPU_STATE_IDLE = new StateDefinition(Messages.cpuStateIdle, FlatUIColors.GRAY, LineThickness.TINY);
+ public static final StateDefinition CPU_STATE_IRQ_ACTIVE = new StateDefinition(Messages.cpuStateIrqActive, FlatUIColors.DARK_PURPLE, LineThickness.NORMAL);
+ public static final StateDefinition CPU_STATE_SOFTIRQ_ACTIVE = new StateDefinition(Messages.cpuStateSoftIrqActive, FlatUIColors.DARK_ORANGE, LineThickness.NORMAL);
+ public static final StateDefinition CPU_STATE_SOFTIRQ_RAISED = new StateDefinition(Messages.cpuStateSoftIrqRaised, FlatUIColors.DARK_YELLOW, LineThickness.NORMAL);
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Messages class
+ *
+ * @author Alexandre Montplaisir
+ * @noreference Message class
+ */
+@SuppressWarnings("javadoc")
+@NonNullByDefault({})
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+
+ public static String noState;
+
+ public static String threadStateUnknown;
+ public static String threadStateWaitUnknown;
+ public static String threadStateWaitBlocked;
+ public static String threadStateWaitForCpu;
+ public static String threadSateUsermode;
+ public static String threadStateSyscall;
+ public static String threadStateInterrupted;
+
+ public static String cpuStateUnknown;
+ public static String cpuStateIdle;
+ public static String cpuStateIrqActive;
+ public static String cpuStateSoftIrqActive;
+ public static String cpuStateSoftIrqRaised;
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
--- /dev/null
+###############################################################################
+# Copyright (c) 2017 EfficiOS Inc., Alexandre Montplaisir
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+noState = None
+
+threadStateUnknown = Unknown Thread State
+threadStateWaitUnknown = Wait Unknown
+threadStateWaitBlocked = Waiting Blocked
+threadStateWaitForCpu = Waiting For CPU
+threadSateUsermode = Running, usermode
+threadStateSyscall = Running, syscall
+threadStateInterrupted = Interrupted
+
+cpuStateUnknown = Unknown CPU State
+cpuStateIdle = Idle
+cpuStateIrqActive = Executing IRQ
+cpuStateSoftIrqActive = Executing Soft IRQ
+cpuStateSoftIrqRaised = Soft IRQ Raised
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.lttng.scope.lttng.kernel.core.views.timegraph;
--- /dev/null
+/*
+ * Copyright (C) 2016-2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph.resources;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Messages class
+ *
+ * @author Alexandre Montplaisir
+ * @noreference Message class
+ */
+@SuppressWarnings("javadoc")
+@NonNullByDefault({})
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+
+ public static String resourcesCpuIrqProviderName;
+ public static String resourcesIrqProviderName;
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph.resources;
+
+import java.util.Comparator;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import org.lttng.scope.lttng.kernel.core.analysis.os.KernelAnalysisModule;
+import org.lttng.scope.lttng.kernel.core.views.timegraph.resources.elements.ResourcesIrqTreeElement;
+import org.lttng.scope.lttng.kernel.core.views.timegraph.resources.elements.ResourcesIrqTreeElement.IrqType;
+import org.lttng.scope.tmf2.views.core.timegraph.model.provider.states.ITimeGraphModelStateProvider;
+import org.lttng.scope.tmf2.views.core.timegraph.model.provider.statesystem.StateSystemModelProvider;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeRender;
+
+/**
+ * Base class for Resources (for now, CPUs and IRQs) model providers.
+ *
+ * Implementations of this class can define the hierarchy the resources are to
+ * be presented in, for example CPUs/IRQs or IRQs/CPUs.
+ *
+ * @author Alexandre Montplaisir
+ */
+public abstract class ResourcesBaseModelProvider extends StateSystemModelProvider {
+
+ private static final Supplier<ITimeGraphModelStateProvider> STATE_PROVIDER = () -> {
+ return new ResourcesModelStateProvider();
+ };
+
+ /**
+ * Comparator to sort IRQ entries in the tree model.
+ *
+ * Shows (hardware) IRQs first, followed by Soft IRQs. Within each section they
+ * are sorted by numerical (not String!) value of their IRQ number.
+ */
+ protected static final Comparator<ResourcesIrqTreeElement> IRQ_SORTER = Comparator
+ .<ResourcesIrqTreeElement, IrqType> comparing(treeElem -> treeElem.getIrqType())
+ .thenComparingInt(treeElem -> treeElem.getIrqNumber());
+
+ /**
+ * Constructor
+ *
+ * @param providerName
+ * Name of this provider
+ * @param treeRenderFunction
+ * Function to generate a tree render from a given tree context
+ */
+ public ResourcesBaseModelProvider(String providerName, Function<TreeRenderContext, TimeGraphTreeRender> treeRenderFunction) {
+ super(providerName,
+ null,
+ null,
+ STATE_PROVIDER.get(),
+ null,
+ /* Parameters specific to state system render providers */
+ KernelAnalysisModule.ID,
+ treeRenderFunction);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph.resources;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.views.timegraph.resources.elements.ResourcesCpuTreeElement;
+import org.lttng.scope.lttng.kernel.core.views.timegraph.resources.elements.ResourcesIrqTreeElement;
+import org.lttng.scope.lttng.kernel.core.views.timegraph.resources.elements.ResourcesIrqTreeElement.IrqType;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeElement;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeRender;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.primitives.Ints;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystem;
+
+/**
+ * View model for a Resources view, showing CPUs as the first level, then
+ * per-cpu IRQs as the second level.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class ResourcesCpuIrqModelProvider extends ResourcesBaseModelProvider {
+
+ /**
+ * Each "CPU" attribute has the following children:
+ *
+ * <ul>
+ * <li>Current_thread</li>
+ * <li>Soft_IRQs</li>
+ * <li>IRQs</li>
+ * </ul>
+ */
+ private static final String[] CPUS_QUARK_PATTERN = { Attributes.CPUS, "*" }; //$NON-NLS-1$
+
+ /**
+ * Get the tree element name for every cpu.
+ */
+ @VisibleForTesting
+ public static final Function<TreeRenderContext, TimeGraphTreeRender> SS_TO_TREE_RENDER_FUNCTION = (treeContext) -> {
+ ITmfStateSystem ss = treeContext.ss;
+
+ List<TimeGraphTreeElement> treeElems = ss.getQuarks(CPUS_QUARK_PATTERN).stream()
+ .map(cpuQuark -> {
+ String cpuStr = ss.getAttributeName(cpuQuark);
+ Integer cpu = Ints.tryParse(cpuStr);
+ if (cpu == null) {
+ return null;
+ }
+
+ List<ResourcesIrqTreeElement> children = new LinkedList<>();
+
+ /* Add the "IRQ" children. */
+ int irqsQuark = ss.getQuarkRelative(cpuQuark, Attributes.IRQS);
+ for (int irqQuark : ss.getSubAttributes(irqsQuark, false)) {
+ int irqNumber = Ints.tryParse(ss.getAttributeName(irqQuark));
+ children.add(new ResourcesIrqTreeElement(IrqType.IRQ, irqNumber, irqQuark));
+ }
+
+ /* Add the "SoftIRQ" children. */
+ int softIrqsQuark = ss.getQuarkRelative(cpuQuark, Attributes.SOFT_IRQS);
+ for (int softIrqQuark : ss.getSubAttributes(softIrqsQuark, false)) {
+ int irqNumber = Ints.tryParse(ss.getAttributeName(softIrqQuark));
+ children.add(new ResourcesIrqTreeElement(IrqType.SOFTIRQ, irqNumber, softIrqQuark));
+ }
+
+ Collections.sort(children, IRQ_SORTER);
+ /* Generic types are not covariant :/ Use a raw type instead... */
+ @SuppressWarnings("rawtypes")
+ List children2 = children;
+ return new ResourcesCpuTreeElement(cpu, children2, cpuQuark);
+ })
+ .filter(Objects::nonNull)
+ /*
+ * Sort entries according to their CPU number (not just an
+ * alphabetical sort!)
+ */
+ .sorted(Comparator.comparingInt(ResourcesCpuTreeElement::getCpu))
+ .collect(Collectors.toList());
+
+ TimeGraphTreeElement rootElement = new TimeGraphTreeElement(treeContext.traceName, treeElems);
+ return new TimeGraphTreeRender(rootElement);
+ };
+
+ /**
+ * Constructor
+ */
+ public ResourcesCpuIrqModelProvider() {
+ super(requireNonNull(Messages.resourcesCpuIrqProviderName), SS_TO_TREE_RENDER_FUNCTION);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph.resources;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.function.Function;
+
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.views.timegraph.resources.elements.ResourcesIrqTreeElement;
+import org.lttng.scope.lttng.kernel.core.views.timegraph.resources.elements.ResourcesIrqTreeElement.IrqType;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeElement;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeRender;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.primitives.Ints;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystem;
+
+/**
+ * View model for a Resources view showing IRQs and SoftIRQs.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class ResourcesIrqModelProvider extends ResourcesBaseModelProvider {
+
+ private static final String[] IRQS_QUARK_PATTERN = { Attributes.IRQS, "*" }; //$NON-NLS-1$
+ private static final String[] SOFT_IRQS_QUARK_PATTERN = { Attributes.SOFT_IRQS, "*" }; //$NON-NLS-1$
+
+ /**
+ * Get the tree element name for every cpu.
+ */
+ @VisibleForTesting
+ public static final Function<TreeRenderContext, TimeGraphTreeRender> SS_TO_TREE_RENDER_FUNCTION = (treeContext) -> {
+ ITmfStateSystem ss = treeContext.ss;
+
+ List<ResourcesIrqTreeElement> treeElems = new LinkedList<>();
+ /* Create "IRQ *" children */
+ ss.getQuarks(IRQS_QUARK_PATTERN).forEach(irqQuark -> {
+ String name = ss.getAttributeName(irqQuark);
+ Integer irqNumber = Ints.tryParse(name);
+ if (irqNumber != null) {
+ treeElems.add(new ResourcesIrqTreeElement(IrqType.IRQ, irqNumber, irqQuark));
+ }
+ });
+
+ /* Create "SoftIRQ *" children */
+ ss.getQuarks(SOFT_IRQS_QUARK_PATTERN).forEach(irqQuark -> {
+ String name = ss.getAttributeName(irqQuark);
+ Integer irqNumber = Ints.tryParse(name);
+ if (irqNumber != null) {
+ treeElems.add(new ResourcesIrqTreeElement(IrqType.SOFTIRQ, irqNumber, irqQuark));
+ }
+ });
+
+ Collections.sort(treeElems, IRQ_SORTER);
+ @SuppressWarnings("rawtypes")
+ List treeElems2 = treeElems;
+ TimeGraphTreeElement rootElement = new TimeGraphTreeElement(treeContext.traceName, treeElems2);
+ return new TimeGraphTreeRender(rootElement);
+ };
+
+ /**
+ * Constructor
+ */
+ public ResourcesIrqModelProvider() {
+ super(requireNonNull(Messages.resourcesIrqProviderName), SS_TO_TREE_RENDER_FUNCTION);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph.resources;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.lttng.scope.lttng.kernel.core.analysis.os.KernelAnalysisModule;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+import org.lttng.scope.lttng.kernel.core.views.timegraph.KernelAnalysisStateDefinitions;
+import org.lttng.scope.tmf2.views.core.config.ConfigOption;
+import org.lttng.scope.tmf2.views.core.timegraph.model.provider.statesystem.StateSystemModelStateProvider;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.ColorDefinition;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.LineThickness;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.StateDefinition;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+
+import ca.polymtl.dorsal.libdelorean.exceptions.StateValueTypeException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+
+/**
+ * State provider of the Resources time graph.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class ResourcesModelStateProvider extends StateSystemModelStateProvider {
+
+ // ------------------------------------------------------------------------
+ // Label mapping
+ // ------------------------------------------------------------------------
+
+ private static final Function<StateIntervalContext, @Nullable String> LABEL_MAPPING_FUNCTION = ssCtx -> null;
+
+ // ------------------------------------------------------------------------
+ // Color mapping, line thickness
+ // ------------------------------------------------------------------------
+
+ /**
+ * State definitions used in this provider.
+ */
+ private static final List<StateDefinition> STATE_DEFINITIONS = ImmutableList.of(
+ KernelAnalysisStateDefinitions.CPU_STATE_IDLE,
+ KernelAnalysisStateDefinitions.THREAD_STATE_SYSCALL,
+ KernelAnalysisStateDefinitions.THREAD_STATE_USERMODE,
+ KernelAnalysisStateDefinitions.CPU_STATE_IRQ_ACTIVE,
+ KernelAnalysisStateDefinitions.CPU_STATE_SOFTIRQ_ACTIVE,
+ KernelAnalysisStateDefinitions.CPU_STATE_SOFTIRQ_RAISED);
+
+ private static final Function<StateIntervalContext, StateDefinition> STATE_DEF_MAPPING_FUNCTION = ssCtx -> {
+ ITmfStateValue val = ssCtx.sourceInterval.getStateValue();
+ return stateValueToStateDef(val);
+ };
+
+ @VisibleForTesting
+ static final StateDefinition stateValueToStateDef(ITmfStateValue val) {
+ if (val.isNull()) {
+ return KernelAnalysisStateDefinitions.NO_STATE;
+ }
+
+ try {
+ int status = val.unboxInt();
+ switch (status) {
+ case StateValues.CPU_STATUS_IDLE:
+ return KernelAnalysisStateDefinitions.CPU_STATE_IDLE;
+ case StateValues.CPU_STATUS_RUN_SYSCALL:
+ return KernelAnalysisStateDefinitions.THREAD_STATE_SYSCALL;
+ case StateValues.CPU_STATUS_RUN_USERMODE:
+ return KernelAnalysisStateDefinitions.THREAD_STATE_USERMODE;
+ case StateValues.CPU_STATUS_IRQ:
+ return KernelAnalysisStateDefinitions.CPU_STATE_IRQ_ACTIVE;
+ case StateValues.CPU_STATUS_SOFTIRQ:
+ return KernelAnalysisStateDefinitions.CPU_STATE_SOFTIRQ_ACTIVE;
+ case StateValues.CPU_STATUS_SOFT_IRQ_RAISED:
+ return KernelAnalysisStateDefinitions.CPU_STATE_SOFTIRQ_RAISED;
+ default:
+ return KernelAnalysisStateDefinitions.CPU_STATE_UNKNOWN;
+ }
+
+ } catch (StateValueTypeException e) {
+ return KernelAnalysisStateDefinitions.CPU_STATE_UNKNOWN;
+ }
+ }
+
+ private static final Function<StateIntervalContext, String> STATE_NAME_MAPPING_FUNCTION = ssCtx -> STATE_DEF_MAPPING_FUNCTION.apply(ssCtx).getName();
+
+ private static final Function<StateIntervalContext, ConfigOption<ColorDefinition>> COLOR_MAPPING_FUNCTION = ssCtx -> STATE_DEF_MAPPING_FUNCTION.apply(ssCtx).getColor();
+
+ private static final Function<StateIntervalContext, ConfigOption<LineThickness>> LINE_THICKNESS_MAPPING_FUNCTION = ssCtx -> STATE_DEF_MAPPING_FUNCTION.apply(ssCtx).getLineThickness();
+
+ // ------------------------------------------------------------------------
+ // Properties
+ // ------------------------------------------------------------------------
+
+ private static final Function<StateIntervalContext, Map<String, String>> PROPERTIES_MAPPING_FUNCTION = ssCtx -> {
+ // TODO Add current thread on this CPU
+ return Collections.emptyMap();
+ };
+
+ /**
+ * Constructor
+ */
+ public ResourcesModelStateProvider() {
+ super(STATE_DEFINITIONS,
+ KernelAnalysisModule.ID,
+ STATE_NAME_MAPPING_FUNCTION,
+ LABEL_MAPPING_FUNCTION,
+ COLOR_MAPPING_FUNCTION,
+ LINE_THICKNESS_MAPPING_FUNCTION,
+ PROPERTIES_MAPPING_FUNCTION);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 EfficiOS Inc., Alexandre Montplaisir
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph.resources.elements;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Messages class
+ *
+ * @author Alexandre Montplaisir
+ * @noreference Message class
+ */
+@SuppressWarnings("javadoc")
+@NonNullByDefault({})
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+
+ public static String treeElementPrefixCpu;
+ public static String treeElementPrefixIrq;
+ public static String treeElementPrefixSoftIrq;
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph.resources.elements;
+
+import java.util.List;
+import java.util.function.Predicate;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.ctf.tmf.core.event.CtfTmfEvent;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.tmf2.views.core.timegraph.model.provider.statesystem.StateSystemTimeGraphTreeElement;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeElement;
+
+/**
+ * Element of the Resources time graph which represents a CPU.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class ResourcesCpuTreeElement extends StateSystemTimeGraphTreeElement {
+
+ private final int fCpu;
+
+ /**
+ * Constructor
+ *
+ * @param cpu
+ * The CPU of this CPU tree element
+ * @param children
+ * The child elements
+ * @param sourceQuark
+ * The corresponding quark (under the "CPUs" sub-tree) in the
+ * state system.
+ */
+ public ResourcesCpuTreeElement(int cpu,
+ List<TimeGraphTreeElement> children, int sourceQuark) {
+ super(Messages.treeElementPrefixCpu + ' ' + String.valueOf(cpu),
+ children,
+ sourceQuark);
+
+ fCpu = cpu;
+ }
+
+ /**
+ * Get the CPU represented by this tree element
+ *
+ * @return The CPU number
+ */
+ public int getCpu() {
+ return fCpu;
+ }
+
+ @Override
+ public @NonNull Predicate<ITmfEvent> getEventMatching() {
+ return event -> {
+ // FIXME The notion of CPU should be in the base framework.
+ if (!(event instanceof CtfTmfEvent)) {
+ return false;
+ }
+ CtfTmfEvent ctfEvent = (CtfTmfEvent) event;
+ return (fCpu == ctfEvent.getCPU());
+ };
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph.resources.elements;
+
+import java.util.Collections;
+
+import org.lttng.scope.tmf2.views.core.timegraph.model.provider.statesystem.StateSystemTimeGraphTreeElement;
+
+/**
+ * Element of the Resources time graph which represents an IRQ (Software or
+ * Hardware).
+ *
+ * @author Alexandre Montplaisir
+ */
+public class ResourcesIrqTreeElement extends StateSystemTimeGraphTreeElement {
+
+ /** Type of IRQ */
+ public enum IrqType {
+ /** Hardware IRQ */
+ IRQ,
+ /** Software IRQ */
+ SOFTIRQ
+ }
+
+ private final IrqType fIrqType;
+ private final int fIrqNumber;
+
+ /**
+ * Constructor
+ *
+ * @param irqType
+ * Type of IRQ
+ * @param irqNumber
+ * IRQ number
+ * @param sourceQuark
+ * The corresponding quark (under the "CPUs" sub-tree) in the state
+ * system.
+ */
+ public ResourcesIrqTreeElement(IrqType irqType, int irqNumber, int sourceQuark) {
+ super(getName(irqType, irqNumber),
+ Collections.emptyList(),
+ sourceQuark);
+
+ fIrqType = irqType;
+ fIrqNumber = irqNumber;
+ }
+
+ private static final String getName(IrqType irqType, int irqNumber) {
+ String prefix;
+ switch (irqType) {
+ case IRQ:
+ prefix = Messages.treeElementPrefixIrq;
+ break;
+ case SOFTIRQ:
+ default:
+ prefix = Messages.treeElementPrefixSoftIrq;
+ break;
+ }
+ return prefix + ' ' + String.valueOf(irqNumber);
+ }
+
+ /**
+ * Get the IRQ type.
+ *
+ * @return IRQ type
+ */
+ public IrqType getIrqType() {
+ return fIrqType;
+ }
+
+ /**
+ * Get the IRQ number.
+ *
+ * @return IRQ number
+ */
+ public int getIrqNumber() {
+ return fIrqNumber;
+ }
+
+}
--- /dev/null
+###############################################################################
+# Copyright (c) 2017 EfficiOS Inc., Alexandre Montplaisir
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+treeElementPrefixCpu = CPU
+treeElementPrefixIrq = IRQ
+treeElementPrefixSoftIrq = Soft IRQ
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.lttng.scope.lttng.kernel.core.views.timegraph.resources.elements;
--- /dev/null
+###############################################################################
+# Copyright (C) 2016-2017 EfficiOS Inc., Alexandre Montplaisir
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+resourcesCpuIrqProviderName = CPU / IRQ
+resourcesIrqProviderName = IRQ
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.lttng.scope.lttng.kernel.core.views.timegraph.resources;
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph.threads;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Messages class
+ *
+ * @author Alexandre Montplaisir
+ * @noreference Message class
+ */
+@SuppressWarnings("javadoc")
+@NonNullByDefault({})
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+
+ public static String ControlFlowSortingModes_ByTid;
+ public static String ControlFlowSortingModes_ByThreadName;
+
+ public static String ControlFlowFilterModes_InactiveEntries;
+
+ public static String threadsProviderName;
+
+ public static String arrowSeriesCPUs;
+
+ public static String propertyNotAvailable;
+ public static String propertyNameCpu;
+ public static String propertyNameSyscall;
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph.threads;
+
+import static org.lttng.scope.common.core.NonNullUtils.nullToEmptyString;
+
+import org.lttng.scope.tmf2.views.core.timegraph.model.provider.ITimeGraphModelProvider.FilterMode;
+import org.lttng.scope.tmf2.views.core.timegraph.model.provider.ITimeGraphModelProvider.SortingMode;
+
+public interface ThreadsConfigModes {
+
+ SortingMode SORTING_BY_TID = new SortingMode(nullToEmptyString(Messages.ControlFlowSortingModes_ByTid));
+
+ SortingMode SORTING_BY_THREAD_NAME = new SortingMode(nullToEmptyString(Messages.ControlFlowSortingModes_ByThreadName));
+
+ FilterMode FILTERING_INACTIVE_ENTRIES = new FilterMode(nullToEmptyString(Messages.ControlFlowFilterModes_InactiveEntries));
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph.threads;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.FutureTask;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.analysis.os.KernelAnalysisModule;
+import org.lttng.scope.tmf2.views.core.TimeRange;
+import org.lttng.scope.tmf2.views.core.timegraph.model.provider.statesystem.StateSystemModelArrowProvider;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.FlatUIColors;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.TimeGraphEvent;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.arrows.TimeGraphArrow;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.arrows.TimeGraphArrowRender;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.arrows.TimeGraphArrowSeries;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.arrows.TimeGraphArrowSeries.LineStyle;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeElement;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeRender;
+
+import com.google.common.collect.Iterables;
+import com.google.common.primitives.Ints;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystem;
+import ca.polymtl.dorsal.libdelorean.StateSystemUtils;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.exceptions.StateSystemDisposedException;
+import ca.polymtl.dorsal.libdelorean.interval.ITmfStateInterval;
+
+public class ThreadsModelArrowProviderCpus extends StateSystemModelArrowProvider {
+
+ private static final TimeGraphArrowSeries ARROW_SERIES = new TimeGraphArrowSeries(
+ requireNonNull(Messages.arrowSeriesCPUs),
+ FlatUIColors.RED,
+ LineStyle.FULL);
+
+ public ThreadsModelArrowProviderCpus() {
+ super(ARROW_SERIES, KernelAnalysisModule.ID);
+ }
+
+ @Override
+ public TimeGraphArrowRender getArrowRender(TimeGraphTreeRender treeRender, TimeRange timeRange, @Nullable FutureTask<?> task) {
+ ITmfStateSystem ss = getStateSystem();
+ if (ss == null) {
+ return TimeGraphArrowRender.EMPTY_RENDER;
+ }
+
+ List<Integer> threadLineQuarks = ss.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD); //$NON-NLS-1$
+ List<List<TimeGraphArrow>> allArrows = new LinkedList<>();
+ try {
+ for (int threadLineQuark : threadLineQuarks) {
+ List<ITmfStateInterval> intervals = StateSystemUtils.queryHistoryRange(ss, threadLineQuark, timeRange.getStart(), timeRange.getEnd(), 1, task);
+ if (task != null && task.isCancelled()) {
+ return TimeGraphArrowRender.EMPTY_RENDER;
+ }
+ if (intervals.size() < 2) {
+ /* Not enough states to establish a timeline */
+ continue;
+ }
+
+ String cpuName = ss.getAttributeName(ss.getParentAttributeQuark(threadLineQuark));
+ Integer cpu = Ints.tryParse(cpuName);
+ List<TimeGraphArrow> arrows = getArrowsFromStates(treeRender, intervals, cpu);
+ allArrows.add(arrows);
+ }
+
+ } catch (AttributeNotFoundException | StateSystemDisposedException e) {
+ e.printStackTrace();
+ return TimeGraphArrowRender.EMPTY_RENDER;
+ }
+
+ Iterable<TimeGraphArrow> flattenedArrows = Iterables.concat(allArrows);
+ return new TimeGraphArrowRender(timeRange, flattenedArrows);
+ }
+
+ private List<TimeGraphArrow> getArrowsFromStates(TimeGraphTreeRender treeRender, List<ITmfStateInterval> threadTimeline, @Nullable Integer cpu) {
+ List<TimeGraphArrow> arrows = new LinkedList<>();
+ for (int i = 1; i < threadTimeline.size(); i++) {
+ ITmfStateInterval interval1 = threadTimeline.get(i - 1);
+ ITmfStateInterval interval2 = threadTimeline.get(i);
+ int thread1 = interval1.getStateValue().unboxInt();
+ int thread2 = interval2.getStateValue().unboxInt();
+
+ if (thread1 == -1 || thread2 == -1) {
+ /* No arrow to draw here */
+ continue;
+ }
+
+ TimeGraphTreeElement startTreeElem = getTreeElementFromThread(treeRender, thread1, cpu);
+ TimeGraphTreeElement endTreeElem = getTreeElementFromThread(treeRender, thread2, cpu);
+ TimeGraphEvent startEvent = new TimeGraphEvent(interval1.getEndTime(), startTreeElem);
+ TimeGraphEvent endEvent = new TimeGraphEvent(interval2.getStartTime(), endTreeElem);
+
+ TimeGraphArrow arrow = new TimeGraphArrow(startEvent, endEvent, getArrowSeries());
+ arrows.add(arrow);
+ }
+ return arrows;
+ }
+
+ private static TimeGraphTreeElement getTreeElementFromThread(TimeGraphTreeRender treeRender, int tid, @Nullable Integer cpu) {
+ if (tid != 0) {
+ // FIXME Could be improved via indexing, to avoid iterating the
+ // whole
+ // array for every single tid.
+ return Iterables.find(treeRender.getAllTreeElements(), treeElem -> {
+ ThreadsTreeElement cfvTreeElem = (ThreadsTreeElement) treeElem;
+ return (cfvTreeElem.getTid() == tid);
+ });
+ }
+ if (cpu == null) {
+ throw new IllegalStateException();
+ }
+ String prefix = "0/" + cpu.toString(); //$NON-NLS-1$
+ return Iterables.find(treeRender.getAllTreeElements(), treeElem -> {
+ ThreadsTreeElement cfvTreeElem = (ThreadsTreeElement) treeElem;
+ return cfvTreeElem.getName().startsWith(prefix);
+ });
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph.threads;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.analysis.os.KernelAnalysisModule;
+import org.lttng.scope.tmf2.views.core.timegraph.model.provider.arrows.ITimeGraphModelArrowProvider;
+import org.lttng.scope.tmf2.views.core.timegraph.model.provider.states.ITimeGraphModelStateProvider;
+import org.lttng.scope.tmf2.views.core.timegraph.model.provider.statesystem.StateSystemModelProvider;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeElement;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeRender;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+
+import ca.polymtl.dorsal.libdelorean.ITmfStateSystem;
+import ca.polymtl.dorsal.libdelorean.StateSystemUtils;
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.interval.ITmfStateInterval;
+
+public class ThreadsModelProvider extends StateSystemModelProvider {
+
+ private static final Supplier<ITimeGraphModelStateProvider> STATE_PROVIDER = () -> {
+ return new ThreadsModelStateProvider();
+ };
+
+ private static final Supplier<List<ITimeGraphModelArrowProvider>> ARROW_PROVIDERS = () -> {
+ return ImmutableList.of(
+ new ThreadsModelArrowProviderCpus()
+ );
+ };
+
+ private static final List<SortingMode> SORTING_MODES = ImmutableList.of(
+ ThreadsConfigModes.SORTING_BY_TID,
+ ThreadsConfigModes.SORTING_BY_THREAD_NAME);
+
+ private static final List<FilterMode> FILTER_MODES = ImmutableList.of(
+ ThreadsConfigModes.FILTERING_INACTIVE_ENTRIES);
+
+ // ------------------------------------------------------------------------
+ // Tree render
+ // ------------------------------------------------------------------------
+
+ /**
+ * State values that are considered inactive, for purposes of filtering out
+ * when the "filter inactive entries" mode is enabled.
+ */
+// private static final Set<ITmfStateValue> INACTIVE_STATE_VALUES = ImmutableSet.of(
+// TmfStateValue.nullValue(),
+// StateValues.PROCESS_STATUS_UNKNOWN_VALUE,
+// StateValues.PROCESS_STATUS_WAIT_UNKNOWN_VALUE,
+// StateValues.PROCESS_STATUS_WAIT_BLOCKED_VALUE
+// );
+
+ /**
+ * Each "Thread" attribute has the following children:
+ *
+ * <ul>
+ * <li>Prio</li>
+ * <li>System_call</li>
+ * <li>Exec_name</li>
+ * <li>PPID</li>
+ * </ul>
+ *
+ * The "Thread" is considered the base quark.
+ */
+ private static final String[] BASE_QUARK_PATTERN = { Attributes.THREADS, "*" }; //$NON-NLS-1$
+
+ /**
+ * Get the tree element name for every thread. It consists of the TID
+ * followed by the first available exec_name for this thread.
+ *
+ * FIXME This implies a static tree definition for every TID, which does not
+ * handle TID re-use correctly. The state system structure should be updated
+ * accordingly.
+ */
+ @VisibleForTesting
+ public static final Function<TreeRenderContext, TimeGraphTreeRender> SS_TO_TREE_RENDER_FUNCTION = (treeContext) -> {
+ ITmfStateSystem ss = treeContext.ss;
+// List<ITmfStateInterval> fullState = treeContext.fullQueryAtRangeStart;
+
+ Stream<ThreadsTreeElement> treeElems = ss.getQuarks(BASE_QUARK_PATTERN).stream()
+ .map(baseQuark -> {
+ String tid = ss.getAttributeName(baseQuark);
+
+ String threadName;
+ try {
+ int execNameQuark = ss.getQuarkRelative(baseQuark, Attributes.EXEC_NAME);
+ // TODO We should look starting at
+ // treeContext.renderTimeRangeStart first, and if we
+ // don't find anything use ss.getStartTime(), so that we
+ // catch subsequent process name changes
+ ITmfStateInterval firstInterval = StateSystemUtils.queryUntilNonNullValue(ss,
+ execNameQuark, ss.getStartTime(), Long.MAX_VALUE);
+ if (firstInterval == null) {
+ threadName = null;
+ } else {
+ threadName = firstInterval.getStateValue().unboxStr();
+ }
+ } catch (AttributeNotFoundException e) {
+ threadName = null;
+ }
+
+ return new ThreadsTreeElement(tid, threadName, Collections.emptyList(), baseQuark);
+ });
+
+ /* Run the entries through the active filter modes */
+// Set<FilterMode> filterModes = treeContext.filterModes;
+// if (filterModes.contains(ControlFlowConfigModes.FILTERING_INACTIVE_ENTRIES)) {
+// /*
+// * Filter out the tree elements whose state is considered inactive
+// * for the whole duration of the configured time range.
+// */
+// treeElems = treeElems.filter(elem -> {
+// ITmfStateInterval interval = fullState.get(elem.getSourceQuark());
+// if (interval.getEndTime() > treeContext.renderTimeRangeEnd &&
+// INACTIVE_STATE_VALUES.contains(interval.getStateValue())) {
+// return false;
+// }
+// return true;
+// });
+// }
+
+ /* Sort entries according to the active sorting mode */
+ SortingMode sortingMode = treeContext.sortingMode;
+ if (sortingMode == ThreadsConfigModes.SORTING_BY_TID) {
+ treeElems = treeElems.sorted(Comparator.comparingInt(ThreadsTreeElement::getTid));
+ } else if (sortingMode == ThreadsConfigModes.SORTING_BY_THREAD_NAME) {
+ treeElems = treeElems.sorted((elem1, elem2) -> {
+ return elem1.getThreadName().compareToIgnoreCase(elem2.getThreadName());
+ });
+ }
+
+ List<TimeGraphTreeElement> treeElemsList = treeElems.collect(Collectors.toList());
+ TimeGraphTreeElement rootElement = new TimeGraphTreeElement(treeContext.traceName, treeElemsList);
+ return new TimeGraphTreeRender(rootElement);
+ };
+
+ /**
+ * Constructor
+ */
+ public ThreadsModelProvider() {
+ super(requireNonNull(Messages.threadsProviderName),
+ SORTING_MODES,
+ FILTER_MODES,
+ STATE_PROVIDER.get(),
+ ARROW_PROVIDERS.get(),
+ /* Parameters specific to state system render providers */
+ KernelAnalysisModule.ID,
+ SS_TO_TREE_RENDER_FUNCTION);
+
+ enableFilterMode(0);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.lttng.scope.lttng.kernel.core.views.timegraph.threads;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.analysis.os.KernelAnalysisModule;
+import org.lttng.scope.lttng.kernel.core.analysis.os.StateValues;
+import org.lttng.scope.lttng.kernel.core.views.timegraph.KernelAnalysisStateDefinitions;
+import org.lttng.scope.tmf2.views.core.config.ConfigOption;
+import org.lttng.scope.tmf2.views.core.timegraph.model.provider.statesystem.StateSystemModelStateProvider;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.ColorDefinition;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.LineThickness;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.StateDefinition;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
+import ca.polymtl.dorsal.libdelorean.exceptions.StateValueTypeException;
+import ca.polymtl.dorsal.libdelorean.statevalue.ITmfStateValue;
+
+public class ThreadsModelStateProvider extends StateSystemModelStateProvider {
+
+ // ------------------------------------------------------------------------
+ // Label mapping
+ // ------------------------------------------------------------------------
+
+ /** Prefixes to strip from syscall names in the labels */
+ // TODO This should be inferred from the kernel event layout
+ private static final Collection<String> SYSCALL_PREFIXES = Arrays.asList("sys_", "syscall_entry_"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ private static final Function<StateIntervalContext, @Nullable String> LABEL_MAPPING_FUNCTION = ssCtx -> {
+ int statusQuark = ssCtx.baseTreeElement.getSourceQuark();
+ long startTime = ssCtx.sourceInterval.getStartTime();
+ ITmfStateValue val = ssCtx.ss.querySingleState(startTime, statusQuark).getStateValue();
+
+ /* If the status is "syscall", use the name of the syscall as label */
+ if (!val.equals(StateValues.PROCESS_STATUS_RUN_SYSCALL_VALUE)) {
+ return null;
+ }
+
+ String syscallName;
+ try {
+ int syscallQuark = ssCtx.ss.getQuarkRelative(statusQuark, Attributes.SYSTEM_CALL);
+ syscallName = ssCtx.ss.querySingleState(startTime, syscallQuark).getStateValue().unboxStr();
+ } catch (AttributeNotFoundException | StateValueTypeException e) {
+ return null;
+ }
+
+ /*
+ * Strip the "syscall" prefix part if there is one, it's not useful in
+ * the label.
+ */
+ for (String sysPrefix : SYSCALL_PREFIXES) {
+ if (syscallName.startsWith(sysPrefix)) {
+ syscallName = syscallName.substring(sysPrefix.length());
+ }
+ }
+
+ return syscallName;
+ };
+
+ // ------------------------------------------------------------------------
+ // Color mapping, line thickness
+ // ------------------------------------------------------------------------
+
+ /**
+ * State definitions used in this provider.
+ */
+ private static final List<StateDefinition> STATE_DEFINITIONS = ImmutableList.of(
+ KernelAnalysisStateDefinitions.THREAD_STATE_UNKNOWN,
+ KernelAnalysisStateDefinitions.THREAD_STATE_WAIT_UNKNOWN,
+ KernelAnalysisStateDefinitions.THREAD_STATE_WAIT_BLOCKED,
+ KernelAnalysisStateDefinitions.THREAD_STATE_WAIT_FOR_CPU,
+ KernelAnalysisStateDefinitions.THREAD_STATE_USERMODE,
+ KernelAnalysisStateDefinitions.THREAD_STATE_SYSCALL,
+ KernelAnalysisStateDefinitions.THREAD_STATE_INTERRUPTED);
+
+ private static final Function<StateIntervalContext, StateDefinition> STATE_DEF_MAPPING_FUNCTION = ssCtx -> {
+ ITmfStateValue val = ssCtx.sourceInterval.getStateValue();
+ return stateValueToStateDef(val);
+ };
+
+ @VisibleForTesting
+ static final StateDefinition stateValueToStateDef(ITmfStateValue val) {
+ if (val.isNull()) {
+ return KernelAnalysisStateDefinitions.NO_STATE;
+ }
+
+ try {
+ int status = val.unboxInt();
+ switch (status) {
+ case StateValues.PROCESS_STATUS_WAIT_UNKNOWN:
+ return KernelAnalysisStateDefinitions.THREAD_STATE_WAIT_UNKNOWN;
+ case StateValues.PROCESS_STATUS_WAIT_BLOCKED:
+ return KernelAnalysisStateDefinitions.THREAD_STATE_WAIT_BLOCKED;
+ case StateValues.PROCESS_STATUS_WAIT_FOR_CPU:
+ return KernelAnalysisStateDefinitions.THREAD_STATE_WAIT_FOR_CPU;
+ case StateValues.PROCESS_STATUS_RUN_USERMODE:
+ return KernelAnalysisStateDefinitions.THREAD_STATE_USERMODE;
+ case StateValues.PROCESS_STATUS_RUN_SYSCALL:
+ return KernelAnalysisStateDefinitions.THREAD_STATE_SYSCALL;
+ case StateValues.PROCESS_STATUS_INTERRUPTED:
+ return KernelAnalysisStateDefinitions.THREAD_STATE_INTERRUPTED;
+ default:
+ return KernelAnalysisStateDefinitions.THREAD_STATE_UNKNOWN;
+ }
+
+ } catch (StateValueTypeException e) {
+ return KernelAnalysisStateDefinitions.THREAD_STATE_UNKNOWN;
+ }
+ }
+
+ private static final Function<StateIntervalContext, String> STATE_NAME_MAPPING_FUNCTION = ssCtx -> STATE_DEF_MAPPING_FUNCTION.apply(ssCtx).getName();
+
+ private static final Function<StateIntervalContext, ConfigOption<ColorDefinition>> COLOR_MAPPING_FUNCTION = ssCtx -> STATE_DEF_MAPPING_FUNCTION.apply(ssCtx).getColor();
+
+ private static final Function<StateIntervalContext, ConfigOption<LineThickness>> LINE_THICKNESS_MAPPING_FUNCTION = ssCtx -> STATE_DEF_MAPPING_FUNCTION.apply(ssCtx).getLineThickness();
+
+ // ------------------------------------------------------------------------
+ // Properties
+ // ------------------------------------------------------------------------
+
+ private static final Function<StateIntervalContext, Map<String, String>> PROPERTIES_MAPPING_FUNCTION = ssCtx -> {
+ /* Include properties for CPU and syscall name. */
+ int baseQuark = ssCtx.baseTreeElement.getSourceQuark();
+ long startTime = ssCtx.sourceInterval.getStartTime();
+
+ String cpu;
+ try {
+ int cpuQuark = ssCtx.ss.getQuarkRelative(baseQuark, Attributes.CURRENT_CPU_RQ);
+ ITmfStateValue sv = ssCtx.ss.querySingleState(startTime, cpuQuark).getStateValue();
+ cpu = (sv.isNull() ? requireNonNull(Messages.propertyNotAvailable) : String.valueOf(sv.unboxInt()));
+ } catch (AttributeNotFoundException e) {
+ cpu = requireNonNull(Messages.propertyNotAvailable);
+ }
+
+ String syscall;
+ try {
+ int syscallNameQuark = ssCtx.ss.getQuarkRelative(baseQuark, Attributes.SYSTEM_CALL);
+ ITmfStateValue sv = ssCtx.ss.querySingleState(startTime, syscallNameQuark).getStateValue();
+ syscall = (sv.isNull() ? requireNonNull(Messages.propertyNotAvailable) : sv.unboxStr());
+ } catch (AttributeNotFoundException e) {
+ syscall = requireNonNull(Messages.propertyNotAvailable);
+ }
+
+ return ImmutableMap.of(requireNonNull(Messages.propertyNameCpu), cpu,
+ requireNonNull(Messages.propertyNameSyscall), syscall);
+ };
+
+ /**
+ * Constructor
+ */
+ public ThreadsModelStateProvider() {
+ super(STATE_DEFINITIONS,
+ KernelAnalysisModule.ID,
+ STATE_NAME_MAPPING_FUNCTION,
+ LABEL_MAPPING_FUNCTION,
+ COLOR_MAPPING_FUNCTION,
+ LINE_THICKNESS_MAPPING_FUNCTION,
+ PROPERTIES_MAPPING_FUNCTION);
+ }
+}
--- /dev/null
+package org.lttng.scope.lttng.kernel.core.views.timegraph.threads;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.List;
+import java.util.function.Predicate;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.ctf.tmf.core.event.CtfTmfEvent;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.lttng.scope.lttng.kernel.core.analysis.os.Attributes;
+import org.lttng.scope.lttng.kernel.core.event.aspect.KernelTidAspect;
+import org.lttng.scope.tmf2.views.core.timegraph.model.provider.statesystem.StateSystemTimeGraphTreeElement;
+import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeElement;
+
+import com.google.common.primitives.Ints;
+
+public class ThreadsTreeElement extends StateSystemTimeGraphTreeElement {
+
+ private static final String UNKNOWN_THREAD_NAME = "???"; //$NON-NLS-1$
+
+ private final int fTid;
+ /** CPU is only defined when fTid == 0 */
+ private final @Nullable Integer fCpu;
+ private final String fThreadName;
+
+ public ThreadsTreeElement(String tidStr, @Nullable String threadName,
+ List<TimeGraphTreeElement> children, int sourceQuark) {
+ super(getElementName(tidStr, threadName),
+ children,
+ sourceQuark);
+
+ if (tidStr.startsWith(Attributes.THREAD_0_PREFIX)) {
+ fTid = 0;
+ String cpuStr = tidStr.substring(Attributes.THREAD_0_PREFIX.length());
+ Integer cpu = Ints.tryParse(cpuStr);
+ fCpu = (cpu == null ? 0 : cpu);
+ } else {
+ fTid = Integer.parseInt(tidStr);
+ fCpu = null;
+ }
+
+ fThreadName = (threadName == null ? UNKNOWN_THREAD_NAME : threadName);
+ }
+
+ private static String getElementName(String tidStr, @Nullable String threadName) {
+ String tidPart = tidStr;
+ if (tidPart.startsWith(Attributes.THREAD_0_PREFIX)) {
+ /* Display "0/0" instead of "0_0" */
+ tidPart = tidPart.replace('_', '/');
+ }
+
+ String threadNamePart = (threadName == null ? UNKNOWN_THREAD_NAME : threadName);
+ return (tidPart + " - " + threadNamePart); //$NON-NLS-1$
+ }
+
+ public int getTid() {
+ return fTid;
+ }
+
+ public String getThreadName() {
+ return fThreadName;
+ }
+
+ @Override
+ public @Nullable Predicate<ITmfEvent> getEventMatching() {
+ /*
+ * This tree element represents a thread ID. Return true for events
+ * whose TID aspect is the same as the TID of this element.
+ */
+ return event -> {
+ Integer eventTid = KernelTidAspect.INSTANCE.resolve(event);
+ if (eventTid == null) {
+ return false;
+ }
+ if (fTid != 0) {
+ return (eventTid.intValue() == fTid);
+ }
+ /*
+ * There are many elements for TID 0. We also need to compare the
+ * CPU.
+ */
+ int elemCpu = requireNonNull(fCpu).intValue();
+ // TODO The notion of CPU should move to the framework
+ int eventCpu;
+ if (event instanceof CtfTmfEvent) {
+ eventCpu = ((CtfTmfEvent) event).getCPU();
+ } else {
+ eventCpu = 0;
+ }
+ return (eventTid.intValue() == fTid
+ && eventCpu == elemCpu);
+ };
+ }
+
+}
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+ControlFlowSortingModes_ByTid = Sort by TID
+ControlFlowSortingModes_ByThreadName = Sort by Thread Name
+
+ControlFlowFilterModes_InactiveEntries = Filter inactive entries
+
+threadsProviderName = Threads
+
+arrowSeriesCPUs = CPUs
+
+propertyNotAvailable = N/A
+propertyNameCpu = CPU
+propertyNameSyscall = Syscall
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.lttng.scope.lttng.kernel.core.views.timegraph.threads;