/// <summary>
        /// The event header has a variant 'v' that contains one of two structs:
        /// "compact" or "extended".
        ///
        /// In the compact case, the variant tag is used as the event id.
        /// In the extended case, the extended structure contains an id field.
        /// </summary>
        /// <param name="ctfEvent">An event</param>
        /// <returns>The id of the event</returns>
        private uint GetEventId(ICtfEvent ctfEvent)
        {
            uint id = 0;

            if (ctfEvent.StreamDefinedEventHeader.FieldType == CtfTypes.Struct)
            {
                var streamDefinedEventHeader = ctfEvent.StreamDefinedEventHeader as CtfStructValue;
                if (streamDefinedEventHeader != null)
                {
                    foreach (var field in streamDefinedEventHeader.Fields)
                    {
                        if (field.FieldName == "id")
                        {
                            if (uint.TryParse(field.GetValueAsString(), out id))
                            {
                                return(id);
                            }
                            else
                            {
                                throw new PerfPlaybackException($"Unable to parse event id: {field}");
                            }
                        }
                    }
                }
            }

            return(id);
        }
        /// <inheritdoc />
        public ICtfEventDescriptor GetEventDescriptor(
            ICtfEvent ctfEvent,
            ICtfMetadata metadata)
        {
            uint id = this.GetEventId(ctfEvent);

            ICtfEventDescriptor eventDescriptor;

            if (metadata is PerfMetadata typedMetadata)
            {
                // optimization if we get our own metadata back
                // we'll check this below
                typedMetadata.EventByEventId.TryGetValue(id, out eventDescriptor);
            }
            else
            {
                eventDescriptor = metadata.Events.FirstOrDefault(x => x.Id == id);
            }

            if (eventDescriptor == null)
            {
                throw new PerfPlaybackException($"Unable to find event descriptor for event id={id}.");
            }

            return(eventDescriptor);
        }
Beispiel #3
0
        public bool PopEvent(out ICtfEvent ctfEvent, out ICtfPacket ctfPacket, out ulong bytesConsumed)
        {
            this.dataReadyForConsumption.Wait(this.cancellationToken);
            this.cancellationToken.ThrowIfCancellationRequested();

            lock (this.Events)
            {
                if (this.Events.Count == 0)
                {
                    // we've reached the end of the stream
                    ctfEvent      = null;
                    ctfPacket     = null;
                    bytesConsumed = 0;
                    return(false);
                }

                ctfEvent      = this.Events.Dequeue();
                ctfPacket     = this.Packets.Dequeue();
                bytesConsumed = this.BytesProcessed.Dequeue();

                if (this.Events.Count == 0 && !this.endOfStream)
                {
                    this.dataReadyForConsumption.Reset();
                }

                this.readyForNewData.Set();
            }

            return(true);
        }
        public virtual CtfTimestamp GetTimestampFromEventHeader(ICtfEvent ctfEvent, CtfTimestamp previousTimestamp)
        {
            var variantStruct = GetStreamEventHeaderStructure(ctfEvent);

            Debug.Assert(variantStruct != null);

            if (!variantStruct.FieldsByName.TryGetValue("timestamp", out var timestampValue))
            {
                throw new LTTngPlaybackException("stream.event.header variant 'v' struct has no 'timestamp' field");
            }

            if (!(timestampValue is CtfIntegerValue timestampInteger))
            {
                throw new LTTngPlaybackException("stream.event.header variant 'v' struct field 'timestamp'" +
                                                 " is not an integer");
            }

            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));
        }
Beispiel #5
0
 public CtfConfigurationPreview(ICtfEvent ctf, IEnumerable <ICountry> countries)
 {
     this.Name       = ctf.Name;
     this.Organizers = ctf.Organizers;
     this.StartTime  = ctf.StartTime;
     this.EndTime    = ctf.EndTime;
     this.Scoring    = ctf.Scoring;
     this.Countries  = countries;
 }
        /// <inheritdoc />
        public ICtfEventDescriptor GetEventDescriptor(
            ICtfEvent ctfEvent)
        {
            uint id = this.GetEventId(ctfEvent);

            if (!this.metadataCustomization.LTTngMetadata.EventByEventId.TryGetValue(id, out var eventDescriptor))
            {
                throw new LTTngPlaybackException($"Unable to find event descriptor for event id={id}.");
            }

            return(eventDescriptor);
        }
