public string GetTimestampClockName(CtfIntegerValue timestampField) { if (String.IsNullOrWhiteSpace(timestampField.MapValue)) { return(null); } // note: this may be overly cautious making this LTTng specific, but it's not clear to me that the CTF // specification mandates this clock reference format. It might just be another "example". // LTTng maps are in the form of: clock.<clock_name>.value // where <clock_name> is the name of the clock // e.g. "clock.monotonic.value" string map = timestampField.MapValue; int firstSplitIndex = map.IndexOf('.'); string clockToken = map.Substring(0, firstSplitIndex); if (!StringComparer.Ordinal.Equals(clockToken, "clock")) { return(null); } int lastSplitIndex = map.LastIndexOf('.'); string valueToken = map.Substring(lastSplitIndex + 1); if (!StringComparer.Ordinal.Equals(valueToken, "value")) { return(null); } return(map.Substring(firstSplitIndex + 1, lastSplitIndex - firstSplitIndex - 1)); }
public virtual CtfTimestamp GetTimestampFromEventHeader(ICtfEvent ctfEvent, CtfTimestamp previousTimestamp) { CtfIntegerValue timestampInteger = null; // Hack for perf? if (ctfEvent.StreamDefinedEventHeader.FieldType == CtfTypes.Struct) { var streamDefinedEventHeader = ctfEvent.StreamDefinedEventHeader as CtfStructValue; if (streamDefinedEventHeader != null) { foreach (var field in streamDefinedEventHeader.Fields) { if ("timestamp".Equals(field.FieldName)) { return(new CtfTimestamp(this.MetadataCustomization, (CtfIntegerValue)field)); } } } } if (previousTimestamp is null) { // todo:I think we need to do something else for this case, especially if the integer size is < 64 // not sure what yet. maybe base it on the clock's offset? return(new CtfTimestamp(this.MetadataCustomization, timestampInteger)); } // Timestamps aren't actually absolute values. To quote from CTF spec 1.8.2 section 8: // For a N-bit integer type referring to a clock, if the integer overflows compared to the N low order bits // of the clock prior value found in the same stream, then it is assumed that one, and only one, overflow // occurred. It is therefore important that events encoding time on a small number of bits happen frequently // enough to detect when more than one N-bit overflow occurs. // So to determine a timestamp, we must know the previous timestamp. If they're all the same number of bits, it // wouldn't be necessary (I don't think so anyways). But some timestamps are smaller than others. if (timestampInteger.Descriptor.Size < 64) { if (!timestampInteger.Value.TryGetInt64(out long thisTimestamp)) { Debug.Assert(false); throw new CtfPlaybackException("Unable to retrieve timestamp as long."); } long previous = (long)previousTimestamp.NanosecondsFromClockBase; long oneBitBeyondBitsUsed = 1L << (byte)timestampInteger.Descriptor.Size; long bitMask = ~(oneBitBeyondBitsUsed - 1); long highBitsFromPreviousTimestamp = previous & bitMask; long newTimestamp = highBitsFromPreviousTimestamp | thisTimestamp; if (newTimestamp < previous) { // handle the overflow case newTimestamp += oneBitBeyondBitsUsed; Debug.Assert(newTimestamp > previous); } return(new CtfTimestamp(this.MetadataCustomization, timestampInteger, newTimestamp)); } return(new CtfTimestamp(this.MetadataCustomization, timestampInteger)); }
public string GetTimestampClockName(CtfIntegerValue timestampField) { throw new NotImplementedException(); }