Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [linuxtools-dev] Tmf: a model to support new trace analysis types

2013/7/12 Geneviève Bastien <gbastien@xxxxxxxxxxxx>:
> Each new analysis can then be implemented in its own standalone plugin, with
> core and ui, which would require only the tmf.core|ui (and the plugins
> containing other analysis it requires of course). The main plugins would not
> require any analysis modules.
>
> I'd like some feedback on the proposed approach.  I know Francis Giraldeau
> has been thinking on this problem as well, mostly on the dependencies
> between analysis.  I think this approach is complementary.

The idea is to build more complex analysis based on simpler ones. Here
is the event processing design I would suggest.

First, we should be able to query an analysis module to get the list
of events it requires. This way, only required event could be enabled
for a specific analysis, thus reducing the runtime overhead compared
to blindly enable all events. This is not possible currently with
switch cases in handleData(), and listing then by hand would break DRY
principle. Instead, we could implement handlers with inner anonymous
classes per-event, something very close to GUI event listeners:

processingManager.addListener("event_foo", new ITmfProcessingUnit() {
    @Override
    public void handleEvent(ITmfEvent event) {
        // process event_foo ...
    }
}

We also need multi-phases analysis. For instance, for kernel traces,
we need to read the statedump, then rewind the trace and start again,
because statedump and the actual tracing is interleaved.

Finally, we need dependencies between analysis modules. I would
suggest to add annotation with required classes. Here is a quick
prototype, with few analysis module classes Cx:

public class TmfProcessingDependencyTest {

    public static class C1 {}

    @TmfProcessingRequires(C1.class)
    public static class C2 {}

    @TmfProcessingRequires(C2.class)
    public static class C3 {}

    @TmfProcessingRequires(C1.class)
    public static class C4 {}

    @Before
    public void setup() {
        TmfProcessingRegistry man = TmfProcessingRegistry.getInstance();
        man.register(C1.class);
        man.register(C2.class);
        man.register(C3.class);
        man.register(C4.class);
    }

    @Test
    public void testModuleDependencyGraph() {
        List<Class<?>> deps =
TmfProcessingRegistry.getInstance().getDependencies(C3.class);
        assertTrue(deps.contains(C1.class));
        assertTrue(deps.contains(C2.class));
        assertTrue(deps.contains(C3.class));
        assertFalse(deps.contains(C4.class));
        assertTrue(isBefore(deps, C1.class, C2.class));
        assertTrue(isBefore(deps, C2.class, C3.class));
    }

    private static boolean isBefore(List<Class<?>> deps, Class<?>
before, Class<?> after) {
        return deps.indexOf(before) < deps.indexOf(after);
    }

Topological sort could be used to compute the dependencies, and then
classes could be instantiated dynamically. In this example, the module
C1 would receive the event before C2, and C3 would get it last, then
the next event would be processed.

The analysis extension point would make a reference to a top-level
analysis class. I don't know if this is state-of-the-art, or if the is
already some mechanism to handle this kind of class dependencies, so
comments are very welcome!

Thanks,

Francis Giraldeau


Back to the top