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
_______________________________________________
lttng-dev mailing list
[email protected]
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev