Welcome to mirror list, hosted at ThFree Co, Russian Federation.

NameInfo.cs « TraceLogging « Tracing « Diagnostics « System « shared « System.Private.CoreLib « src - github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a7daf5e757a2b63373373891a6bda9195ec6af94 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using Interlocked = System.Threading.Interlocked;

#if ES_BUILD_STANDALONE
namespace Microsoft.Diagnostics.Tracing
#else
namespace System.Diagnostics.Tracing
#endif
{
    /// <summary>
    /// TraceLogging: Stores the metadata and event identifier corresponding
    /// to a tracelogging event type+name+tags combination.
    /// </summary>
    internal sealed class NameInfo
        : ConcurrentSetItem<KeyValuePair<string, EventTags>, NameInfo>
    {
        /// <summary>
        /// Insure that eventIds strictly less than 'eventId' will not be
        /// used by the SelfDescribing events.   
        /// </summary>
        internal static void ReserveEventIDsBelow(int eventId)
        {
            for(;;)
            {
                int snapshot = lastIdentity;
                int newIdentity = (lastIdentity & ~0xFFFFFF) + eventId;
                newIdentity = Math.Max(newIdentity, snapshot);      // Should be redundant.  as we only create descriptors once.  
                if (Interlocked.CompareExchange(ref lastIdentity, newIdentity, snapshot) == snapshot)
                    break;
            }
        }

        private static int lastIdentity = Statics.TraceLoggingChannel << 24;
        internal readonly string name;
        internal readonly EventTags tags;
        internal readonly int identity;
        internal readonly byte[] nameMetadata;

        public NameInfo(string name, EventTags tags, int typeMetadataSize)
        {
            this.name = name;
            this.tags = tags & Statics.EventTagsMask;
            this.identity = Interlocked.Increment(ref lastIdentity);

            int tagsPos = 0;
            Statics.EncodeTags((int)this.tags, ref tagsPos, null);

            this.nameMetadata = Statics.MetadataForString(name, tagsPos, 0, typeMetadataSize);

            tagsPos = 2;
            Statics.EncodeTags((int)this.tags, ref tagsPos, this.nameMetadata);
        }

        public override int Compare(NameInfo other)
        {
            return this.Compare(other.name, other.tags);
        }

        public override int Compare(KeyValuePair<string, EventTags> key)
        {
            return this.Compare(key.Key, key.Value & Statics.EventTagsMask);
        }

        private int Compare(string otherName, EventTags otherTags)
        {
            int result = StringComparer.Ordinal.Compare(this.name, otherName);
            if (result == 0 && this.tags != otherTags)
            {
                result = this.tags < otherTags ? -1 : 1;
            }
            return result;
        }

#if FEATURE_PERFTRACING
        public IntPtr GetOrCreateEventHandle(EventProvider provider, TraceLoggingEventHandleTable eventHandleTable, EventDescriptor descriptor, TraceLoggingEventTypes eventTypes)
        {
            IntPtr eventHandle;
            if ((eventHandle = eventHandleTable[descriptor.EventId]) == IntPtr.Zero)
            {
                lock (eventHandleTable)
                {
                    if ((eventHandle = eventHandleTable[descriptor.EventId]) == IntPtr.Zero)
                    {
                        byte[] metadataBlob = EventPipeMetadataGenerator.Instance.GenerateEventMetadata(
                            descriptor.EventId,
                            name,
                            (EventKeywords)descriptor.Keywords,
                            (EventLevel)descriptor.Level,
                            descriptor.Version,
                            eventTypes);
                        uint metadataLength = (metadataBlob != null) ? (uint)metadataBlob.Length : 0;

                        unsafe
                        {
                            fixed (byte* pMetadataBlob = metadataBlob)
                            {
                                // Define the event.
                                eventHandle = provider.m_eventProvider.DefineEventHandle(
                                    (uint)descriptor.EventId,
                                    name,
                                    descriptor.Keywords,
                                    descriptor.Version,
                                    descriptor.Level,
                                    pMetadataBlob,
                                    metadataLength);
                            }
                        }

                        // Cache the event handle.
                        eventHandleTable.SetEventHandle(descriptor.EventId, eventHandle);
                    }
                }
            }

            return eventHandle;
        }
#endif
    }
}