[lttng-dev] ctf document quick review

Aaron Spear aspear at vmware.com
Tue Feb 7 01:38:40 EST 2012

Hi Matthew,

> clocks: well though out IMO, looks like it would support a large
> veriety of clocks. On a hardware side, would a jitter/drift be
> interesting? also would scaling clocks (such as the turbo button 
> on 286s ) be interesting?

We have thought a fair bit about how frequency scaling could be handled.  It is quite important for use cases beyond turbo buttons :-)  An increasing amount of embedded systems now-a-days (e.g. an Android phone) consist of many cores with power management that are doing a lot of voltage and frequency scaling in order to squeeze every little bit out of the battery.  This of course can create discontinuities in the clocks.  Clocks speeding up, slowing down, stopping altogether, getting reset.  There is even the possibility of the clock for a trace event stream completely changing to a different clock mid-stream.  Of course if you do not have a way to know that it happened you are in trouble, but the hope is to be able to record these as events in the stream (which means instrumenting the power management, or doing it in hardware). 

Section 8 of the CTF spec details how clock values are set/referenced through the type system:

typealias integer {
	size = 64; align = 1; signed = false;
	map = clock.cycle_counter_sync.value;
} := uint64_ccnt_t;

This declares that a field that contains a value of this type is setting the VALUE (the count) of this clock.

So then it is possible to declare a stream in which every event sets the current value of the clock:

stream {
	/* ... */
	event.header := struct {
		uint64_ccnt_t timestamp;
		/* ... */
	packet.context := struct packet_context;

So then every time an event occurs, it is in effect setting the current value of the clock.  The value of the clock is not necessarily the only thing that can be adjusted in this way though.  It could also be possible to adjust the frequency in the same way.  Say you had another type declared like this:

typealias integer {
	size = 64; align = 1; signed = false;
	map = clock.cycle_counter_sync.freq;
} := uint64_ccnt_freq_t;

So this declares a type that when referenced sets the FREQUENCY of the clock as opposed to the current count value.  Say for example that you had a power management event that changes the current count and frequency at the same time.  In the TDSL, that CTF defines, this event might look like this:

event {
        name = ccnt_change_event;
        id = 1;
        fields := {
            uint64_ccnt_t      ccnt_value;
            uint64_ccnt_freq_t ccnt_freq;

so when this occurs it changes the frequency and count.

* Yes, it is true that this sort of thing happening in the trace stream has implications for algorithms that are trying to go through gigabytes of trace events with a binary search and that sort of thing.  I think that in general you would have to know that there were events in the stream that changed the frequency and have to find them all in order to really maintain accurate timekeeping, at least if you cared about correlation with other cores.

hope this helps,
Aaron Spear

More information about the lttng-dev mailing list