none
How to get a contiguous trace using PerfSet, PerfInc and PerfDec calls RRS feed

  • Question

  • My code looks like this

    PerfCreateInstance();    // Create the Object instance 

    PerfSetULongLongCounterValue(NewData);    // Set a value say 100

    OldData = NewData;

    while(1) {

        if (NewData > OldData) {

            PerfIncrementULongLongCounterValue(NewData - OldData);

            OldData = NewData;

        }

        if (NewData < OldData) {

            PerfDecrementULongLongCounterValue(OldData - NewData);

            OldData = NewData;

        } 

        if (NewData == OldData) {

            PerfSetULongLongCounterValue(NewData);

            OldData = NewData;

        }

    } // end of while loop

    My values are all ULONGLONG. I get a perfect smooth trace. However 

    Whenever NewData == OldData and I do PerfSetULongLongCounterValue(NewData); I get all broken traces.

    I did try by doing simply calling PerfSetULongLongCounterValue() for all values without bothering to check for the old value or doing INC or DEC operation and that resulted in even bad broken trace form.  

    while(1) {

        PerfSetULongLongCounterValue(NewData);   // This produces broken trace

    }

    Sample Code:

    PerfSetULongLongCounterValue(abcd, GPerfInstance0[0], TOT_MBW_ID, 0);
    	ULONGLONG counterValue = 0, oldCounterValue = 0;
    	SYSTEMTIME sysTime;
    	while (!_kbhit()) {
    		counterValue = 30+ (rand() % 10)*100;
    		if (counterValue > oldCounterValue) {
    			PerfIncrementULongLongCounterValue(abcd, GPerfInstance0[0], TOT_MBW_ID, llabs(counterValue - oldCounterValue));
    		} else if (counterValue < oldCounterValue) {
    			PerfDecrementULongLongCounterValue(abcd, GPerfInstance0[0], TOT_MBW_ID, llabs(counterValue - oldCounterValue));
    		} else {
    			PerfSetULongLongCounterValue(abcd, GPerfInstance0[0], TOT_MBW_ID, counterValue);
    		}
    		GetSystemTime(&sysTime);
    		cout << counterValue << ", " << sysTime.wMinute << ":" << sysTime.wSecond << "\n";
    		oldCounterValue = counterValue;
    		Sleep(1000);
    	}

    I have tried this code with just PerfSetULongLongCounterValue() and that also was equally bad. The data is picture perfect:

    830, 42:2
    230, 42:3
    430, 42:4
    530, 42:5
    530, 42:6
    130, 42:7
    730, 42:8
    130, 42:9
    130, 42:10
    530, 42:11
    230, 42:13
    730, 42:14
    630, 42:15
    130, 42:16
    430, 42:17
    230, 42:18
    330, 42:19
    230, 42:20
    230, 42:21
    130, 42:22
    630, 42:23
    830, 42:24
    530, 42:25
    730, 42:26
    630, 42:27

    Could some kind soul point me out what part of the logic is wrong in my code? 

    thanks

    ananda




    Monday, December 2, 2019 1:58 AM

All replies

  • MSFT provides a sample code here: https://github.com/microsoft/Windows-classic-samples/blob/master/Samples/Win7Samples/winbase/PerfCounters/Basic/CPP 
    This sample has one issue, I could not get PerfSetCounterRefValue() to work. It complained about ERROR_INVALID_PARAMETER (0x57). My code does not use it. 
    The other problem was using PerfSetULongLongCounterValue(), if I use that instead of PerfIncrementULongLongCounterValue() my trace breaks up do not get contiguous trace. 

    Ok finally I got it working. Is it the correct/official way? I don't know. In my case it works fine and faithfully traces the value fed to it. 

        ULONGLONG initValue = 0;
        ULONGLONG currentValue = 0;
        SYSTEMTIME sysTime;
        PerfSetULongLongCounterValue(HandleX, PerfInstance, 1, initValue);
        
        while (!_kbhit()) {
        currentValue = (rand() % 10)*100;
        GetSystemTime(&sysTime);
        PerfIncrementULongLongCounterValue(HandleX, PerfInstance, 1, currentValue);
        cout << sysTime.wMinute << ":" << sysTime.wSecond << " " << currentValue << "\n";
        Sleep(1000);
        }
        return 0;
    Tuesday, December 10, 2019 11:51 PM