Exemple #1
0
        /// <summary>
        /// Sets the Profile Sources (CPU machine counters) that will be used if PMC (Precise Machine Counters)
        /// are turned on.   Each CPU counter is given a id (the profileSourceID) and has an interval 
        /// (the number of counts you skip for each event you log).   You can get the human name for 
        /// all the supported CPU counters by calling GetProfileSourceInfo.  Then choose the ones you want
        /// and configure them here (the first array indicating the CPU counters to enable, and the second
        /// array indicating the interval.  The second array can be shorter then the first, in which case
        /// the existing interval is used (it persists and has a default on boot).  
        /// </summary>
        public static unsafe void SetProfileSources(int[] profileSourceIDs, int[] profileSourceIntervals)
        {
            var version = Environment.OSVersion.Version.Major * 10 + Environment.OSVersion.Version.Minor;
            if (version < 62)
                throw new ApplicationException("Profile source only availabe on Win8 and beyond.");

            TraceEventNativeMethods.SetSystemProfilePrivilege();
            var interval = new TraceEventNativeMethods.TRACE_PROFILE_INTERVAL();
            for (int i = 0; i < profileSourceIntervals.Length; i++)
            {
                interval.Source = profileSourceIDs[i];
                interval.Interval = profileSourceIntervals[i];
                var result = TraceEventNativeMethods.TraceSetInformation(0,
                    TraceEventNativeMethods.TRACE_INFO_CLASS.TraceSampledProfileIntervalInfo,
                    &interval, sizeof(TraceEventNativeMethods.TRACE_PROFILE_INTERVAL));
                if (result != 0)
                    Marshal.ThrowExceptionForHR(TraceEventNativeMethods.GetHRFromWin32(result));
            }

            fixed (int* sourcesPtr = profileSourceIDs)
            {
                var result = TraceEventNativeMethods.TraceSetInformation(0,
                    TraceEventNativeMethods.TRACE_INFO_CLASS.TraceProfileSourceConfigInfo,
                    sourcesPtr, profileSourceIDs.Length * sizeof(int));
                if (result != 0)
                    Marshal.ThrowExceptionForHR(TraceEventNativeMethods.GetHRFromWin32(result));
            }
        }
Exemple #2
0
        /// <summary>
        /// Returns a ditionary of keyed by name of ProfileSourceInfo structures for all the CPU counters available on the machine. 
        /// TODO FIX NOW remove log parameter. 
        /// </summary>
        public static unsafe Dictionary<string, ProfileSourceInfo> GetProfileSourceInfo()
        {
            var version = Environment.OSVersion.Version.Major * 10 + Environment.OSVersion.Version.Minor;
            if (version < 62)
                throw new ApplicationException("Profile source only availabe on Win8 and beyond.");

            var ret = new Dictionary<string, ProfileSourceInfo>(StringComparer.OrdinalIgnoreCase);

            // Figure out how much space we need.  
            int retLen = 0;
            var result = TraceEventNativeMethods.TraceQueryInformation(0,
                TraceEventNativeMethods.TRACE_INFO_CLASS.TraceProfileSourceListInfo,
                null, 0, ref retLen);
            Debug.Assert(result == 24);     // Not enough space.  
            if (retLen != 0)
            {
                // Do it for real.  
                byte* buffer = stackalloc byte[retLen];
                result = TraceEventNativeMethods.TraceQueryInformation(0,
                    TraceEventNativeMethods.TRACE_INFO_CLASS.TraceProfileSourceListInfo,
                    buffer, retLen, ref retLen);

                if (result == 0)
                {
                    var interval = new TraceEventNativeMethods.TRACE_PROFILE_INTERVAL();
                    var profileSource = (TraceEventNativeMethods.PROFILE_SOURCE_INFO*)buffer;
                    for (int i = 0; i < 10; i++)
                    {
                        char* namePtr = (char*)&profileSource[1];       // points off the end of the array;

                        interval.Source = profileSource->Source;
                        interval.Interval = 0;
                        result = TraceEventNativeMethods.TraceQueryInformation(0,
                            TraceEventNativeMethods.TRACE_INFO_CLASS.TraceSampledProfileIntervalInfo,
                            &interval, sizeof(TraceEventNativeMethods.TRACE_PROFILE_INTERVAL), ref retLen);
                        if (result != 0)
                            Marshal.ThrowExceptionForHR(TraceEventNativeMethods.GetHRFromWin32(result));

                        var name = new string(namePtr);
                        ret.Add(name, new ProfileSourceInfo()
                        {
                            Name = name,
                            ID = profileSource->Source,
                            Interval = interval.Interval,
                            MinInterval = profileSource->MinInterval,
                            MaxInterval = profileSource->MaxInterval,
                        });
                        if (profileSource->NextEntryOffset == 0)
                            break;
                        profileSource = (TraceEventNativeMethods.PROFILE_SOURCE_INFO*)(profileSource->NextEntryOffset + (byte*)profileSource);
                    }
                }
                else
                    Marshal.ThrowExceptionForHR(TraceEventNativeMethods.GetHRFromWin32(result));
            }
            return ret;
        }