Beispiel #7
0
        public CtfPacket(PacketReader packetReader, ICtfEvent previousEvent)
        {
            this.packetReader = packetReader;

            // This is set for the sake of timestamps. The first timestamp in this packet might be
            // less than 64-bits, and so requires the last timestamp of the stream to complete it.
            // See CTF specification 1.8.2 section 8 "Clocks" - and read carefully about N-bit integer
            // types referring to clocks.
            //
            this.CurrentEvent = previousEvent;

            Debug.Assert(this.packetReader.Metadata.TraceDescriptor.PacketHeader != null);
        }
        public void ProcessEvent(ICtfEvent ctfEvent, ICtfPacket eventPacket, ICtfTraceInput traceInput, ICtfInputStream ctfEventStream)
        {
            var eventDescriptor = ctfEvent.EventDescriptor as EventDescriptor;

            Debug.Assert(eventDescriptor != null);
            if (eventDescriptor == null)
            {
                throw new LTTngPlaybackException("EventDescriptor is not an LTTng descriptor.");
            }

            if (!this.streamToCpu.TryGetValue(ctfEventStream, out var cpuId))
            {
                var    cpuIndex = ctfEventStream.StreamSource.LastIndexOf('_');
                string cpu      = ctfEventStream.StreamSource.Substring(cpuIndex + 1);
                if (!uint.TryParse(cpu, out cpuId))
                {
                    Debug.Assert(false, "Unable to parse cpu from LTTng stream channel");
                    cpuId = uint.MaxValue;
                }

                this.streamToCpu.Add(ctfEventStream, cpuId);
            }

            if (!this.traceContexts.TryGetValue(traceInput, out var traceContext))
            {
                traceContext = new TraceContext(this.metadataCustomization.LTTngMetadata);
                this.traceContexts.Add(traceInput, traceContext);
            }

            var callbackEvent = new LTTngEvent(ctfEvent);

            var callbackContext = new LTTngContext(this.metadataCustomization, ctfEventStream, traceContext)
            {
                // todo: when supporting multiple traces, this timestamp needs to become relative to the earliest timestamp all traces
                // todo: when supporting multiple traces, this one event number needs to become cumulative across traces, and one specific to the current trace
                CurrentCpu                    = cpuId,
                Timestamp                     = (long)ctfEvent.Timestamp.NanosecondsFromClockBase,/// - this.baseTimestamp,
                CurrentEventNumber            = this.eventNumber,
                CurrentEventNumberWithinTrace = this.eventNumber,
            };

            foreach (var callback in this.eventCallbacks)
            {
                callback(callbackEvent, callbackContext);
            }

            ++this.eventNumber;
        }
        /// <summary>
        /// The event header has a variant 'v' that contains one of two structs:
        /// "compact" or "extended".
        ///
        /// In the compact case, the variant tag is used as the event id.
        /// In the extended case, the extended structure contains an id field.
        /// </summary>
        /// <param name="ctfEvent">An event</param>
        /// <returns>The id of the event</returns>
        private uint GetEventId(ICtfEvent ctfEvent)
        {
            var eventHeaderVariant = this.GetStreamEventHeaderVariant(ctfEvent);

            Debug.Assert(eventHeaderVariant != null);

            var eventHeaderStruct = GetStreamEventHeaderStructure(eventHeaderVariant);

            Debug.Assert(eventHeaderStruct != null);

            uint id = 0;

            if (StringComparer.InvariantCulture.Equals(eventHeaderStruct.FieldName, "compact"))
            {
                if (!eventHeaderVariant.TagEnum.IntegerValue.TryGetUInt32(out id))
                {
                    throw new LTTngPlaybackException("stream.event.header.v<tag> - tag value is not a uint.");
                }

                return(id);
            }

            if (!eventHeaderStruct.FieldsByName.TryGetValue("id", out var idValue))
            {
                throw new LTTngPlaybackException("stream.event.header.v value is not 'id'.");
            }

            if (!(idValue is CtfIntegerValue idFieldIntegerValue))
            {
                throw new LTTngPlaybackException("stream.event.header 'id' field is not an integer.");
            }

            if (!idFieldIntegerValue.Value.TryGetUInt32(out id))
            {
                throw new LTTngPlaybackException($"stream.event.header.v 'id' is not a uint.");
            }

            return(id);
        }
        internal PerfEvent(ICtfEvent ctfEvent)
        {
            if (!(ctfEvent.EventDescriptor is IEventDescriptor eventDescriptor))
            {
                throw new CtfPlaybackException("Not a valid Perf event.");
            }

            if (ctfEvent.Payload is null)
            {
                throw new CtfPlaybackException("Perf event payload is null.");
            }

            if (!(ctfEvent.Payload is CtfStructValue payload))
            {
                throw new CtfPlaybackException("Perf event payload is not a structure.");
            }

            this.ctfEvent        = ctfEvent;
            this.eventDescriptor = eventDescriptor;

            ///          streamDefinedEventContext
        }
