Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [linuxtools-dev] TMF: pluggable state provider contribution(s)

Hi Alexandre and Aaron,

Thank you for the discussion.

Replies below,

Le 23/04/2013 14:22, Alexandre Montplaisir a écrit :
On 13-04-23 12:40 PM, Aaron Spear wrote:
Hi Alexandre,

replies below:

----- Original Message -----

- In the XML files to define the state changes, you separate the actions
of "switching context" and "applying state change to the current
context". Is there any reason for this? This can make sense / be easier
when dealing with single-threaded applications, but in multi-threaded
applications or systems, a series of events in the trace could relate to
completely different attributes.
I realize that is a little odd to get your brain wrapped around it.  It is like
this because it was the most simple way that I could, in the same data driven 
implementation, be able to support the notion of a call stack on a given thread.
The events that come across for the function tracer that I did basically have a 
thread id in every event, and then a function/entry or exit as the event type.  
Because it is multi-threaded you have no idea what order any events will come in, 
and this means that you must, in the viewer, track the call stack for each thread
individually. So I FIRST check to see if we should "switch context" for the given
event, and then switch to a data structure that tracks the call stack for that 
context/thread.  Then if that same event is setup for any "push state change" or
"pop state change" I apply those.  I did want to keep this information (of the 
call stack for the thread) in the state system, but could not really figure out
an efficient way to do this.  I would certainly be open to better ideas here.
Oh yes, I definitely see the need of wanting to track all the values in
a stack. In fact, we already have something in place for exactly that ;)

If you look at ITmfStateSystemBuilder#pushAttribute and #popAttribute
(implemented in StateSystem.java), it allows pushing and popping
attributes in a stack, while tracking
- the current depth of the stack
- the state value of each element in the stack.

It works by using one attribute as the "stack attribute", whose value
indicates the current stack depth. It then uses sub-attributes of this
one, called "1", "2", "3", etc (representing the positions in the stack,
starting at the bottom), and the values of these attributes represent
the values that were pushed to the stack.
There is also a convenience ITmfStateSystem#querySingleStackTop that can
be used to directly query the value of the "top" of the stack, instead
of doing 2 queries every time.

If you are curious about how it can be used, you can look at its unit
tests in StateSystemPushPopTest.java. It goes over all the possible use
cases.

This is probably something you can re-use for your push/popping of
contexts. Or we can see if it could be improved so that it can be re-used.

Would it be more generic to have only one entry per state change, which
would define both the attribute/context to modify and the value that is
being given?
Well, it is trickier than that though.  Consider the use case of this function
tracer.  In that case, you have only have the following two different events 
-thread id
-event type: function entry
-new function name

-thread id
-event type: function exit
-name of function you are EXITING

There are two reasons then why you must have the "push", "pop" in addition to a
switch:

-You want to be able to indicate functions for a given thread mutually 
exclusively so that it is clear what functions are running and what functions
are up stack at any point. 
-If you didn't care about showing what was up stack in a different color you
could do a switch for the function entry, since you have all the information
you need in the event.  However, for function exit, you only have that you are
exiting a function, and thus you do not know what you need to switch to.  You
must track this outside.

Yes, you could have a single entry that can do all of this, but it ends up being
"6 of one, half dozen of the other".  If you do this, then to support my 
"call stack" use case you must indicate that this particular event is either a 
"switch only" in which case the new value in the event is the complete value, 
or a "push" (in which case the new value is pushed on to a stack for the given
context) or a "pop".
Indeed, we would definitely need "modify" but also the "push" and "pop"
operations. As mentioned before, there are already push/pop operations
in ITmfStateSystemBuilder. We'd just have to see if they cover your use
case, and if it's easy enough to hook the XML parser into using those.

Side-note, there is also a 4th operation called "incrementAttribute",
which simply increments the value of the attribute by one (has to be an
integer value of course). This is what we use for statistics for example.

Note that doing this does open up some interesting visualization possibilities
for state machines in addition to function calls.

Very crude and unoriginal example, let's suppose I have an event
"sched_switch", and I want to update the value of the attribute
"Thread/[thread tid]/Status" to the value "running":

<eventHandler eventName="sched_switch">
  <stateChange>
    # Define the path to the attribute to be affected
    <attribute name="Threads" /> # hard-coded value
    <attribute fieldvalue="tid" /> # a field in sched_switch
    <attribute name="Status" />
    # Apply the state change
    <modify valueType="string" value="Running" />
Going back to this example, here we could also support let's say
<push valueType="string" value="running" />
or simply
<pop />

to indicate that we want to call pushAttribute() or popAttribute(),
instead of modifyAttribute().

  </stateChange>
</eventHandler

I like this tree defition. But we must add the possibilities to make quey on the State Sytem in the path (as was proposed in New Features in TMF about filters expressions subject)
The XML is the conversion of your exemple : /Threads/[${/event/tid}]/Status = Running
We want to be able to have /Threads/[${/CPUs/[${/event/Cpu}]/Current_thread}]/System_call = NULL    (it's the first instruction for a kernel exit_syscall event)
and query the value of the node /CPUs/[${/event/Cpu}]/Current_thread in the state system, and use this value to make the <attribute fieldvalue="tid" />

Exemple :
<stateChange>
    # Define the path to the attribute to be affected
    <attribute name="Threads" /> # hard-coded value
    <attribute query="StateSystem" > # begin the query of the SS query
	<attribute name="CPUs" />
	<attribute fieldvalue="Cpu" /> # a field in syscall event
	<attribute name="Cuurent_thread" />
    </attribute>
    <attribute name="System_call" />
    # Apply the state change
    <modify valueType="string" value="NULL" />
</stateChange>

equivalent : 
/Threads/[${/CPUs/[${/event/Cpu}]/Current_thread}]/System_call = NULL

I put a String value, but of course we'd probably want an integer value
here instead. I also put the <stateChange> under the event name itself,
since sometimes one event can cause more than one state change. Any
thoughts?
One thing that does occur to me is that there is probably some value in
decoupling the logic used to populate the state system with what you want
to display.  What you have above is good in that it outlines clearly what
event information is going into the state system, but of course you don't
know from this alone what is supposed to be displayed on the Y axis at all.
You would need something else to tell the view what the hierarchy is, how
to get the values from the state system, and the display information for those
states (and of course my xml file does all of this in one file at the moment)
True that, we don't necessarily want to display everything that is
stored in one state system (unless it's for the State System Explorer of
course!)

There's already some ways to get specific attributes, like
ITmfStateSystem#getQuarks(). We can do getQuarks("Threads", "*",
"Status"), and it will return the quarks for the "Status" attributes for
all the threads found in the state system. A view can then iterate over
those and query only these attributes. It could be improved, for example
supporting more than one wildcard, or eventually maybe having DB-like
queries. But for our use cases so far this was sufficient, since we
control both the attribute tree creation, and the contents of the Y-axis
of the view.

I'm not sure yet if this "list of attributes to display" should be
explicitely defined in the XML file, or if this should be defined in the
view itself (like we could build a state history from the XML file
first, then tweak what we want to display in the view).

I agree with the fact that we should separate the logic to populate the state system and the logic to make the view. Because it's more easy to have one states system for more than one view. It takes two separate parts in the XML ou two XML.


Florian


Back to the top