Beispiel #11
0
        /// <summary>
        /// Creates a new instance of the loader.
        /// </summary>
        /// <param name="opts">Application configuration.</param>
        public YamlCtfConfigurationLoader(IOptions <ConfigurationRoot> opts)
        {
            var des = new SerializerSettings
            {
                ObjectFactory = new YamlObjectFactory()
            };

            des.RegisterSerializerFactory(new YamlTimeSpanConverter());
            des.RegisterSerializerFactory(new YamlDateTimeOffsetConverter());
            des.RegisterSerializerFactory(new YamlUriConverter());

            var deserializer = new Serializer(des);

            var optv = opts.Value;
            var fi   = new FileInfo(optv.EventConfiguration);

            using (var fs = fi.OpenRead())
                using (var sr = new StreamReader(fs, AbstractionUtilities.UTF8))
                {
                    var parser = new Parser(sr);
                    var er     = new EventReader(parser);
                    if (er.Expect <StreamStart>() == null)
                    {
                        throw new InvalidDataException("YAML configuration is malformed.");
                    }

                    this._eventConfig = ReadEvent(er, deserializer);
                    this._categories  = ReadCategories(er, deserializer);

                    foreach (var cat in this._categories)
                    {
                        foreach (var chall in cat.Challenges)
                        {
                            (chall as YamlCtfChallenge).Category = cat;
                        }
                    }
                }
        }
Beispiel #12
0
        private void PushEvent(ICtfEvent ctfEvent, ICtfPacket ctfPacket, ulong bytesConsumed)
        {
            Debug.Assert(ctfEvent != null);
            Debug.Assert(ctfPacket != null);
            Debug.Assert(bytesConsumed != 0);

            this.readyForNewData.Wait(this.cancellationToken);
            this.cancellationToken.ThrowIfCancellationRequested();

            lock (this.Events)
            {
                this.Events.Enqueue(ctfEvent);
                this.Packets.Enqueue(ctfPacket);
                this.BytesProcessed.Enqueue(bytesConsumed);

                if (this.Events.Count >= QueueSizeLimit)
                {
                    this.readyForNewData.Reset();
                }

                this.dataReadyForConsumption.Set();
            }
        }
        private CtfVariantValue GetStreamEventHeaderVariant(ICtfEvent ctfEvent)
        {
            if (ctfEvent.StreamDefinedEventHeader == null)
            {
                throw new LTTngPlaybackException("stream.event.header is not defined");
            }

            if (!(ctfEvent.StreamDefinedEventHeader is CtfStructValue eventHeaderStruct))
            {
                throw new LTTngPlaybackException("stream.event.header is not a structure");
            }

            if (!eventHeaderStruct.FieldsByName.TryGetValue("v", out var variant))
            {
                throw new LTTngPlaybackException("stream.event.header does not contain field 'v'");
            }

            if (!(variant is CtfVariantValue variantValue))
            {
                throw new LTTngPlaybackException("stream.event.header does not field 'v' is not a variant");
            }

            return(variantValue);
        }
        private CtfStructValue GetStreamEventHeaderStructure(ICtfEvent ctfEvent)
        {
            var variantValue = this.GetStreamEventHeaderVariant(ctfEvent);

            return(GetStreamEventHeaderStructure(variantValue));
        }